Create Jar for a specific file in a project using ant - java

I compiled all the java files using ant and stored the class files in a folder.
I want to make jar for a specific class file form the output folder(compiled).
How can i done this.
NOTE:The class file depends another classes in the project

Use the ant Jar Task with a nested fileset that specifies only the file(s) you wish to include in the jar file.
Something like:
<jar jarfile="pinky.jar">
<fileset dir="build/classes" >
<include name="com/example/Brain.class" />
</fileset>
</jar>

Related

How do I change the destination directory of Ant's fileset command?

I have an Ant buildfile for a Java library. It looks something like this:
<project ... ><target ... >
<jar destfile="C:\path\to\export.jar">
<manifest> ... </manifest>
<fileset dir="C:\path\to\bin" />
<fileset dir="C:\path\to\src" />
<fileset dir="C:\path\to\doc" />
<zipfileset src="C:\path\to\included\library.jar" />
</jar>
</target></project>
The only problem is that my JavaDoc is being exported directly into the root directory of the resulting jar file. Essentialy, I'd like some equivalent of the <copydir> command that can be used inside the <jar> command.
My desired structure is this:
export.jar
META-INF
Manifest.MF
com
example
whatever
Blah.class
Blah.java
org
external
somelibrary
Magic.class // contents of the included library jar file
doc
// javadoc files here
The current structure is:
export.jar
META-INF
Manifest.MF
com
example
whatever
Blah.class
Blah.java
// some javadoc files here
org
external
somelibrary
Magic.class // contents of the included library jar file
// more javadoc files here
My current "solution" is to omit the documentation <fileset> command, then, once the jar has exported, go into Windows Explorer and right click → 7-Zip → Open Archive; I can then drop the doc directory in there just fine. However, this pretty completely defeats the purpose of Ant as a completely automated build system.
If it matters, this file was originally generated by Eclipse with the Runnable JAR exporter. However, I obviously need to modify it to add source files, etc. because it's a library and not actually a runnable jar. I exported it as a runnable jar to get Eclipse to package in the required libraries; apparently libraries on the build path aren't available for export via the standard File → Export → JAR file.
A jar is actually like a zip file. Hence you can use a zipfileset. Its attribute prefix is what you are looking for.
The zipfileset command can accept either a zip file via src or a filesystem directory via dir. Using the latter, you can add the following command:
<zipfileset dir="C:\path\to\doc" prefix="doc" />
Also worth to note is that zipfileset supports all attributes of fileset. Thus if you want to include just a single file in a specific location you can use:
<zipfileset file="C:\path\to\doc\file.txt" prefix="doc" />
Further reading: http://ant.apache.org/manual/Types/zipfileset.html

Difference between setting classpath in build.xml using fileset and pathelement

I have a build file that declares the classpath as shown
<path id="compile.classpath">
<fileset dir="${basedir}/lib" includes="**"/>
<fileset dir="${jboss.home}/lib" includes="**"/>
<pathelement path ="${build.classes.dir}"/>
</path>
I tried looking at the documentation but I am not able to understand the use of
pathelement.
I know that the ID is used to refer to this class path while performing a task and fileset includes the jarfiles.
edit 1:
My doubt is Why can't we use fileset to include the class files in place of pathelement?
Latest edit:
My doubt is Why can't we use fileset to include the class files in place of pathelement?
If you use a fileset then you'd be adding a set of class files to the path as follows:
CLASSPATH=classes/MyClass1.class:classes/MyClass2.class:classes/MyClass3.class:....
When what Java expects to see is simply:
CLASSPATH=classes
Only jar (and WAR,EAR,etc) files are explicitly listed on the classpath (Java will open them up and load their class files), hence the need for a fileset in ANT.
Update
Here's the Oracle documentation:
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html
Class paths to the .jar, .zip or .class files. Each classpath should end with a filename or directory depending on what you are setting the class path to:
For a .jar or .zip file that contains .class files, the class path ends with the name of the .zip or .jar file.
For .class files in an unnamed package, the class path ends with the directory that contains the .class files.
For .class files in a named package, the class path ends with the directory that contains the "root" package (the first package in the full package name).
There was already similar question about 'pathelements' here. From the provided documentation:
"If it's path structure like in your example: "A path-like structure can include a reference to another path-like structure (a path being itself a resource collection) via nested elements"
<path id="base.path">
<pathelement path="${classpath}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
<pathelement location="classes"/>
</path>
If it's classpath structure:
"The path attribute is intended to be used with predefined paths"
<classpath>
<pathelement path="${classpath}"/>
<pathelement location="lib/helper.jar"/>
</classpath>

Trying to get a properties file from a jar file in another jar file

I have an executable jar file (A.jar), built with Eclipse, that relies on other jar files (B.jar) that are included in the jar file, and accessed via the jarinjarloader. While this works to access the java code inside those jar files, when that code calls
InputStream inStream = <Class>.getClassLoader().getResourceAsStream(propFile);
it fails to find the properties file contained in B.jar. The code works when run in Eclipse, so I know the correct properties files are there.
I tried extracting A.jar, then extracting B.jar, and then zipping up the combined files, but this does not work. Looking at the Manifest file, the Main-Class is org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Is there some change I can make to the Manifest file (say, adding something to Rsrc-Class-Path) that will get this to work? Rsrc-Class-Path includes "./" already, but that clearly isn't letting the properties loader see my properties files.
TIA,
Greg
I'd also recommend working around nested jars. I usually just do this in my build.xml to build one jar with all the libraries unpacked into it:
<target name="fatjar" depends="compile">
<jar destfile="${isamjar}" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="com.xyz.Main"/>
<attribute name="Class-Path" value="."/>
</manifest>
<fileset dir="./bin"/>
<fileset dir="." includes="src/**"/>
<zipfileset excludes="META-INF/*.SF" src="${l}/derby.jar"/>
<zipfileset excludes="META-INF/*.SF" src="${l}/jconn3.jar"/>
<zipfileset excludes="META-INF/*.SF" src="${l}/log4j-1.2.9.jar"/>
<zipfileset excludes="META-INF/*.SF" src="${l}/${jar4j}"/>
</jar>
Turns out Eclipse has a setting I missed. When Exporting a "Runnable JAR File" you can select "Extract required libraries into generated JAR". while this may give some license issues (depending upon the JARs you're merging in), in my case it worked like a charm, giving me a single (smaller, since there were a lot of duplicates among the various jar files I'd been including) jar that actually worked.

Using ant to create a distributable zip file with JAR and libraries and doc

I have a library that is typically distributed by making a zip file of the JAR and its dependencies and its javadoc by hand. I would like to automate this task in ant.
One quirk for the intended use case for this distribution is that when it is unpacked, the JAR my team has created and any library JARs should all be in the same path. We cannot have myproject.zip/the.jar and myproject.zip/lib/a_library.jar both should be in the root path of the zip.
I have had much success using the following task:
<target name="myproject.distributable" depends="artifact.mycompany_myproject, myproject.javadoc"
description="Build the distributable JAR for myproject">
<zip destfile="${basedir}/dist/myproject.zip">
<fileset file="${temp.jar.path.mycompany_myproject.jar}"/>
<zipfileset dir="mycompany_myproject/lib" prefix="lib">
<patternset id="myproject.dist.libs">
<include name ="**/*.jar"/>
</patternset>
</zipfileset>
<zipfileset dir="docs/myproject" prefix="docs"/>
</zip>
</target>
The only thing it doesn't do is 'flatten' or move the library JARs to the root path of the zip.
I have tried using <zipfileset prefix="/"> for the libs but that did not work as expected.
The prefix attribute of the zipfileset is used to describe where the files should appear in the created zip file. Since you want the jar files to appear at the root of the zip file you don't need to specify this, and can leave it out (I'm not sure what the effect of setting it to "/" will be, I think it'll be safer to omit it).
You problem seems to be that your libs are stored in subdirectories under your lib dir, but you want them to be directly in the root of the zip file. The 'zip' task, unlike the copy task, doesn't accept a mapper directly to change how files should appear in the zip, but if you're using ant 1.7 or later it will accept a resource collection. You can use a mappedresources element with a fileset and a flattenmapper to get the effect you're after:
<target name="myproject.distributable" depends="artifact.mycompany_myproject, myproject.javadoc" description="Build the distributable JAR for myproject">
<zip destfile="${basedir}/dist/myproject.zip">
<fileset file="${temp.jar.path.mycompany_myproject.jar}"/>
<mappedresources>
<fileset dir="mycompany_myproject/lib" includes="**/*.jar" />
<flattenmapper />
</mappedresources>
<zipfileset dir="docs/myproject" prefix="docs"/>
</zip>
</target>
This means you don't have to use copy first to put the jars into a staging area.
According to this post the zipgroupfileset should do the trick; have not tried it myself though...

How can I include data text files in a jar using Ant?

In my src folder there is another folder called data which contains files data1.txt and data2.txt. The application loads a graph from these files in the initialization, so I want to include these files in my final jar. I use Ant to produce the jar file.
Example from http://ant.apache.org/manual/Tasks/jar.html :
<jar destfile="${dist}/lib/app.jar">
<fileset dir="${build}/classes"/>
<fileset dir="${src}/resources"/>
</jar>
So basically you would want to include the data-files in the same way as "resources" are included above.
From the documentation of the <jar> task:
It is possible to refine the set of files that are being jarred. This can be done with the includes, includesfile, excludes, excludesfile and defaultexcludes attributes.
Copy the files to your classes directory, where they will be included into the jar.
enter code here
<target name="copyHibernateXml">
<copy todir="classes">
<fileset dir="${basedir}/${sourceDir}" includes="*.xml,*.csv"/>
</copy>
</target>

Categories