这是我第一次使用 Ant,当它尝试运行时,我遇到了java.lang.NoClassDefFoundError
异常。这是我的 Ant 构建脚本,
<project name="LearnKirtan" basedir="." default="main">
<property name="src.dir" value="src" />
<property name="lib.dir" value="lib" />
<property name="build.dir" value="build" />
<property name="classes.dir" value="${build.dir}/classes" />
<property name="jar.dir" value="${build.dir}/jar" />
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar" />
</path>
<property name="main-class" value="gsingh.learnkirtan.Main" />
<target name="clean">
<delete dir="${build.dir}" />
</target>
<target name="compile">
<mkdir dir="${classes.dir}" />
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" classpathref="classpath" />
</target>
<target name="jar" depends="compile">
<mkdir dir="${jar.dir}" />
<jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Main-Class" value="${main-class}" />
</manifest>
</jar>
</target>
<target name="run" depends="jar">
<java classname="${main-class}" fork="true" />
<classpath>
<path refid="classpath" />
<path location="${jar.dir}/${ant.project.name}.jar" />
</classpath>
</target>
<target name="clean-build" depends="clean,jar" />
<target name="main" depends="clean,run" />
</project>
构建不会给出任何错误。运行目标给出异常。我已经检查了jar文件中生成的清单,它看起来像这样,
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.6.0_30-b12 (Sun Microsystems Inc.)
Main-Class: gsingh.learnkirtan.Main
你的运行目标看起来有点不稳定,<java classname="${main-class}" fork="true" />
是自闭合的,所以从不使用classpath
元素
<target name="run" depends="jar">
<java classname="${main-class}" fork="true" >
<classpath>
<path refid="classpath" />
<path location="${jar.dir}/${ant.project.name}.jar" />
</classpath>
</java>
</target>
可能为你工作。
问题是您没有正确指定java
任务的类路径。
试试这个:
<java classname="${main-class}" fork="true">
<classpath>
<path refid="classpath" />
<path location="${jar.dir}/${ant.project.name}.jar" />
</classpath>
</java>
我有一个可能的问题。我的脚本如下:
<java classname="SchedulerManager" fork="true">
<jvmarg value="-Ddb.username=${db.user}"/>
<jvmarg value="-Ddb.password=${db.password}"/>
<jvmarg value="-Ddb.url=${db.url}"/>
<classpath>
<pathelement location="${tomcat.home}/webapps/${project.war}-admin/WEB-INF/lib/${jar_name}"/>
<pathelement path="com.${company}.${project}.scheduler.SchedulerManager"/>
</classpath>
</java>
当我运行时,我收到以下错误:
[java] Exception in thread "main" java.lang.NoClassDefFoundError: com/<company>/<project>/scheduler/SchedulerManager
[java] Caused by: java.lang.ClassNotFoundException: com.<company>.<project>.scheduler.SchedulerManager
[java] at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
[java] at java.security.AccessController.doPrivileged(Native Method)
[java] at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
[java] at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
[java] at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[java] Could not find the main class: com.<company>.<project>.scheduler.SchedulerManager. Program will exit.
[java] Java Result: 1
但是如果我CD到文件夹" ${tomcat.home}/webapps/${project.war}-admin/WEB-INF/lib/
"并运行:
java -cp "*" -Ddb.username=${db.user} -Ddb.password=${db.password} -Ddb.url=${db.url} com.<company>.<project>.scheduler.SchedulerManager (of course I gave real parameters)
成功了!
终于找到了决定!我们按以下方式重写了脚本:
<path id="master-classpath">
<fileset dir="${tomcat.home}/webapps/${project.war}-admin/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${workspace.path}/artifacts">
<include name="${jar_name}"/>
</fileset>
<fileset dir="${workspace.path}/deploy_scripts/libs/app">
<include name="${jdbc_jar_name}"/>
</fileset>
</path>
<java classname="com.${company}.${project}.scheduler.SchedulerManager" fork="true">
<jvmarg value="-Ddb.username=${db.user}"/>
<jvmarg value="-Ddb.password=${db.password}"/>
<jvmarg value="-Ddb.url=${db.url}"/>
<classpath refid="master-classpath"/>
</java>