tags:

views:

788

answers:

3

I have NetBeans 6.8 and I wrote one class which has two libraries (jar-files). Building it, I get a "dist" folder with my project.jar and a "lib" folder which contains the two lib jar files.

How could I get all this in one jar file? (I do not use Maven/Ant or something like this.)

+3  A: 

The basic problem is that the current version of Java does not support jars inside jars out of the box.

The recommended solution is to use the Class-Path line in the MANIFEST.MF file inside your jar to point to required libraries (relative paths are allowed) and then deploy all files together and invoking it with "java -jar your.jar"

If you really want to have a "jar-inside-jar" solution, we have used one-jar for several years, but gone away from it since our target JVM worked better with the solution described above.

http://one-jar.sourceforge.net/

I used it with the fatjar plugin in Eclipse. I do not have any experiences with building it into Netbeans, but it is simple to build into an ant script which I believe is what NEtbeans use anyway.

Thorbjørn Ravn Andersen
+3  A: 

You can create an extra build target in the build.xml file. And use zipfileset and zipgroupfileset to create one big jar e.g.

<target name="YourBigJar" depends="-post-jar">
  <jar destfile="BigJar.jar">
    <zipfileset src="dist/Project1.jar"/>
    <zipfileset src="../OtherProject/dist/project2.jar"/>
    <zipgroupfileset dir="../libs/."/>
  </jar>
</target>
Waverick
+1 using ant is probably the best way
stacker
Notice that this will break signed jars etc.
Thorbjørn Ravn Andersen
+1  A: 

I agree with Waverick. The simplest way to do this with NetBeans is to add a custom target to your build.xml. (By the way, by virtue of using NetBeans, you are using Ant, since NetBeans uses Ant to build your jar file.)

Waverick's Ant target seems to be designed to merge the compiled code from a different NetBeans project into the current project's jar file. My targets below do exactly what you are looking for.

<target name="-unjar-and-copy-lib-jars">
    <unjar dest="${build.classes.dir}">
        <fileset dir="lib">
            <include name="**/*.jar"/>
        </fileset>
        <patternset>
            <exclude name="META-INF/**"/>
            <exclude name="/*"/>
        </patternset>
    </unjar>
</target>

<target depends="init,compile,-pre-pre-jar,-pre-jar,-unjar-and-copy-lib-jars" name="fat-jar">
    <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
    <jar destfile="${dist.jar}">
        <fileset dir="${build.classes.dir}"/>
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
    <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>

<target depends="clean,fat-jar" name="clean-and-fat-jar"/>

For more information on how to use this, see the blog post I wrote when I ran into the same issue.

Joshua Born