Java:Ant脚本就像一个魅力,但是Jar会抛出异常

时间:2012-03-10 11:41:44

标签: java ant jar classpath noclassdeffounderror

我创建了我的第一个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

2 个答案:

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