javaeclipseanttaskdef

ANT eclipse headless build - java.lang.NoClassDefFoundError


I am trying to make a headless build that requires eclipse specific tasks.

For launching the ant buildfile, I use the following command. I do it this way because I believe it allows me to run eclipse tasks that previously complained that they needed a workspace to run in. If this is incorrect/if there is a better way, please inform me.

My batch script:

    java -jar %EQUINOX_LAUNCHER_JAR% -application org.eclipse.ant.core.antRunner -buildfile %ANT_SCRIPT_JAR% -data %WORKSPACE_PATH%

Inside my ant buildfile, I need to define a task:

<taskdef name="myTask" classname="path.to.class.with.execute"><classpath><pathelement location="path\to\dependency.jar"/></classpath></taskdef>

When running

<myTask/>

I get

java.lang.NoClassDefFoundError: path/to/class/that/I/tried/to/import

Solution

  • Classes which your task’s code uses must be in the classpath. One option is to add them explicitly to the classpath when defining the task:

    <taskdef name="myTask" classname="path.to.class.with.execute">
        <classpath>
            <pathelement location="path/to/dependency.jar"/>
            <pathelement location="path/to/transitive-dependency.jar"/>
            <pathelement location="path/to/other-transitive-dependency.jar"/>
        </classpath>
    </taskdef>
    

    If all the .jar files are in the same directory tree, you can shorten it to:

    <taskdef name="myTask" classname="path.to.class.with.execute">
        <classpath>
            <fileset dir="path/to/dir" includes="**/*.jar"/>
        </classpath>
    </taskdef>
    

    One other possibility is to add a Class-Path attribute to the manifest of the .jar which contains the task class. The attribute’s value is a space separated list of relative URLs, with their implied base being the .jar file where the manifest resides. For example:

    Class-Path: transitive-dependency.jar utils/other-transitive-dependency.jar
    

    If you’re building the task .jar itself in Ant, you can specify the Class-Path attribute in Ant’s jar task:

    <jar destfile="task.jar">
        <fileset dir="classes"/>
        <manifest>
            <attribute name="Class-Path"
                value="transitive-dependency.jar utils/other-transitive-dependency.jar"/>
        </manifest>
    </jar>