I am trying to rearchitect my build technique for creating Java jar files which depend on common 3rd party jar files. (GlazedLists, Apache Commons, etc.)
I had been chucking them all into {Java JRE dir}/lib/ext so they would automatically be seen by the JRE, but that led to problems like not remembering that I need to distribute certain jar files, so I'd like to learn to be more explicit.
So I moved them all into c:\appl\java\common\, added them to the Eclipse build path, aand defined this in my ant file:
<path id="javac_classpath">
<fileset dir="${libDir}">
<include name="*.jar"/>
</fileset>
<fileset dir="c:/appl/java/common">
<include name="*.jar"/>
</fileset>
</path>
I have my Class-Path manifest header set to "." in my jar
task but that doesn't seem to work even if I put the relevant jar files into the same directory as my application jar file. I can add them all manually one-by-one to the Class-Path header, but I'm wondering, is there an easier way to get the Class-Path header setup properly?
With ant 1.7 and after, the manifestclasspath task is the way forward. If you are using a version of ant prior to 1.7, the manifestclasspath task does not exist.
The following gives the same result: -
This is all you need:
As you can probably see, it assumes you've compiled your Java classes and output them to
${build}
. It also assumes you've copied your jarfiles to${dist}/lib
.That said, it would be worth looking into other build systems which have built-in support for dependencies, such as Maven and Gradle. These other build systems have already thought through many common project structures and build operations, so you don't have to script everything down to the last detail.
The Class-Path manifest header for jar files requires you to explicitly list the jar files you want to include. Listing a directory in the classpath means java will look for .class files in that directory, not jarfiles.
Classpath directories do not, by default, include Jar files for security reasons. Someone could place a jar file in there, and it could be loaded up, overriding your code, without your knowledge. I do know that there was discussion about adding another flag or ending token to allow Jar files to be added to the classpath, but, if my memory serves, that is slated for version 7. However, I could be wrong on the last part.
What you want is a mapper. Flattenmapper is probably the easiest, but essentially you need to create a path element which specifies your classpath, then use a pathconvert on it to turn it into a string that can be included in your manifest.
Edit: you can use include rules to build the path element, so everything in a directory ending with jar would be
**/*.jar
Since you're in Ant, you probably don't want to switch, but Maven is pretty good at identifying all your dependencies, and has several facilities for copying or combining your lib jars together for distribution purposes. For my purposes I have a Maven plugin that creates a run script during build, which in turn sets the classpath for me so I don't need to worry about it.