THE MANGO
THE MANGO

Reputation: 11

Can't run Java code after compiling with ANT

I've got the following project structure:

ProjectDir
-src
-lib
-data

src is the Java source files, lib contains several external JARs that my project uses, and data contains a variety of text files that the program uses to store and reference data. Up until now I've done all my development in an IDE (obviously) and everything's been fine, but I'm trying to write a build file that compiles the code (with the JARs in the classpath) and can be run with the data files. It's been a while since I've done a build with ANT so I'm sure this is a simple problem but I can't get the build script to work properly.

Below is the ant file:

<project name="CMSC491Project" basedir="." default="main">

    <property name="src.dir"     value="src"/>

    <property name="build.dir"   value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir"     value="${build.dir}/jar"/>
    <property name="lib.dir"     value="lib"/>

    <property name="main.class"  value="parse.Driver"/>
    <property name="args"     value="?"/>



    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>

    <fileset id="lib" dir="${lib.dir}">
        <include name="*.jar"/>
    </fileset>

    <path id="build.classpath">
        <fileset refid="${lib.dir}"/>
    </path>

    <target name="compile">
        <mkdir dir="${classes.dir}"/>

        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="build.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}"/>
        <attribute name="Class-Path" value="${lib.dir}/javahash ${lib.dir}/twitter4j-core-2.2.5 ${lib.dir}/twitter4j-stream-2.2.5"/>
            </manifest>
        </jar>
    </target>

    <target name="clean-build" depends="clean,jar"/>

    <target name="main" depends="clean,jar"/>

    <target name="run" depends="compile" description="run the project">
        <java dir="${classes.dir}" classname="${main.class}" fork="yes">
            <arg line="${args}"/>
        </java>
    </target>

</project>

It compiles fine, but if I try ant run I get an error saying that java can't find one of the classes from one of the JARs from the data directory.

Not sure what it needs me to do, but thanks in advance.

Upvotes: 1

Views: 1636

Answers (2)

S.R.I
S.R.I

Reputation: 1870

You use dir in java ant task. That tells your JVM to invoke the process in that directory. Have a look at the docs here. You should be referring to the jar either via jar or classpath attribute. Try changing your build configuration to:

<path id="build.classpath">         
    <fileset refid="lib"/>
    <fileset dir="${classes.dir}"/>     
</path>

<target name="run" depends="compile" description="run the project">
    <java classpathref="build.classpath" classname="${main.class}" fork="yes">
        <arg line="${args}"/>
    </java>
</target>

EDIT (Include classpathref in compilation)

Upvotes: 2

Mark O&#39;Connor
Mark O&#39;Connor

Reputation: 77991

You have not specified the correct relative links to the jars your executable jar depends upon. Your jar is located here:

build/jar

and it cannot find jars in the following locations (Take from the "Class-Path" in your manifest):

build/jar/lib/??.jar

The best way to solve this problem is to use ANT's manifestclasspath task:

<manifestclasspath property="jar.classpath" jarfile="${jar.dir}/${ant.project.name}.jar">
    <fileset dir="lib" >
        <include name="*.jar"/>
    </fileset>
</manifestclasspath>

<jar jarfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
   <manifest>
      <attribute name="Main-Class" value="${main-class}"/>
      <attribute name="Class-Path" value="${jar.classpath}"/>
   </manifest>
</jar>

Once all this is setup you run the jar as follows:

<java dir="${classes.dir}" jar="${jar.dir}/${ant.project.name}.jar" fork="yes">
    <arg line="${args}"/>
</java>

There are two ways to run a jar. Either using the jar parameter to specifying the main class using classname.

Only the jar parameter will use the classpath embedded in your jar files manifest. If you use classpath you'll be forced to specify it.

You should finally consider how this jar will be distributed. If you give the jar to someone else, they'll need to have the dependencies located in a directory which is located in the following relative path to the jar

../../lib

Upvotes: 0

Related Questions