JARring with Ant
My project has many dependencies that I've referenced from other projects. I am now writing the build.xml file and am currently writing the JAR task. I guess I'll begin with the bold presumption that if I expect my JAR to behave correctly outside of Eclipse, I'll need to include a copy of each referenced JAR dependency somehwere in the JAR file.
So I now need to add a fileset
under the jar
task to instruct Ant to include these dependencies in the JAR. The problem is, when I switch to Navigator View and try to find my dependencies in my project, I don't find them! The only reference to them is in a .classpath
file that references their absolutely URLs, which I assume is how Eclipse finds them.
So my question is, how do I instruct Ant to look for the dependencies in this .classpath file and include them in my JAR?
My fear is that I'll have to first manually copy each JAR into a directory underneath my project root, and then simply reference that directory in my build. But there'a a lot of JARs, and that would mean a lot of tiem lost to copy-n-pastin'.
Please no suggestions for Ivy or Maven, I'm well aware that these are the best solutions for my situation but for reasons outside the scop开发者_JAVA百科e of this question, they are just not feasible.
Thanks for any help.
Do you want your project to produce an executable jar or will it be part of a distributable package that gets extracted and run? If its not an executable jar that you need then you should create a jar that includes just the classes and resources from your project without any of the dependent jars. Then if you want to release your project as a distributable package you would probably create a zip and tar.gz that includes the dependencies.
There is no way that I know of to automatically synchronize filesets between Ant and the Eclipse .classpath file. Aside from writing your own tool, which I've seen done before. So the manual copying of jars may turn out to be the quickest solution.
You could export the project from Eclipse as an Ant build file (right click the project, click export, select Ant Build File). The exported build.xml file will contain a path
element called <your project name>.classpath
. That path
element will contain the paths of all the jars needed to build your application. Since you want to use a fileset
you could modify the generated build.xml
to reuse that path
.
The only other way to get Ant to use Eclipse's classpath is to write Ant so that it parses the .classpath file.
As a side note, I don't recommend trying to put jars inside of jars. Java can't load classes from a jar inside a jar (unless you write your own class loader to do that). You can use a zipfileset
if you absolutely need to. However, the proper solution is to bundle the 3rd party jars outside your application's jar file when you distribute your application. Then set up the classpath property in your MANIFEST.MF file to refer to the paths of the files (you can reuse the <your project name>.classpath
from above for the MANIFEST.MF.
You can declare the dependent JARs path tag or so and use it as reference to classpath later. For example,
<project basedir="." default="build.all" name="My Application">
<path id="myclasspath">
<pathelement location="${project.syslib}/log4j-1.2.8.jar"/>
<pathelement location="${project.syslib}/xalan.jar"/>
<pathelement location="${project.syslib}/common.jar" />
<fileset dir="${config.common}/taglib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${config.csr}/taglib">
<include name="**/*.jar"/>
</fileset>
</path>
<target name="compile" depends="prepare" >
<javac srcdir="${project.root}/src"
destdir="${project.root.build}"
classpathref="myclasspath"
nowarn="yes"
debug="on"
fork="yes"
memoryInitialSize="80m"
memoryMaximumSize="256m"
/>
</target>
</project>
Also, in Eclipse if you add jars through Add Jars button then it uses relative path.
I think copy&paste is the smallest problem if you have so many dependencies. The main problem is that you are no longer modular and flexible during development. Try to reduce them and keep only the dependencies really necessary. For this, you can for instance use Jdepend or metrics or - both have Eclipse plugins (or Class Dependency Analyzer).
The dependencies that are left can either be put all together in one jar (that is all class files, not nested jars), which might be comfortable to some people, or externally in a separate file each, which is more common and especially useful for third party libraries that the users might have already anyways.
My point being: modularity is good, for development as well as deployment.
精彩评论