views:

79

answers:

4

I'm going to deploy a Java application with a custom launcher, and I need to have all the classes needed for my app in a single jar file so I don't have to deploy the entire Java SE libraries with it.

I was thinking of using some pre-existent ant tasks to create a target that recursively searches all my compiled classes files for its dependencies. After all the dependencies have been determined it would extract the needed class files from their JAR's, copy it along with my classes to an output directory and make a single jar from it.

If there's no such thing avaliable out of box, I can create one myself, but I need to know how references to other classes are stored in .class files. It could be much easier if there's some kind of java library like .NET's Mono.Cecil/System.Reflection that exposes an high level API for inspecting/manipulating Java.

Since I'm new to Java, I'm having some trouble in finding what is needed to acomplish those things. Can someone give me some direction?

+1  A: 

You won't have to deply Java SE classes, as they already are in the customer JRE.

If your dependencies are expressed ion a common way (through Maven or Ivy) i guess it's quite easy to find an equivalent of maven uberjar task ... which will do what you want to do, but in a more simple way (as it simply repacks all jars in one big jar).

Riduidel
+2  A: 

After all the dependencies have been determined it would extract the needed class files from their JAR's, copy it along with my classes to an output directory and make a single jar from it.

As an easy solution, if you use Eclipse IDE you use the following solution:

Under the Java project properties (right click):

 Export... => Export as Runnable JAR

The exported JAR will have all its dependencies packed into it.

alt text

Bakkal
Hmm, deja vu ;)
BalusC
Software is all about reuse :D
Bakkal
+2  A: 

Unfortunately, you cannot ship only part of Java SE - that will breach the license agreement. If you use Java SE, then all of Java SE must be available.

The simplest way to achieve this is to use an Ahead Of Time compiler. These take care of packaging only the classes you need, and adhere to the JDK license agreement by making the "unused" parts of the JDK available via optional download.

For example, Excelsior JET is a good AOT compiler and will package just the classes you need. It's not free for commercial use, although open source projects can apply for a free license grant.

Alternatively, you may simply assume that the user has the JRE already since it's installed on over 90% of desktops, and in cases where the JRE is not available, have your installer download one for the user. AdvancedInstaller has a free edition that will accomplish this.

mdma
Do you think there will be license problems if I deploy an open source JVM with only the required java classes from GNU classpath?
Thiado de Arruda
Sorry I don't know the answer to that. I've not looked into the open source java license.
mdma
+2  A: 

Here is one suggestion I found on the web:

<jar destfile="${build-abc}/abc.jar" duplicate="fail" index="true">
  <zipfileset src="${compile-lib}/demo.jar" includes="**/*.class"/>
</jar>

This should add the dependencies to the jar (as shown with demo.jar). You still have to adapt the manifest file so that the added jars appear on the classpath.

This doesn't solve the 'Java SE' classes problem - you'll have to bundle a jre in the installer package or depend on an existing one on the target system.

Andreas_D