Creating a merged executable Jar from many jar files(used in classpath) - java

I have a desktop application , which is packaged as a self-executable jar file, but my code needs to access many jar files , which i have set in the class-path in the manifest file. But the problem that I am encountering is that all the jars to be used in the class-path I have to keep them in the same directory as my executable jar file.What I need is to somehow merge all the various jars so that I can specify this single jar in my class-path in .mf file.
The .mf file is-->
Class-Path: poi-3.7-20101029.jar poi-examples-3.7-20101029.jar poi-ooxml-3.7-20101029.jar poi-ooxml-schemas-3.7-20101029.jar poi-scratchpad-3.7-20101029.jar jfreechart-1.0.14.jar jcommon-1.0.17.jar jfreechart-1.0.14-experimental.jar jfreechart-1.0.14-swt.jar junit.jar servlet.jar swtgraphics2d.jar gnujaxp.jar iText-2.1.5.jar
Main-Class: gui/GUILauncher
Kindly suggest me a solution, so that I can achieve my objective...

You could specify a path to each at file in the manifest
Class-Path: lib/poi-3.7-20101029 ...
And store the library jars here.
While I like the idea of combining all he classes into a single Jar, you need to be careful of resources that might share the same path. We have this issue in our app, all our Jars contain a Version file we use as a marker and read via Class.getResources(...)

You need not keep all these jars in executable jar directory. Instead you could specify relative path of dependent jars in Manifest.mf file.
e.g.
You have kept your executable jar under bin folder and dependent jars under lib folder.
app-root
+
+ \bin
+ + GuiLauncher.jar
+
+ \lib
+ junit.jar
+ servlet.jar
Manifest.mf Classpath will be
Class-Path: ..\lib\junit.jar ..\lib\servlet.jar

Related

How to load a whole directory using Class-Path: jar manifest header? [duplicate]

This question already has an answer here:
Does the Class-Path in the MANIFEST.MF can only include jar Files?
(1 answer)
Closed 7 years ago.
If in the manifest for a jar file that needs to load non executable jars, I have the Class-Path: specification and then a directory holding the jars as the class path instead of a jar file. Will the manifest then load the whole directory or will it just fail?
Update:
I tried to use Class-Path: foo/* however it failed to load the foo directory. Does the manifest classpath not support regex>
As long as your foo directory contains only .class files, you can safely set the Class-Path: header like this:
Class-Path: foo/
Since you have non executable jars in it, you should use a build tool like Maven to generate the Class-Path: entry for you. The non executable jars will be dependencies of your Maven project.
Reference:
JAR : MANIFEST.MF Class-Path referencing a directory

java.lang.NoClassDefFoundError - Generating Executable Jar

I have created my JAR on Windows 2000 having java version 1.5 which contains following directories/files:
manifest.txt
com
lib
lib contains all JARS which I want to make part of my JAR. com contains my class files and below is manfiest.txt file
Main-Class: com.as.qst.result.ResultTriggerSchedular
Class-Path: lib/axis.jar lib/c3p0-0.9.1.1.jar lib/commons-discovery-0.2.jar lib/commons-logging-1.0.4.jar lib/jaxrpc.jar lib/log4j-1.2.16.jar lib/medplus-hub-8.2-wsclients.jar lib/medplus-hub-13.1-jaxws-clients.jar lib/quartz-2.2.1.jar lib/quartz-jobs-2.2.1.jar lib/saaj.jar lib/slf4j-api-1.6.6.jar lib/slf4j-log4j12-1.6.6.jar lib/ wsdl4j-1.5.1.jar lib/xercesImpl.jar com\as\qst\result
I used following command to generate my JAR
jar cvfm test.jar manifest.txt com lib
It has successfully created a JAR file but when I try to run it with
java -jar test.jar
it does not execute and throws above exception. I used the same process for Windows 7 which has version 1.7 and it did work out even without class files path in manifest.txt com\as\qst\result. Is something more to do with class-path besides defining in manifest? and why is it working in Windows 7?
You do not need the class file path in your class path entry. So instead of adding com\as\qst\result to your class-path.
More over you must not package other jar files in your runnable jar.
Other required jars must be provided in the same folder as your jar file (may be in separate folder) and Add current directory "." (without quotes) to your class-path.
Hope this helps.
EDIT
Just found this Stackoverflow Link. This might give you more insight. Please read through it.

Where will the jar be loaded up from in this situation?

This site:
http://pic.dhe.ibm.com/infocenter/wmqv7/v7r1/index.jsp?topic=%2Fcom.ibm.mq.doc%2Fjm10330_.htm
says that
The manifest of the JAR file com.ibm.mqjms.jar contains references to
most of the other JAR files required by WebSphere MQ classes for JMS
applications, and so you do not need to add these JAR files to your
class path.
So in the MANIFEST of my jar I have the following manifest classpath:
Class-Path: /opt/mqm/java/lib/com.ibm.mqjms.jar
In the com.ibm.mqjms.jar, it contains the following MANIFEST classpath
Class-Path: jms.jar com.ibm.mq.jmqi.jar dhbcore.jar rmm.jar jndi.jar l
dap.jar fscontext.jar providerutil.jar CL3Export.jar CL3Nonexport.jar
My question is: when the com.ibm.mqjms.jar starts looking for the jms.jar (or other jar),
where will it be looking ? (or at least looking first?
In the jar file itself,or on the /opt/mqm/java/lib
It will be looking in the directory where com.ibm.mqjms.jar is present. This makes it easier for the user as one need not know the dependencies of com.ibm.mqjms.jar ... Just ensure that you don't move individual jars out of that directory.
Some more details here: http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html

error: package org.apache.commons.net.ntp does not exist

I downloaded commons-net-3.0.1-bin.zip file and extracted it to java lib folder. I have set the path to java bin folder and classpath=.;C:\Program Files\Java\jdk1.7.0_01\lib\commons-net-3.0.1.
commons-net-3.0.1 folder has commons-net-3.0.1 jar , commons-net-3.0.1-sources.jar and commons-net-examples-3.0.1.jar files.
In my program I imported org.apache.commons.net.ntp.* package, and it gave the "package doesn't exist" error.
Just adding the directory containing the JAR files isn't enough. Add the specific JAR file to the classpath instead, e.g.
classpath=.;C:\Program Files\Java\jdk1.7.0_01\lib\commons-net-3.0.1\commons-net-3.0.1.jar
Alternatively, use a classpath wildcard to add all JARs in a given directory. See How to use a wildcard in the classpath to add multiple jars?
check that package org.apache.commons.net.ntp.* presents in jar file
make sure that the jar file is in the class path of an application How to set Classpath

Should putting a jar file in lib/ext work instead of using a CLASSPATH on Windows XP?

I have two jar files, A.jar and B.jar. A contains my main function and it relies on classes defined in B.
I put A and B in the same folder, which is in the Windows PATH, and try and run my main in A...
java -jar A.jar -dosomething
This gives me a java.lang.NoClassDefFound error on a method of B that I call in the code underneath -dosomething. Interestingly it has found A.jar and called the main method, but it can't find B.jar, even though it is in the same folder as A.jar.
So I read around (again) about CLASSPATHs and the JAVA_HOME variable and I made sure that my JAVA_HOME is pointing to the right place. This document describes how I should be able to put my extension jar file(s), in my case B, into the /lib/ext folder, so I tred that, but I get the same java.lang.NoClassDefFound error.
I am using Java jdk1.5.0_10, so for good measure I also placed B.jar in the jre/lib/ext folder underneath there.
So now I have it in three places, the local folder on the PATH, JAVA_HOME/lib/ext and JAVA_HOME/jre/lib/ext and I still get the same error.
Should using lib/ext work? Where on earth have I got to put my B.jar file for this to work properly?
JAVA_HOME is not a environment variable used by Java. It's used by other tools such as Ant, but not by Java.
The PATH environment variable is not used by Java either. It's used to find executables in windows, but Java doesn't use it to find jars.
Placing two jars in the same directory doesn't make them automatically in the same classpath. If A.jar is an executable jar (as it seems to be), and it depends on an external B.jar, then its Class-Path entry of its manifest must reference B.jar. Read http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html
You need to add a manifest file to your A.jar file like this.
The contents of the manifest file should look like this, where the Main-Class points to your package name and the class name of your main class in A.
Save this in a file named something like Manifest.mf
Manifest-Version: 1.0
Main-Class: com.your.package.name.A
Class-Path: A.jar B.jar
You can manually add this file to your jar by changing your .jar file to a .zip then opening it and modifying the contents of the existing manifest file if there is one or copying the Manifest.mf file into your jar/zip file and changing it back to a .jar file.
You need to have a Manifest file to be able to call classes from another jar. Check this link
I would consider using a build system like Ant or Maven, my personal preference is for Maven. Most have plugins to take care of the complex classpath / dependency issue - in Maven, that's the Shade plugin.
I would do Hello World with a Maven example. Most modern IDEs (IDEA, Eclipse, NetBeans) can generate projects from a pom.xml.
http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
To make executable-jar file you need to add a manifest file which contains the Main-class name and other dependent class paths.
Manifest.txt
Main-class: A
Class-Path: B.jar
Add this manifest file into A.jar
cmd:/folderLocation>jar cvfm A.jar manifest.txt A.class
place both jars in one folder and run A.jar using cmd java -jar A.jar

Categories