我一直在研究命令行可执行Java程序。它处于测试阶段,将其打包已经证明是一个问题。这个问题的关键在于我的应用程序所具有的许多依赖项。我的lib文件夹(包含jar)接近500mb。
目前我一直在使用Eclipse Runnable Jar Export向导。完美无缺,除非必须从Eclipse完成。它生成一个大约500mb的Jar(不要问......足以说明需要在这个程序中打包很多COBOL程序)。此过程需要<30秒。
理想情况下,我希望这是一个某种类型的Ant任务,可以通过Jenkins运行并发布到存储库。这样一来,用户就可以抓住Jar并运行它。
快速构建时间(5分钟)
<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>
缓慢的构建时间(20分钟+)
<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>
所以是的,有没有人有任何建议?我有兴趣听到人们的想法。
编辑:具体......为什么Eclipse Runnable Jar导出向导可以在不到30秒内导出我的Jar,但我的构建时间是&gt; 30分钟。
答案 0 :(得分:3)
我知道回答你的问题可能不赞成,但我昨天设法解决了这个问题。在我尝试的所有选项中,我发现最快的解决方案是复制Eclipse Runnable Jar Export Wizard。它需要jar-in-jar-loader.zip
可以使用Runnable Jar Export Wizard获取...或者你可以通过Google / Eclipse安装找到它。
我发现这个解决方案构建速度快(30s),运行速度更快(5s启动成本)。它还使罐子结构非常整洁,没有爆炸的罐子。
<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>