Java: le script Ant fonctionne comme un charme, mais Jar lève des exceptions


J'ai créé mon premier script Ant et ça marche plutôt bien. Il compile toutes mes sources java, crée un .fichier jar et exécute le programme sans même aucun avertissement.

Mais quand j'essaie de courir mon .jar à partir de la ligne de commande, j'obtiens des exceptions NoClassDefFoundError.

Alors, comment traduire cet extrait de fourmi pour fonctionner à partir de la ligne de commande?

<property name="main.class" value="de.bfs.radon.omsimulation.OMMainFrame"/>

<path id="classpath">
  <fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

<target name="run" depends="jar">
  <java fork="true" classname="${main.class}">
    <classpath>
      <path refid="classpath"/>
      <path location="${bin.dir}/omsimulation-${version}.jar"/>
    </classpath>
  </java>
</target>

C'est la ligne de commande:

# java -classpath lib/ -jar bin/omsimulation-0.4.45-beta3.jar

Jette:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: com/toedter/calendar/JDateChooser
    at de.bfs.radon.omsimulation.OMMainFrame.(OMMainFrame.java:133)
    at de.bfs.radon.omsimulation.OMMainFrame$1.run(OMMainFrame.java:106)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)

Pourquoi mon .fichier jar ne fonctionne pas avec le défini classpath? Plus bas le script Ant:

<target name="jar" depends="manifest">
  <mkdir dir="${bin.dir}" />
  <jar jarfile="${bin.dir}/omsimulation-${version}.jar" manifest="${src.dir}/omsimulation.manifest" compress="no" basedir="${build.dir}" includes="de/**" />
</target>

<target name="manifest" depends="compile">
  <manifestclasspath property="manifest.cp" jarfile="${bin.dir}/omsimulation-${version}.jar">
    <classpath refid="classpath" />
  </manifestclasspath>
  <manifest file="${src.dir}/omsimulation.manifest">
    <attribute name="Built-By" value="${author}"/>
    <attribute name="Main-Class" value="${main.class}"/>
  </manifest>
</target>

Encore une fois, l'exécution du script Ant fonctionne correctement. J'ai même essayé d'ajouter lesdites bibliothèques à mon .jar mais cela ne fait qu'exploser la taille du fichier, le problème persiste.

<jar jarfile="${bin.dir}/omsimulation-${version}.jar" manifest="${src.dir}/omsimulation.manifest" compress="no" basedir="${build.dir}"> <!-- includes="de/**" /-->
  <fileset dir="${lib.dir}">
    <include name="**/*.jar" />
  </fileset>
</jar>

Des idées à ce sujet?

Merci beaucoup, donc_oe

RÉSOLU : Grâce à perception, la ligne de commande unix que je cherchais est:

# java -cp lib/*:bin/myjarfile.jar my.package.MyMainClass

Et pour Windows (notez le ; point-virgule):

# javaw -cp lib/*;bin/myjarfile.jar my.package.MyMainClass
Author: Community, 2012-03-10

2 answers

La chose pertinente à noter dans votre script de construction est la suivante:

<path id="classpath">
  <fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

Avec ce petit extrait, vous avez défini une construction path dans Ant, à laquelle vous faites ensuite référence dans votre tâche run:

<target name="run" depends="jar">
  <java fork="true" classname="${main.class}">
    <classpath>
      <path refid="classpath"/>
      <path location="${bin.dir}/omsimulation-${version}.jar"/>
    </classpath>
  </java>
</target>

Ceci est en effet en cours d'exécution:

java -cp ${lib.dir}/*.jar:${bin.dir}/omsimulation-${version}.jar ${main.class}

Bien sûr, il le fait sans les lignes squigly et le(s) chemin (s) complètement substitué (s). Le point principal étant que la commande que vous essayez d'exécuter vous-même n'est pas équivalent à tous. Lorsque vous tentez d'appeler à partir de la ligne de commande besoin d'inclure dans le classpath tous les JAR nécessaires contenant votre code et toutes les bibliothèques tierces. En supposant que tout est toujours regroupé dans les dossiers créés par Ant, quelque chose comme:

java -cp <full-path-to-lib>/* -jar <full-path-to-bin>/omsimulation-0.4.45-beta3.jar

Ou:

java -cp <full-path-to-lib?/*:<full-path-to-bin>/omsimulation-0.4.45-beta3.jar <MainClass>
 1
Author: Perception, 2012-03-10 13:23:20

ClassDefNotFoundException se produit très probablement lorsque la classe est trouvée dans classpath, mais elle est chargée dans un chargeur de classe différent, ou dans un mauvais chemin, etc.

À partir du fichier de génération, vous semblez créer un fichier jar qui inclut d'autres fichiers jar. Cela peut ne pas donner le résultat souhaité.

Très probablement, vous voulez une solution décrite dans Moyen le plus simple de fusionner une version dans un fichier JAR. Mon préféré est one-jar.

 0
Author: Jayan, 2017-05-23 11:55:53