I am using zipgroupfileset to bundle all jars from lib folder to include in my executable application jar file.
<zipgroupfileset dir="${lib.dir}" />
Jars must be getting included in some default order. I want to alter this default order.
A note on why I want this: my Java desktop application uses many third party jars which are included in class path. When I run my code through Eclipse it works fine. But when I build the jar file using ANT it doesn't work as expected. I am sure it is related to jar sequence in classpath as if I change jar order in Eclipse it fails there as well.
Note: I am using Eclipse Kepler, Java 7, Ant 1.8.
Finally I got the solution. I build the Jar after altering my ANT file. Now my ANT build includes 3rd party APIs explicitly in classpath and that was the key to the solution.
<property name="lib.dir" value="lib" />
<manifestclasspath property="jar.classpath" jarfile="${lib.dir}/*.jar">
<classpath refid="project.class.path"/>
</manifestclasspath>
<jar destfile="${jar.dir}/${jar.name}">
<fileset dir="${class.root}" includes="**/*.*" />
<manifest>
<attribute name="Main-Class" value="${Main-Class}" />
<attribute name="Class-Path" value="${jar.classpath}" />
</manifest>
</jar>
Previously I had class-path entry in ANT as follows:
<attribute name="Class-Path" value="." />
I need to include some third party jar file to my project jar. I mentioned it in my build.xml and include this to MANIFEST.MF. Now i get thirdparty1.jar thirdparty2.jar file into inside the project jar. But still i can't able to use the jars. Is it need any addition configuration
Here is my build.xml
<manifest>
<attribute name="Class-Path" value="thirdparty1.jar thirdparty2.jar thirdparty3.jar"/>
If i copy the two jar separately it works well. But i don't understand what is the need for copy these separate. How it solve with out copying jar separately.
If the dependency jar is packaged inside the project jar, you need a solution to load it from there. The standard class-path handling in Java won't access jar files located inside other jar files.
See this answer: Classpath including JAR within a JAR. Specifically the One Jar solution: http://one-jar.sourceforge.net/.
It's also possible to use zipgroupfileset for that.given is the sample ant task for that.
<!-- Build JAR file -->
<target name="jar" depends="init-build-dir,compile-main">
<!--creating a temp jar contains all jar -->
<jar jarfile="${project.build.lib.dir}/external-libs.jar">
<zipgroupfileset dir="${project.lib.redist.dir}">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
<sleep seconds="1" />
<!-- creating main jar with temp jar-->
<jar jarfile="${project.build.lib.dir}/${ant.project.name}.jar" manifest="MANIFEST.MF">
<fileset dir="${project.build.main.classes.dir}" includes="**/*.*" />
<zipfileset src="${project.build.lib.dir}/external-libs.jar">
<exclude name="*" />
</zipfileset>
</jar>
<!--removing temp jar -->
<delete>
<fileset dir="${project.build.lib.dir}">
<include name="external-libs.jar" />
</fileset>
</delete>
</target>
I usually code with IDEs like Intellij Idea or Eclipse, but due to several reasons, I no longer have access to an IDE, and I'd like to be able to code in Java on a remote Linux machine through a ssh terminal.
Making simple progams with only a few classes is easy, but some of my projects have several libraries and several separate .java files. I also need to export to a .jar file.
For example, I have the following file organisation:
project/
src/
a.java
b.java
c.java
libs/
lib1.jar
lib2.jar
out/
export_here.jar
someconfig.conf
The java app consists of the a, b, and c .java files, uses libraries lib1 and lib2, and the file someconfig.conf needs to be inside the export jar.
I want to know how to easily compile and build a project such as this.
In other words, I just want to know how to export my project into a runnable jar the right way.
I expect this can be done with a few commands. If so, I plan to make a shell script to automate everything.
Thanks in advance!
As suggested by other users you need to use a build management tool to do this like Ant, Maven etc. I have used Ant quiet frequently to do these kind of automated tasks. In order to install and Use Ant you can refer How To Install Apache Ant
After that the main task is to write your automation script and that is called a build xml in ant world. Here is a sample build.xml file you can refer to start with:
<project>
<target name="clean">
<delete dir="build"/>
</target>
<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/HelloWorld.jar" basedir="build/classes">
<manifest>
<attribute name="Main-Class" value="oata.HelloWorld"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>
</project>
And for more information on the above sample You can visit this
In General you can read more at How to create build.xml
After creating your build.xml you can run ant by ant <path to build.xml> or ant in case your build.xml lies in current directory
Hope this helps you in right direction
When I run "clean and build" the .jar file that is being created only runs if the lib folder is at the same folder of the .jar file.
So if I move the jar file to the desktop and leave the lib folder in the dist folder, the jar file will give me an exception.
How can I deal with this problem?
I solved this by creating just one jar file with all libraries inside, adding the following to my build.xml file in NetBeans:
<target name="-post-jar">
<jar jarfile="dist/Combined-dist.jar">
<zipfileset src="${dist.jar}" excludes="META-INF/*" />
<zipfileset src="lib/commons-io-1.4.jar" excludes="META-INF/*" />
<zipfileset src="lib/ninja-utils-3.2.jar" excludes="META-INF/*" />
<zipfileset src="lib/unicorn-1.0.jar" excludes="META-INF/*" />
<manifest>
<attribute name="Main-Class" value="com.example.mypackage.Main"/>
</manifest>
</jar>
</target>
This creates a jar file (Combined-dist.jar) which is the combination of the dist jar and the specified library jars (in this case, commons-io-1.4.jar,ninja-utils-3.2.jar and unicorn-1.0.jar). You have to be sure to specify your Main Class package for the new jar file or it won't run when you try to open it.
If you copy your jars into the source code directory, they will be in your final jar. Nevetheless, I am not sure if this will work 100% of the time.
There is a great post at java-forum that states the following:
Except for a select few circumstances, what works best for me is to
simply merge the files manually. A .jar is basically a .zip with
organized contents, and you can open them in almost any .zip capable
archive program (I just use gnome's standard archiver, File Roller,
and it works great). Backup your jar file and open it in the archiver
of your choice, and do the same for each library jar in the library
directory. Drag and drop the working folders (IE, everything EXCEPT
the META-INF Directory) from each library into your jar's root path
(alongside your META-INF and your app's root package). Now drag the
META-INF/MANIFEST.MF file from your jar to your Desktop or any other
folder. Open it, and erase the Class-Path and X-COMMENT lines. Don't
forget to leave a blank newline at the end of the file! Save the new
manifest file and drag it back to your jar's META-INF directory,
overwriting the old one. Test the jar.
That's really easy to package every dependent library (*.jar) into one single myProject.jar.
Just follow these steps and you will finally pack every dependent library into single jar. If you are using NetBeans then you can follow exactly or else you need to find your build.xml file in project files.
Follow these steps to edit build.xml
1) Click on Files tab on the left side of the project panel in NetBeans.
2) Double click on the build.xml file and add these lines in it just before </project> line
<target name="package-for-store" depends="jar">
<property name="store.jar.name" value="myProject"/>
<property name="store.dir" value="store"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${store.dir}"/>
<mkdir dir="${store.dir}"/>
<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<zip destfile="${store.jar}">
<zipfileset src="${store.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete file="${store.dir}/temp_final.jar"/>
</target>
3) Change value in second line of the code as per your project name which is
<property name="store.jar.name" value="myProject"/> //<---Just value not name
4) Save it and right click on build.xml and choose Run Target and then Other Targets and finally click on Package-for-store
5) And here you done. Now you can go and check just like dist folder there will be a store folder which will be containing your final complete jar including all of your dependent libraries. Now whenever you want to change / add more libraries or so, just follow step 4.
Picture for step 4
You could use Apache Ant since version 1.7 for build the JAR with the required libraries in only one file. You could have a configuration file as follows:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="buildJar">
<target name="buildJar">
<!-- Name of jar -->
<jar destfile="C:/MyJar.jar" filesetmanifest="mergewithoutmain">
<manifest>
<!-- Your class with the main method -->
<attribute name="Main-Class" value="myPackage.MyClass"/>
<!-- Path in the jar -->
<attribute name="Class-Path" value="."/>
</manifest>
<!-- Dir of compiled class -->
<fileset dir="C:/NetBeansProjects/MyProject/bin"/>
<!-- Include required jars -->
<zipfileset excludes="META-INF/*.SF"
src="C:/NetBeansProjects/MyProject/lib/library1.jar"/>
<zipfileset excludes="META-INF/*.SF"
src="C:/NetBeansProjects/MyProject/lib/library2.jar"/>
</jar>
</target>
</project>
In Netbeans, place the XML file in your project and run it with the context menu.
See more in Apache Ant User Manual.
If you are going to distribute your app to another pc
You just zip .jar along with lib folder.
If want to run your app from any place in your pc
Take in cosideration Maven way of doing this - create local repository eg. C:\libs where your libraries would exist and .jar could accesses them later from any place in your pc.
Or you could just use Maven. There is a discussion on distributing application with all dependencies (libraries): Java: How do I build standalone distributions of Maven-based projects?.
Copy that jar file to:
C:\Program Files\Java\jdk\jre\lib\ext
and
C:\Program Files\Java\jre\lib\ext
You should be able to use it in Netbeans and in your manual imports, just like standard imports.
I have found maybe the easiest solution for this problem here. You just need to copy the next code snippet at the end of the build.xml file in your project folder.
<target name="-post-jar">
<!-- Change the value to the name of the final jar without .jar -->
<property name="store.jar.name" value="MyJarName"/>
<!-- don't edit below this line -->
<property name="store.dir" value="dist"/>
<property name="temp.dir" value="temp"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${temp.dir}"/>
<mkdir dir="${temp.dir}"/>
<jar destfile="${temp.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<delete dir="${store.dir}"/>
<zip destfile="${store.jar}">
<zipfileset src="${temp.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete dir="${temp.dir}"/>
</target>
Go to the build.xml in the root of your project and add the code right before </project> tag at the end.
Now change the value of the first propertiy field as commented and save the changes.
From now on, each time you Clean & Build your project, the full jar with dependencies will be generated in the project dist folder
This is what worked for me:
I built in excel export functionality into my project. The 2 external .jars I used for this purpose was jxl.jar end sx.jar
Unpack these 2 jars into a folder(java classes) using 7-Zip without any META files. Unpack your project jar into the same folder including the META file.
Re-Pack the whole java classes folder using JARMaker to recreate your Project .jar in its original distribution folder ... and there you go ... full excel functionality.
user1016588's solution works for me. There's one typo: this line should be
zipfileset src="dist/lib/commons-io-1.4.jar" excludes="META-INF/*"
Try this - in the Netbeans IDE:
Go to Tools --> Libraries
In the dialog box, on the bottom left click "New Library", give a name
On the right side, click on "Add JAR/Folder"
Click OK on the bottom right
Re-start the IDE and check.
Follow these:-
1. Right click on project opened in netbeans editor
2. select properties
3. choose libraries
4. add jar
5. click ok
You can also use this (when the libraries are not in "dist/lib"), tested with NetBeans and ant-contrib:
<target name="-post-jar">
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<!-- Path to ant-contrib -->
<pathelement location="../../Libs/ant-contrib-1.0b3.jar"/>
</classpath>
</taskdef>
<!-- Change the value to the name of the final jar without .jar -->
<property name="store.jar.name" value="${application.title}"/>
<!-- don't edit below this line -->
<property name="store.dir" value="dist"/>
<property name="temp.dir" value="temp"/>
<property name="temp.libs.dir" value="temp/libs"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<fileset id="store.jars.absolute" dir="${store.dir}" includes="*.jar"/>
<pathconvert property="store.jars.relative" refid="store.jars.absolute" dirsep="/">
<map from="${basedir}/" to=""/>
</pathconvert>
<for list="${store.jars.relative}" param="item">
<sequential>
<echo message="Adding #{item} into single JAR at ${store.jar}"/>
</sequential>
</for>
<delete dir="${temp.dir}"/>
<mkdir dir="${temp.dir}"/>
<for list="${javac.classpath}" param="item" delimiter=":">
<sequential>
<echo message="Adding #{item} into single JAR at ${store.jar}"/>
<copy file="#{item}" todir="${temp.libs.dir}" overwrite="true" />
</sequential>
</for>
<jar destfile="${temp.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="${store.dir}" includes="*.jar"/>
<zipgroupfileset dir="${temp.libs.dir}" includes="*.*"/>
<manifest>
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</jar>
<delete dir="${store.dir}"/>
<zip destfile="${store.jar}">
<zipfileset src="${temp.dir}/temp_final.jar" excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete dir="${temp.dir}"/>
</target>
what is the best practice to create a .jar file from a java project??
Some points to consider:
Create proper MANIFEST.MF, which should contain:
Build date;
Author;
Implementation-version;
Use a script/program - like an Ant task - which takes care of properly creating a manifest file.
Here's a simple ant file which builds a java project, adapted from the Ant tutorial:
<project>
<target name="clean">
<delete dir="build"/>
</target>
<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/HelloWorld.jar" basedir="build/classes">
<manifest>
<attribute name="Implementation-Version" value="1.0"/>
</manifest>
</jar>
</target>
<target name="run">
<java jar="build/jar/HelloWorld.jar" fork="true"/>
</target>
</project>
Read up on the basics of Sun's JAR format at this tutorial. In my opinion you should learn the basics -- namely MANIFESTs, the SDK tools -- before jumping into third party tools such as the following.
The Jar command line tool distributed with the Sun JDK:
jar -cf myjar.jar base_src_folder
Where base_src_folder is the parent directory holding your source code.
Alternatively you could use a build tool such as Apache Ant. It has features such as the JAR task to do this for you.
Apache Maven, for projects which are dependent on other projects.
Admittedly, Maven may be overkill for learning projects, but it is invaluable for larger, distributed ones.
Eclipse IDE is the best way for new comers. Just select the project right click export File, select jar anf filename.
Apache Ant
Ant is not quite easy to begin with. Instead, I would suggest using an IDE, for instance NetBeans, which creates an Ant script under the hood. All you have to do is to hit "build", and you get a .jar file as result.