2011-05-28 5 views
8

J'ai des problèmes avec l'exécution d'une application Java dans la console et/ou avec Ant. Je sais que beaucoup de problèmes de démarrage sont liés au fait que le chemin de classe n'est pas défini ou incorrectement défini, bien que je sois à peu près sûr de le configurer correctement, donc ma recherche n'a donné que des résultats.Java NoClassDefFoundError malgré set classpath

Voici la configuration générale de mon application: les classes sont dans les paquets modèle, vue et le contrôleur. controller.Controller est la classe avec la méthode principale. J'utilise objectdb comme fournisseur JPA. J'utilise Ant pour compiler mon application.

Après la compilation, je peux courir ma demande de fourmi avec le script suivant:

<target name="run" description="default build process"> 
    <java fork="true" classname="${main-class}"> 
     <classpath> 
      <path refid="classpath" /> 
     </classpath> 
    </java> 
</target> 

où $ {classe principale} est Controller.Controller et classpath se compose de/lib et/dossiers dist (de l'application fichier jar est compilé à/dist)

maintenant, j'essayé de copier tous les fichiers .jar/lib et/dist dans un dossier séparé et les exécuter avec java -jar cooking.jar -cp . qui se traduit par

Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/Persistence 
    at model.jpa.JPAModelFactory.<init>(JPAModelFactory.java:28) 
    at model.jpa.JPAModelFactory.<init>(JPAModelFactory.java:24) 
    at controller.Controller.<init>(Controller.java:59) 
    at controller.Controller.main(Controller.java:116) 
Caused by: java.lang.ClassNotFoundException: javax.persistence.Persistence 
    at java.net.URLClassLoader$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
    ... 4 more 

donc j'ai essayé fourmi et légèrement modifié ci-dessus la construction cible:

<target name="run2" description="default build process"> 
    <java fork="true" jar="${dist.dir}/${ant.project.name}.jar"> 
     <classpath> 
      <path refid="classpath" /> 
     </classpath> 
    </java> 
</target> 

qui entraîne la même erreur. Je ne comprends pas pourquoi.

Juste pour le tester, j'ai essayé de courir à partir de la ligne de commande en spécifiant la classe principale directement: java -cp . controller.Controller qui, pour une raison quelconque ne peut pas localiser même la classe (il est là, je l'a confirmé):

Exception in thread "main" java.lang.NoClassDefFoundError: controller/Controller 
Caused by: java.lang.ClassNotFoundException: controller.Controller 
    at java.net.URLClassLoader$1.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
    at java.lang.ClassLoader.loadClass(Unknown Source) 
Could not find the main class: controller.Controller. Program will exit. 

I J'ai défini JAVA_HOME sur le chemin de mon JDK, et CLASSPATH sur le chemin de mon JRE/lib. OS est Windows 7 64 bits, la version Java est 1.6.0_25-b06

Je suis perplexe par deux choses: a) Pourquoi est incapable de localiser Java Controller.Controller, même si elle est présente dans le fichier .jar et le fichier .jar est dans le répertoire en cours? b) Qu'est-ce que je fais de mal qu'appeler Java avec -jar semble gâcher les mécanismes de recherche.

Toute aide est fortement appréciée.

+0

Que voyez-vous dans votre fichier Manifest.MF pour les entrées class-path et Main-class? – CoolBeans

+0

Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.1 Créé par: 20.0-b11 (Sun Microsystems Inc.) Classe principale: controller.Controller – Tobias

Répondre

1

si je suis assez sûr que je l'ai mis correctement

La preuve est contre vous. La machine virtuelle Java vous indique que vous ne l'avez pas définie correctement.

À quoi pensez-vous que ref 'classpath' pointe? D'où tenez-vous ses valeurs? Ils devraient être définis dans le build.xml Ant, non? Comme ceci:

<path id="production.class.path"> 
    <pathelement location="${production.classes}"/> 
    <pathelement location="${production.resources}"/> 
    <fileset dir="${production.lib}"> 
     <include name="**/*.jar"/> 
     <exclude name="**/junit*.jar"/> 
     <exclude name="**/*test*.jar"/> 
    </fileset> 
</path> 

<path id="test.class.path">        
    <path refid="production.class.path"/> 
    <pathelement location="${test.classes}"/> 
    <pathelement location="${test.resources}"/> 
    <fileset dir="${test.lib}"> 
     <include name="**/junit*.jar"/> 
     <include name="**/*test*.jar"/> 
    </fileset> 
</path> 

Si vous créez un JAR exécutable, vous devez spécifier la classe principale et classpath dans le manifeste, comme coolbeans souligné à juste titre dans le commentaire. Les emplacements JAR tiers doivent être relatifs au fichier JAR exécutable. Vous devriez les empaqueter avec votre JAR exécutable de telle manière que le chemin relatif soit facile à trier et à comprendre.

+0

Merci pour les réponses jusqu'à présent. – Tobias

+0

Merci pour les réponses. J'ai précisé la classe principale dans le manifeste comme on peut le voir dans mon commentaire ci-dessus. En outre, dans le chemin de classe ant-file pointe vers deux dossiers ("et classpath se compose de dossiers/lib et/dist (le fichier jar de l'application est compilé à/dist)". Je publierais ici la définition de mon fichier de construction. La section des commentaires ne formate pas bien les choses, mais il n'y a pas de jar-emplacements dans le fichier manifeste, je pensais que c'est à ça que sert le commutateur -cp Si cela ne suffit pas, comment puis-je définir les emplacements dans le manifeste – Tobias

+0

-cp est la façon de spécifier le chemin de classe en ligne de commande.Ant n'a aucun effet sur votre fichier JAR à l'exécution - c'est un outil de construction.S'il vous plaît mieux que vous apprendre à définir classpath dans le manifeste de votre JAR: http://download.oracle.com/javase/tutorial/deployment/jar/downman.html – duffymo

2

Le chemin de la classe devrait consister en

  1. répertoires avec des fichiers de classe (dans leur répertoire du paquet)
  2. fichiers jar.

Vous ne pouvez pas pointer le chemin de classe vers un répertoire de fichiers jar. Les choses sont différentes lors de l'exécution d'un serveur d'application (par exemple Tomcat), qui va charger des fichiers jars à partir d'un répertoire pour vous.

0

J'ai trouvé cela se produit lorsque je spécifie à la fois le <classpath> et le jar="..." dans la cible. J'ai retiré le jar="...", placé .jar dans la liste <classpath> et il a couru après cela.