Could not find the main class error with Ant
-
04-06-2021 - |
Domanda
It's my first time using Ant and I'm getting a java.lang.NoClassDefFoundError
Exception when it tries to run. Here is my Ant build script,
<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>
The build gives no errors. The run target gives the exception. I've checked the manifest generated in the jar file and it looks like this,
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
Soluzione
Your run target looks a bit wonky, the <java classname="${main-class}" fork="true" />
is self closing, so the classpath
element is never used
<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>
May work for you.
Altri suggerimenti
The problem is that you are not specifying the classpath for the java
task properly.
Try this:
<java classname="${main-class}" fork="true">
<classpath>
<path refid="classpath" />
<path location="${jar.dir}/${ant.project.name}.jar" />
</classpath>
</java>
And I have the likely problem. My script is the following:
<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>
And when I run, I get the following error:
[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
But if I CD to the folder "${tomcat.home}/webapps/${project.war}-admin/WEB-INF/lib/
" and run:
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)
it worked!
And finally the decision has been found! We rewritten the script in the following way:
<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>