0

I created my first Ant script and it's working pretty well. It compiles all my java sources, creates a .jar file and runs the program without even any warning.

But when i try to run my .jar from command line i get NoClassDefFoundError exceptions.

So, how to translate this Ant snippet to work from command line?

<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>

This is the command line:

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

Throws:

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)

Why does my .jar file not work with the defined classpath? Further down the Ant script:

<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>

Again, running the Ant script works fine. I even tried adding the said libraries to my .jar but that only blows up the file size, the problem still persists.

<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>

Any ideas on this?

Thanks a lot, donc_oe

SOLVED: Thanks to perception, the unix command line i was looking for is:

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

And for Windows (note the ; semicolon):

# javaw -cp lib/*;bin/myjarfile.jar my.package.MyMainClass
Community
  • 1
  • 1
q9f
  • 11,293
  • 8
  • 57
  • 96

2 Answers2

1

The relevant thing to note from your build script is this:

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

With that little snippet you have defined a path construct in Ant, which you then refer to in your run task:

<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>

This is in effect executing:

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

Of course, it does so without the squigly lines and the path(s) fully substituted. The main point being that the command you are trying to run yourself is not equivalent at all. When attempting to invoke from the command line you will need to include in the classpath all the necessar JAR's containing your code and all third party libraries. Assuming everything is still bundled in the Ant created folders, something like:

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

Or:

java -cp <full-path-to-lib?/*:<full-path-to-bin>/omsimulation-0.4.45-beta3.jar <MainClass>
Perception
  • 79,279
  • 19
  • 185
  • 195
  • Using this `java -cp lib/*.jar:bin/omsimulation-0.4.45-beta3.jar de.bfs.radon.omsimulation.OMMainFrame` still throws the NoClassDefFoundError. Using `java -cp /home/qh/Desktop/omsimulation-0.4/lib/*.jar -jar /home/qh/Desktop/omsimulation-0.4/bin/omsimulation-0.4.45-beta3.jar` with full path simply tells me: `Error: Could not find or load main class (... of some libs)`. Question how to create a _standalone_ .jar file which knows where to look for external libs? – q9f Mar 10 '12 at 12:12
  • Try the second way again, but this time add (the full path for) your `omsimulation` jar to the classpath as well, and invoke the main class instead of using -jar. – Perception Mar 10 '12 at 12:25
  • added my jar to the classpath and specified the main class instead of using the -jar: `java -cp /home/qh/Desktop/omsimulation-0.4/lib/*.jar:/home/qh/Desktop/omsimulation-0.4/bin/omsimulation-0.4.45-beta3.jar de.bfs.radon.omsimulation.OMMainFrame` - same result `NoClassDefFoundError: com/toedter/calendar/JDateChooser` - i manually checked that this class is existing. it's a mess ... – q9f Mar 10 '12 at 12:51
  • 1
    Are you on a Windows machines? If so then the classpath elements should be separated by `;` instead of `:`. – Perception Mar 10 '12 at 13:13
  • 1
    Crap, there is an error in the classpath I showed, thats it, no more morning code examples before coffee. See edits. – Perception Mar 10 '12 at 13:22
  • Thanks, removing `.jar` was doing the job. Thats working now. Hell, ... :) – q9f Mar 10 '12 at 13:30
  • Whew, that took awhile! Welcome to SO and congrats on your first question. Don't forget to accept this answer if it helped resolve your issue! – Perception Mar 10 '12 at 13:32
0

ClassDefNotFoundException most likely occur when class is found in classpath, but it is loaded in different classloader, or in a wrong path etc.

From the build file, you appears to create jar that include other jars. This may not give a result you want.

Most likely you want a solution described in Easiest way to merge a release into one JAR file. My personal favorite is one-jar.

Community
  • 1
  • 1
Jayan
  • 18,003
  • 15
  • 89
  • 143
  • Thanks for the links, I will take a look into them. (I only added the jars to my own jar for testing purposes, it's now working without..) – q9f Mar 10 '12 at 13:43