我创建了我的第一个Ant脚本,它运行得很好。它编译我的所有java源代码,创建.jar文件并运行程序,甚至没有任何警告。
但是当我尝试从命令行运行我的.jar时,我得到NoClassDefFoundError异常。
那么,如何将此Ant片段转换为从命令行工作?
<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>
这是命令行:
# java -classpath lib/ -jar bin/omsimulation-0.4.45-beta3.jar
抛出:
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)
为什么我的.jar文件无法使用定义的类路径?进一步沿着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>
再次,运行Ant脚本可以正常工作。我甚至尝试将这些库添加到我的.jar中,但这只会炸掉文件大小,问题仍然存在。
<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>
有关于此的任何想法吗?
非常感谢, donc_oe
已解决:感谢perception,我正在寻找的unix命令行是:
# java -cp lib/*:bin/myjarfile.jar my.package.MyMainClass
对于Windows(请注意; 分号):
# javaw -cp lib/*;bin/myjarfile.jar my.package.MyMainClass
答案 0 :(得分:1)
您的构建脚本需要注意的相关事项是:
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
使用这个小片段,您在Ant中定义了一个path
构造,然后在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>
这实际上是在执行:
java -cp ${lib.dir}/*.jar:${bin.dir}/omsimulation-${version}.jar ${main.class}
当然,如果没有完整的线条和完全替代的路径,它就会这样做。重点是你试图自己运行的命令根本不相同。尝试从命令行调用时,您需要在类路径中包含所有必需的JAR,其中包含您的代码和所有第三方库。假设所有内容仍然捆绑在Ant创建的文件夹中,例如:
java -cp <full-path-to-lib>/* -jar <full-path-to-bin>/omsimulation-0.4.45-beta3.jar
或者:
java -cp <full-path-to-lib?/*:<full-path-to-bin>/omsimulation-0.4.45-beta3.jar <MainClass>
答案 1 :(得分:0)
ClassDefNotFoundException很可能发生在类路径中找到类时,但是它被加载到不同的类加载器或错误的路径中等。
从构建文件中,您似乎创建了包含其他jar的jar。这可能无法给出您想要的结果。
您很可能想要Easiest way to merge a release into one JAR file中描述的解决方案。我个人最喜欢的是one-jar。