I've been working on a command line executable Java program. It's in the testing phase, and packaging it up has proved a bit of an issue. The crux of this problem revolves around the MANY dependencies my application has. My lib folder (containing jars) is close on 500mb.
At the moment I have been using the Eclipse Runnable Jar Export wizard. Works flawlessly, except it has to be done from Eclipse. It generates a Jar about 500mb in size (don't ask... suffice to say there need to be a lot of COBOL programs being packaged inside this program). This process takes <30s.
Ideally I would like this to be an Ant task of some kind, runnable via Jenkins and published to a repository. That way a user can just grab a Jar and run it.
Fast build time (5 mins)
<target name="hello" depends="compile">
<property name="classes.dir" value="onejar" />
<property name="build.dir" value="bin" />
<one-jar destfile="hello.jar">
<manifest>
<attribute name="One-Jar-Main-Class" value="mainclass" />
<attribute name="Class-Path" value="." />
<attribute name="One-Jar-Show-Expand" value="true" />
</manifest>
<main>
<fileset dir="${build.dir}"/>
</main>
<lib>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</lib>
</one-jar>
</target>
Slow build time (20min +)
<target name="compile" depends="resolve">
<javac srcdir="src" destdir="bin" debug="true" deprecation="on">
<classpath>
<path refid="ivy.path" />
</classpath>
</javac>
</target>
<target name="jar" depends="compile" description="Create one big jarfile.">
<jar jarfile="${dist}/deps.jar">
<zipgroupfileset dir="lib">
<include name="**/*.jar" />
</zipgroupfileset>
</jar>
<sleep seconds="1" />
<jar jarfile="${dist}/myjar.jar" basedir="bin">
<zipfileset src="${dist}/deps.jar" excludes="META-INF/*.SF" />
<manifest>
<attribute name="Main-Class" value="mymainclassishere" />
</manifest>
</jar>
</target>
So yeah, does anyone have any suggestions? I am interested to hear peoples thoughts.
Edit: Specifically.... WHY the Eclipse Runnable Jar Export Wizard can export my Jar in less then 30s, yet my build times are > 30 minutes.
I know responding to your question can be frowned upon, but I did manage to solve this problem yesterday. Of all the options I tried I found the fastest solution was to replicate the Eclipse Runnable Jar Export Wizard. It requires the jar-in-jar-loader.zip
which can be acquired using the Runnable Jar Export Wizard... or you can find it via Google/Eclipse install.
I found this solution was fast to build (30s) and much faster to run (5s bootup cost). It also left the jar structure very neat with no exploded jars.
<target name="compile" depends="resolve">
<mkdir dir="bin"/>
<!-- Copy all non java resources since jar javac will exclude them by default. Needed for xmls, properties etc --->
<copy todir="bin">
<fileset dir="src" excludes="**/*.java" />
</copy>
<javac srcdir="src" destdir="bin" debug="true" deprecation="on">
<classpath>
<path refid="ivy.path" />
</classpath>
</javac>
</target>
<!-- Creates the runnable jar. Copies the dependencies as jar files, into the top level of a new jar.
This means nothing without a custom classloader and manifest with a jar listing -->
<target name="jar" depends="compile" description="Create one big jarfile.">
<path id="dependencies.path">
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</path>
<pathconvert property="manifest.classpath" pathsep=" ">
<path refid="dependencies.path" />
<mapper>
<chainedmapper>
<flattenmapper />
<globmapper from="*.jar" to="*.jar" />
</chainedmapper>
</mapper>
</pathconvert>
<mkdir dir="${dist}"/>
<jar destfile="${dist}/jar/Runnable.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader" />
<attribute name="Rsrc-Main-Class" value="mymainclass" />
<attribute name="Class-Path" value="." />
<attribute name="Rsrc-Class-Path" value="./ ${manifest.classpath}" />
</manifest>
<fileset dir="bin" />
<zipfileset src="jar-in-jar-loader.zip" />
<zipfileset dir="lib" includes="**/*.jar*" />
</jar>
</target>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With