views:

4163

answers:

2

I have a standard project layout for a java project:

project /
    src /
        source_file_1.java
        ...
        source_file_N.java
    build /
          classes /
              source_file_X.class
              ...
          jar /
              MyJar.jar
    lib /
          SomeLibrary.jar
          SomeOtherLibrary.jar

As far as I can tell, I am building the project correctly with Ant. I need to set the class-path attribute in the Manifest file so my classes can use the required libraries.

The following relevant information from build.xml

<target name="compile" depends="init">
 <javac srcdir="src" destdir="build\classes">
  <classpath id="classpath">
   <fileset dir="lib">
    <include name="**/*.jar" />
   </fileset>
  </classpath>
 </javac>
</target>

<target name="jar" depends="compile">
 <jar destfile="build\jar\MyJar.jar" basedir="build\classes" >
  <manifest>
   <attribute name="Built-By" value="${user.name}" />
  </manifest>
 </jar>
</target>

Any push in the right direction is appreciated. Thanks

+1  A: 

Looking at my NetBeans-generated build file, I found this snippet in the -do-jar-with-libraries task:

<manifest>
    <attribute name="Main-Class" value="${main.class}"/>
    <attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>

So in other words, it looks like you just need to add another attribute to the manifest task that you already have.

See also the Manifest Task documentation.

Michael Myers
I came to this conclusion myself before you answered, though I was unaware of jar.classpath. I was getting thrown off by <manifestclasspath> in the ant documentation http://ant.apache.org/manual/CoreTasks/manifestclasspath.html
oh yea and thanks
jar.classpath is defined by NetBeans elsewhere in the build file, I believe.
Michael Myers
+6  A: 

Assuming the libraries do not change location from compiling to executing the jar file, you could create a path element to your classpath outside of the compile target like so:

<path id="compile.classpath">
    <fileset dir="lib" includes="**/*.jar"/>
</path>

Then you can use the created path inside your javac task in place of your current classpath.

<classpath refid="compile.classpath"/>

You can then use the path to set a manifestclasspath.

<target name="jar" depends="compile">
    <manifestclasspath property="jar.classpath" jarfile="build\jar\MyJar.jar">
      <classpath refid="compile.classpath"/>
    </manifestclasspath> 
    <jar destfile="build\jar\MyJar.jar" basedir="build\classes" >
     <manifest>
      <attribute name="Built-By" value="${user.name}" />
      <attribute name="Class-Path" value="${jar.classpath}"/>
     </manifest>
    </jar>
</target>

The manifestclasspath generates a properly formatted classpath for use in manifest file which must be wrapped after 72 characters. Long classpaths that contain many jar files or long paths may not work correctly without using the manifestclasspath task.

Daniel Nesbitt