0
votes

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
1
The only possibilities are that either the path to the .jar is wrong, or the class name is wrong. Is the path to the .jar a relative path? If so, is it relative to the build file? Are you specifying an alternate basedir for the project? Did you double-check that the .jar contains the class? - VGR
All paths are absolute. Correct me if I'm wrong, but since the task executes but then gets an error, I believe that means that my classname is set up correctly. I don't believe I set up an alternate basedir - David
So the NoClassDefFoundError is not referring to the task class itself? - VGR
Yep, it is referring to a class that is completely outside the jar that path.to.class.with.execute is in. - David
Any classes on which that class depends will also need to be in the classpath you provide when defining the task. The same goes for any dependencies of other classes which the task might use. - VGR

1 Answers

1
votes

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>