Search code examples
javaantbuildnoclassdeffounderrorbuild-script

Could not find the main class error with Ant


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

Solution

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