Java Jar Ant include folder - java

My Question is: How am i able to put files in a subdirectory into my jar via ant? Right now my Code is:
<jar destfile="${dist.dir}\wo42.jar" basedir="bin">
<manifest>
<attribute name="Main-Class" value="org.alternativedev.wo42.App" />
<attribute name="Class-Path" value="lib" />
</manifest>
<zipgroupfileset dir="lib/." excludes="natives/*" />
<fileset dir="data/." includes="." />
It creates a structure like
ROOT-Jar
-org
--bla
-filefromdata1
-filefromdata2
But it should be
ROOT-Jar
-org
--bla
-data
--filefromdata1
--filefromdata2
Do You know what I mean?
Greetings, BigTeddy

Change the last line to
<fileset dir="." includes="data/**" />
No need to copy files around.
An alternative way (which is useful if you want to have the directory in the archive to have a different name) would be
<zipfileset dir="data" includes="." prefix="folder-name-in-jar"/>

First, you create the file structure you need and copy to it all the files required. Then you run jar command on the resulting root directory.
In order to copy files you can use the ANT copy task
For example:
<copy todir="../dest/dir">
<fileset dir="." includes="data/**/*.java">
</fileset>
More on how to pack jar (basics) here

Related

Apache Ant: adding and using a .txt file

I'm using Apache Ant to compile, jar and run a java project for school. I've run into a problem that I don't know how to include a single .txt file into my .jar, and then reference it as well in my java code.
Here is my compile and jar command in my build.xml.
<target name="compile">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes"/>
</target>
<target name="jar">
<mkdir dir="build/jar"/>
<jar destfile="build/jar/BinaryTree.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="cs3345.MainLauncher"/>
</manifest>
</jar>
</target>
What command do I use to include a .txt file into my jar. I've seen a couple Stack Overflow questions about it already, notably
adding non-code resources to jar file using Ant
How can I include data text files in a jar using Ant?
But none of them really explained how to include a file. They just had commands that didn't really make sense to me. I've tried,
<jar destfile="build/jar/BinaryTree.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="cs3345.MainLauncher"/>
</manifest>
<fileset dir="src/resources" />
</jar>
But that didn't seem to help because I just don't understand Ant, I couldn't find documentation for it that actually explained why you do different things in ant.
My .txt file is in, src/resources.
The <jar> task tasks multiple filesets:
<jar destfile="build/jar/BinaryTree.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="cs3345.MainLauncher"/>
</manifest>
<fileset dir="src/resources" />
</jar>
The <manifest> task is a sub entity. It's very much like the <manifest> task. In your jar is a file called META-INF/MANIFEST.MF and this is adding another attribute to that jar. This particular attribute tells the Jar what is the main class which should launch when the jar is exeuted.
The <fileset dir="src/resources"/> is adding all the files that are found in theresources` directory. What if you only want to add a particular file? You can use selectors. For example:
<jar destfile="build/jar/BinaryTree.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="cs3345.MainLauncher"/>
</manifest>
<fileset dir="src/resources">
<include name="foo.txt"/>
</fileset>
</jar>
This time I'm not adding the entire resources directory tree. I'm just adding a single file called foo.txt into my jar file.
Use <copy>:
<target name="copy" depends="blablabla" description="Copies additional files">
<echo>Start Copying Files</echo>
<copy file="./src/resources/a.txt" overwrite="true" todir="build/classes/"/>
<echo>End Copying Files</echo>
</target>
As a side note
If we want to include some files under src folder, we can write under target something like:
There is nothing in the documentation that says, "you can only add .class files". The fileset tag should work. Perhaps it's putting the file in a place you're not looking. Run in verbose mode to figure out what it's doing with your .txt file. To control the destination, you should use the zipfileset tag.
But that didn't seem to help. My .txt file is in, src/resources.
You're going to have to elaborate on that. How didn't it help? Is the problem that the file was nested under the zip or didn't go in there or you got an error?

Ant including both jar files and .class files in dest jar

I have defined a jar task using ant build.xml. I need to bundle all the dependencies into my jar. I don't understant why ant extracts the jars and includes both .jars and .class files into my jar. It unnecessarily increases the size of my jar file. Here is my jar task.
<jar destfile="build/main/ERS2SupportingUtilities.jar">
<fileset dir="target/classes">
<exclude name="*.sh"/>
</fileset>
<restrict>
<name name="**/*.class"/>
<archives>
<zips>
<fileset dir="./src/main/resources/lib" includes="**/*.jar"/>
</zips>
</archives>
</restrict>
<manifest>
<attribute name="Main-Class" value="com.cibc.ers2.invoker.JobTest"/>
<attribute name="Class-Path" value="./lib/log4j-1.2.16.jar
./lib/org.springframework.context-3.0.3RELEASE.jar
./lib/org.springframework.asm-3.0.3.RELEASE.jar
./lib/junit-4.7.jar
./lib/org.springframework.orm-3.0.3.RELEASE.jar
./lib/org.springframework.transaction-3.0.3.RELEASE.jar
./lib/org.springframework.aspects-3.0.3.RELEASE.jar
./lib/commons-pool-1.5.4.jar
./lib/org.springframework.core-3.0.3.RELEASE.jar
./lib/commons-logging-1.1.1.jar
./lib/HashUtility.jar
./lib/org.springframework.expression-3.0.3.RELEASE.jar
./lib/commons-lang-2.6.jar
./lib/org.springframework.instrument-3.0.3.RELEASE.jar
./lib/mockito-all-1.9.5.jar
./lib/com.springsource.org.aopalliance-1.0.0.jar
./lib/ojdbc14.jar
./lib/commons-io-2.4.jar
./lib/commons-collections-3.1.jar
./lib/org.springframework.jdbc-3.0.3.RELEASE.jar
./lib/spring-batch-infrastructure-2.1.9.RELEASE.jar
./lib/org.springframework.context.support-3.0.3.RELEASE.jar
./lib/commons-dbcp-1.4.jar
./lib/spring-batch-test-2.1.9.RELEASE.jar
./lib/org.springframework.beans-3.0.3.RELEASE.jar
./lib/org.springframework.oxm-3.0.3.RELEASE.jar
./lib/org.springframework.aop-3.0.3.RELEASE.jar
./lib/commons-beanutils.jar
./lib/org.springframework.binding-2.1.1.RELEASE.jar
./lib/spring-batch-core-2.1.9.RELEASE.jar
./lib/org.springframework.test-3.0.3.RELEASE.jar
./launch-context.xml
./log4j.xml"
/>
</manifest>
</jar>
I have also tried zipgroupfileset but that also is giving the same problem.
EDIT
Apologies for not giving enough info about what I am trying to achieve. I have got an application which I am compilint # target/classes. I need to package this application including my class files and dependecies into one jar.
<fileset dir="target/classes">
<exclude name="*.sh"/>
</fileset>
includes all files from target/classes which are not shell scripts.
<restrict>
<name name="**/*.class"/>
<archives>
<zips>
<fileset dir="./src/main/resources/lib" includes="**/*.jar"/>
</zips>
</archives>
</restrict>
It seems like you again include classes and jars here.
If you want only jar change all above to :
<zipfileset dir="./src/main/resources/lib" includes="*.jar"/>

Convert to jar while retaining classpath

I have a Java program that uses an external library, whose location is specified through the classpath. I would now like to make the Java program into a standalone jar file (so I can use my IDE for other things whilst the program is running).
How do I turn my existing .java file into an executable jar file?
I am able to make a jar file that includes the class file, manifest file, and the jar file of the library (that was specified in the classpath), but that still appears to be wrong because I get class not found errors.
Ant script for you. What you missed was the classpath generation as a string for the jar task.
<target name="all">
<property name="dir" value="yourProjectDir" />
<property name="name" value="$yourProjectName" />
<!-- clean -->
<delete dir="temp/" />
<mkdir dir="temp/bin/" />
<!-- prepare libs -->
<copy todir="temp/libs/"><fileset dir="${dir}/lbs/" /></copy>
<!-- prepare classpath -->
<pathconvert property="classpath" pathsep=" ">
<path><fileset dir="temp/libs/" /></path>
<chainedmapper><flattenmapper /><globmapper from="*" to="libs/*" /></chainedmapper>
</pathconvert>
<!-- compile -->
<javac destdir="temp/bin/" srcdir="${dir}/src/" target="1.6" source="1.6" includeAntRuntime="false">
<classpath>
<pathelement location="temp/bin/" />
<fileset dir="temp/libs/" />
</classpath>
</javac>
<!-- jar -->
<jar destfile="temp/${name}.jar" basedir="temp/bin/">
<manifest>
<attribute name="Main-Class" value="Main" />
<attribute name="Class-Path" value="${classpath}" />
</manifest>
</jar>
<!-- zip jar + libs -->
<zip destfile="${name}-${version}.zip">
<fileset dir="temp" includes="${name}.jar, libs/" />
</zip>
</target>
The following is the steps, how run stand alone App from command prompt.
1. Create a sample java file then save in particular location(like d:\sample\Hello.java.
2. open command prompt compile that java class, then create jar like Hello.jar file
3. then set classpath in Environment file(like D:\sample\Hello.jar ;
4. Now run your java class , it will work(d:sample>java Hello

How can include multiple jars in the classpath using ant?

I have a bunch of .java files in a "src" folder that depend on three jars in a "lib" folder. I have the following build.xml file:
<?xml version="1.0"?>
<project name="MyProj" basedir=".">
<property name="src" value="src"/>
<property name="build" value="build"/>
<property name="lib" value="lib"/>
<path id="master-classpath">
<fileset dir="${lib}">
<include name="activemq-all-5.1-SNAPSHOT.jar"/>
<include name="geronimo-jms_1.1_spec-1.1.1.jar"/>
<include name="activemq-core-5.3.0.jar"/>
</fileset>
</path>
<javac destdir="${build}">
<src path="${src}"/>
<classpath refid="master-classpath"/>
</javac>
</project>
This compiles fine, but when I try and run I get
"java.lang.NoClassDefFoundError:
javax/jms/Destination"
This program runs and compiles fine when I include the jars in the buildpath using Eclipse, though.
EDIT: So I copied the jars into the folder that has the compiled classes. The class with the main method is NDriver.class. When I try:
java -classpath
./geronimo-jms_1.1_spec-1.1.1.jar:./activemq-core-5.3.0.jar:./activemq-all-5.1-SNAPSHOT.jar
NDriver
This gives:
Exception in thread "main"
java.lang.NoClassDefFoundError:
NDriver
I'd appreciate any help.
You need to put the jars used at compile time on the classpath when running the application. Sadly, you didn't provide any detail on how you are actually running it so its hard to provide more guidance.
UPDATE: The directory containing the compiled classes needs to be added to the classpath too. If you launch java from the directory containing the compiled classes, then you can use . to designate the current directory. Add it to the classpath as shown below to tell java to look for classes there too (I've added . right after activemq-all-5.1-SNAPSHOT.jar):
java -classpath ./geronimo-jms_1.1_spec-1.1.1.jar:./activemq-core-5.3.0.jar:./activemq-all-5.1-SNAPSHOT.jar:. NDriver
One way (slightly different variables than yours)
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<manifestclasspath property="manifest.classpath" jarfile="${jarfile}">
<classpath refid="classpath"/>
</manifestclasspath>
<target name="jar" depends="compile" description="create the jar">
<jar destfile="${jarfile}" basedir="${build.dir}">
<manifest>
<attribute name="Manifest-Version" value="${manifest-version}"/>
<attribute name="Created-By" value="${ant.java.version}"/>
<attribute name="Main-Class" value="${main-class}"/>
<attribute name="Class-Path" value="${manifest.classpath}"/>
</manifest>
</jar>
</target>
Of course here I'm assuming that you are creating a jar and running it (including the classpath there). Another option would be to have a run target which use the <java> tag and explicitly use the classpath there.
Are the library jars included in the classpath when you run the program? Eclipse automatically add these, but you need to specifying them when you run the program from the command line.
From my experience it seems Eclipse will often include classes and jars in the classpath without explicitly using the classpath declaration. Indeed it can sometimes be quite hard to remove classes from Eclipse's build (they have to be deleted or clean'ed).

How to include the lib folder in the manifest classpath in Netbeans

A library that my java application uses needs looks for a file (log4j.xml) in the class path. I use netbeans to manage my project, but I can't find a way to include the lib/ folder.
Netbeans automatically creates a MANIFEST.MF file inside the application jar and also creates a folder called lib/ which includes all dependencies. This manifest specifies a Class-Path attribute that overrides any -cp argument provided on the command line. I can select an arbitrary folder in netbeans' library panel, but it creates a sub folder in the manifest's classpath. I'd like all dependencies and the log4j.xml file inside the lib/ folder.
Hopefully it's possible to do this in the IDE. I include a snippet of the auto-generated build-impl.xml file.
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries">
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</copylibs>
<echo>To run this application from the command line without Ant, try:</echo>
<property location="${dist.jar}" name="dist.jar.resolved"/>
<echo>java -jar "${dist.jar.resolved}"</echo>
</target>
Thanks.
Instead of editing the build-impl.xml file you should add this entry to the build.xml file. When you modify anything in your project pertaining to the building of that project, it will generate a new build-impl.xml file.
Here is an example of what I put in my build.xml file:
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete file="${dist.jar}"/>
<delete dir="${dist.dir}/lib"/>
<delete dir="${dist.dir}/resources"/>
</target>
Since I put this in the build.xml file, it will override the "-do-clean" section of the build-impl.xml file which contains:
<target depends="init" name="-do-clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
</target>
Furthermore, since it is in the build.xml it won't be modified by Netbeans.
I found a way to acheive this modifying the build-impl.xml.
I changed:
<attribute name="Class-Path" value="${jar.classpath}"/>
to:
<attribute name="Class-Path" value="${jar.classpath} /lib"/>
The problem is that netbeans will overwrite it since this file is automatically generated.
You can simply turn off project option Build/Packaging/Copy Dependent Library and manualy edit manifest.mf in root folder of your project (which is a template for manifest in jar file).
It seems that your problem is the "globmapper" that stores your log4j.xml file in /lib - you'd want it on the "/" or the jar.

Categories

Resources