web-dev-qa-db-fra.com

Aide sur les paquets en Java - l'importation ne fonctionne pas

Je suis un développeur C++ - pas un développeur Java, mais je dois faire fonctionner ce code ...

J'ai 2 classes publiques qui seront utilisées par un autre produit. J'ai utilisé la directive package dans chacun des fichiers Java. 

package com.company.thing;

class MyClass ...

Lorsque j'essaie de compiler une application de test utilisant ce que j'ajoute 

import com.company.thing.*;

Le compilateur javac échoue et des erreurs concernant com.company n'existent pas. (même si je le compile dans le même répertoire que les fichiers de classe, je viens de faire un paquet)

Je suis sûr que je fais quelque chose de stupide et stupide.

J'ai lu les http://Java.Sun.com/docs/books/tutorial/Java/package/usepkgs.html pages et j'ai essayé de configurer une structure de répertoires telle que/com/company/thing, etc., mais soit j'ai tout foutu en l'air, soit je manque quelque chose d'autre.

EDIT Merci pour les suggestions - j’avais déjà essayé le classpath. Cela n'aide pas.

J'ai essayé de compiler 

javac -classpath <parent> client.Java 

et le résultat est:

package com.company does not exist

J'ai le code que je veux importer (les deux fichiers Java) dans\com\company\product. Je compile ces amende. (ils contiennent MyClass) J'ai même créé un fichier jar pour eux. J'ai copié le fichier JAR dans le répertoire parent.

Je l'ai ensuite fait (dans le répertoire parent avec le fichier Java du client) 

javac -cp <jarfile> *.Java

le résultat est:

cannot access MyClass
bad class file: MyClass.class(:MyClass.class)
class file contains wrong class: com.company.product.MyClass
Please remove or make sure it appears in the correct subdirectory of the classpath.

MODIFIER

J'ai le code client à compiler et à exécuter si j'utilisais le nom complet de MyClass et le compilais dans le répertoire parent. Je suis totalement confus maintenant. 

compilé sans classe class - juste 

javac *.Java 

dans le répertoire parent - et cela a bien fonctionné.

Je peux obtenir une application de test à compiler, mais cela ne va pas la réduire lorsque je devrai l'intégrer au code de production. Toujours à la recherche d'aide.

MODIFIER:

Enfin - je ne sais pas pourquoi cela ne fonctionnait pas auparavant - mais j'ai nettoyé tous les fichiers de la structure de répertoires et maintenant cela fonctionne. 

Merci

28
Tim

D'accord, juste pour clarifier les choses qui ont déjà été affichées.

Vous devez avoir le répertoire com, contenant le répertoire company, contenant le répertoire example, contenant le fichier MyClass.Java.

Dans le dossier contenant com, exécutez:

 $ javac com\société\exemple\MaClasse.Java 

Ensuite:

 $ Java com.company.example.MyClass 
 Bonjour de MyClass! 

Celles-ci doivent toutes deux être effectuées à partir de la racine de l'arbre source. Sinon, javac et Java ne pourront trouver aucun autre paquet (en fait, Java ne pourrait même pas exécuter MyClass).

Un petit exemple

J'ai créé les dossiers "testpackage" et "testpackage2". Dans testpackage, j'ai créé TestPackageClass.Java contenant le code suivant:

package testpackage;

import testpackage2.MyClass;

public class TestPackageClass {
    public static void main(String[] args) {
        System.out.println("Hello from testpackage.TestPackageClass!");
        System.out.println("Now accessing " + MyClass.NAME);
    }
}

Dans testpackage2, j'ai créé MyClass.Java contenant le code suivant:

package testpackage2;
public class MyClass {
    public static String NAME = "testpackage2.MyClass";
}

À partir du répertoire contenant les deux nouveaux dossiers, j'ai exécuté:

 C:\exemples> javac testpackage\*. Java 

 C:\exemples> javac testpackage2\*. Java 

Ensuite:

 C:\exemples> Java testpackage.TestPackageClass 
 Hello de testpackage.TestPackageClass! 
 Accédez maintenant à testpackage2.MyClass 

Est-ce que cela rend les choses plus claires?

45
Michael Myers

Oui, c'est un problème de classpath. Vous devez indiquer au compilateur et à l'exécution que le répertoire dans lequel résident vos fichiers .class fait partie de CLASSPATH. Le répertoire que vous devez ajouter est le parent du répertoire "com" au début de la structure de votre package.

Pour ce faire, utilisez l’argument -classpath pour javac.exe et Java.exe.

Devrait également demander comment les classes tierces que vous utilisez sont emballées. S'ils se trouvent dans un fichier JAR et que je vous recommande de les inclure dans un fichier, ajoutez le fichier .jar au chemin de classe:

Java -classpath .;company.jar foo.bar.baz.YourClass

Google pour "classpath Java". Il trouvera des liens comme ceci .

Une dernière chose: "importer" ne charge pas les classes. Tout cela vous évite de taper. Lorsque vous incluez une instruction d'importation, vous ne devez pas utiliser le nom de classe entièrement résolu dans votre code - vous pouvez taper "Foo" au lieu de "com.company.thing.Foo". C'est tout ce que ça fait.

10
duffymo

On dirait que vous êtes sur la bonne voie avec votre structure de répertoires. Lorsque vous compilez le code dépendant, spécifiez l'argument -classpath de javac. Utilisez le répertoire parent du répertoire com, où com, à son tour, contient company/thing/YourClass.class

5
erickson

Vous avez une foule de bonnes réponses, je vais donc émettre une suggestion. Si vous envisagez de travailler sur ce projet pendant plus de 2 jours, téléchargez Eclipse ou netbeans et construisez-y votre projet.

Si vous n’êtes pas normalement un programmeur Java, l’aide qu’elle vous apportera sera inestimable.

Cela ne vaut pas la peine de télécharger/installer pendant une demi-heure si vous ne passez que 2 heures dessus.

Les deux ont des raccourcis clavier/des éléments de menu pour "Réparer les importations", avec cela vous ne devriez plus jamais avoir à vous soucier des importations.

5
Bill K

Le chargeur de classe Java standard est un stickler pour la structure de répertoires. Chaque entrée du chemin de classe est un répertoire ou un fichier jar (ou un fichier Zip, en réalité), dans lequel elle recherche ensuite le fichier de classe donné. Par exemple, si votre chemin de classe est ".; My.jar", il recherchera com.example.Foo aux emplacements suivants:

./com/example/
my.jar:/com/example/

C'est-à-dire qu'il va chercher dans le sous-répertoire qui a le 'nom modifié' du paquet, où '.' est remplacé par le séparateur de fichier.

En outre, il est à noter que vous ne pouvez pas imbriquer des fichiers .jar.

3
krakatoa

Ajoutez simplement une entrée de chemin de classe (je veux dire l’emplacement de votre répertoire parent) dans le menu Variables système et variables utilisateur .... Suivre. Cliquez avec le bouton droit de la souris sur Poste de travail> Propriétés> Avancé> Variables d’environnement.

0
cbinder