将发布合并到一个JAR文件中的最简单方法


74

是否有工具或脚本可以轻松地将一堆JAR文件合并为一个JAR文件?一个好处是可以轻松地设置主文件清单并使之可执行。

具体情况是Java重组文本工具。我想用类似的东西来运行它:

java -jar rst.jar

据我所知,它没有依赖性,这表明它不应该是一个简单的单文件工具,但是下载的ZIP文件包含许多库。

      0  11-30-07 10:01   jrst-0.8.1/
    922  11-30-07 09:53   jrst-0.8.1/jrst.bat
    898  11-30-07 09:53   jrst-0.8.1/jrst.sh
   2675  11-30-07 09:42   jrst-0.8.1/readmeEN.txt
 108821  11-30-07 09:59   jrst-0.8.1/jrst-0.8.1.jar
   2675  11-30-07 09:42   jrst-0.8.1/readme.txt
      0  11-30-07 10:01   jrst-0.8.1/lib/
  81508  11-30-07 09:49   jrst-0.8.1/lib/batik-util-1.6-1.jar
2450757  11-30-07 09:49   jrst-0.8.1/lib/icu4j-2.6.1.jar
 559366  11-30-07 09:49   jrst-0.8.1/lib/commons-collections-3.1.jar
  83613  11-30-07 09:49   jrst-0.8.1/lib/commons-io-1.3.1.jar
 207723  11-30-07 09:49   jrst-0.8.1/lib/commons-lang-2.1.jar
  52915  11-30-07 09:49   jrst-0.8.1/lib/commons-logging-1.1.jar
 260172  11-30-07 09:49   jrst-0.8.1/lib/commons-primitives-1.0.jar
 313898  11-30-07 09:49   jrst-0.8.1/lib/dom4j-1.6.1.jar
1994150  11-30-07 09:49   jrst-0.8.1/lib/fop-0.93-jdk15.jar
  55147  11-30-07 09:49   jrst-0.8.1/lib/activation-1.0.2.jar
 355030  11-30-07 09:49   jrst-0.8.1/lib/mail-1.3.3.jar
  77977  11-30-07 09:49   jrst-0.8.1/lib/servlet-api-2.3.jar
 226915  11-30-07 09:49   jrst-0.8.1/lib/jaxen-1.1.1.jar
 153253  11-30-07 09:49   jrst-0.8.1/lib/jdom-1.0.jar
  50789  11-30-07 09:49   jrst-0.8.1/lib/jewelcli-0.41.jar
 324952  11-30-07 09:49   jrst-0.8.1/lib/looks-1.2.2.jar
 121070  11-30-07 09:49   jrst-0.8.1/lib/junit-3.8.1.jar
 358085  11-30-07 09:49   jrst-0.8.1/lib/log4j-1.2.12.jar
  72150  11-30-07 09:49   jrst-0.8.1/lib/logkit-1.0.1.jar
 342897  11-30-07 09:49   jrst-0.8.1/lib/lutinwidget-0.9.jar
2160934  11-30-07 09:49   jrst-0.8.1/lib/docbook-xsl-nwalsh-1.71.1.jar
 301249  11-30-07 09:49   jrst-0.8.1/lib/xmlgraphics-commons-1.1.jar
  68610  11-30-07 09:49   jrst-0.8.1/lib/sdoc-0.5.0-beta.jar
3149655  11-30-07 09:49   jrst-0.8.1/lib/xalan-2.6.0.jar
1010675  11-30-07 09:49   jrst-0.8.1/lib/xercesImpl-2.6.2.jar
 194205  11-30-07 09:49   jrst-0.8.1/lib/xml-apis-1.3.02.jar
  78440  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.0.2.jar
  86249  11-30-07 09:49   jrst-0.8.1/lib/xmlunit-1.1.jar
 108874  11-30-07 09:49   jrst-0.8.1/lib/xom-1.0.jar
  63966  11-30-07 09:49   jrst-0.8.1/lib/avalon-framework-4.1.3.jar
 138228  11-30-07 09:49   jrst-0.8.1/lib/batik-gui-util-1.6-1.jar
 216394  11-30-07 09:49   jrst-0.8.1/lib/l2fprod-common-0.1.jar
 121689  11-30-07 09:49   jrst-0.8.1/lib/lutinutil-0.26.jar
  76687  11-30-07 09:49   jrst-0.8.1/lib/batik-ext-1.6-1.jar
 124724  11-30-07 09:49   jrst-0.8.1/lib/xmlParserAPIs-2.6.2.jar

可以看到,不需要手动执行此操作有些可取。

到目前为止,我只尝试了AutoJar和ProGuard,它们都很容易上手。看来JAR文件中的常量池存在一些问题。

显然,jrst有点破损,因此我将对其进行修复。在Maven的 pom.xml文件显然是打破过,所以我必须解决这个问题JRST固定之前......我觉得自己像一个错误磁铁:-)


更新:我从来没有修正过这个应用程序,但是我签出了基于胖JAR的Eclipse的“ Runnable JAR导出向导”。我发现这很容易用于部署自己的代码。

其他一些出色的建议对于在非Eclipse环境中进行构建可能会更好,oss可能应该使用Ant进行良好的构建。(到目前为止,Maven只是给我带来了痛苦,但其他人还是喜欢它。)




Answers:


34

Eclipse 3.4 JDT的Runnable JAR导出向导。

在Eclipse 3.5中,已对此进行了扩展。现在,您可以选择要如何处理引用的JAR文件。


您能否检查生成的ant脚本是否可用?之前是绝对文件路径而不是相对文件路径。
托尔比约恩Ravn的安徒生

62

蚂蚁的zipfileset工作

<jar id="files" jarfile="all.jar">
    <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
    <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
</jar>

1
+1,因为这还允许添加<manifest />标记并设置主类。
Shirkrin

是否可以对目录中的所有jar文件执行此操作。会很整洁。库更改时,避免需要更新build.xml。
弗朗斯·伦德伯格

3
尝试这种方法,您不必担心添加新的jar:github.com/anupamsaini/Trie/blob/master/src/build.xml#L42
Anupam Saini

27

尝试了几种不同的解决方案后,我发现One-JAR 是最容易使用的,并且设法做到了这一点:生成包含我需要的所有内容的单个可执行JAR。

One-JAR使用自定义的类加载器,该类加载器可以导航嵌套的资源。查看下载中的.bat文件,它看起来像是jrst-0.8.1.jar中的org.codelutin.jrst.JRST是主类,因此清单应如下所示:

Main-Class: com.simontuffs.onejar.Boot
One-Jar-Main-Class: org.codelutin.jrst.JRST

真正很酷的是,One-JAR将为您处理传递命令行参数。假定您需要的所有资源都捆绑在单个JAR中,则类路径由自定义类加载器处理。

使用One-JAR的最简单方法是使用ant。有一个自定义的“单罐”蚂蚁任务,其工作原理如下(假设您的清单被称为“ rst.mf”):

<target name="jar-rst">
    <one-jar destfile="rst.jar" manifest="rst.mf">
        <main jar="jrst-0.8.1.jar" />
        <lib>
            <fileset dir="${pathToJars}">
                <include name="batik-util-1.6-1.jar" />
                <include name="icu4j-2.6.1.jar" />
                <include name="commons-collections-3.1.jar" />
                <!-- Snip -->
            </fileset>
        </lib>
    </one-jar>
</target>

1
带有ant的one-jar的脚本功能使其可在连续构建系统中使用。
托尔比约恩Ravn的安徒生

1.如果我的jar内有多个应用程序(几个入口点类),One-JAR可以使用吗?2.如果此jar由另一个应用程序使用,它还能使用“ One-JAR”内嵌套jar中的类吗?
MRalwasser'5

14

如果您是Maven用户,通常程序集插件会执行您想要的操作,或者可能是阴影插件,并且在某些情况下会组合使用。

使用Assembly插件,可以使用任何必要的设置将清单文件放入项目中,尽管默认值通常很好。然后完成构建

mvn assembly:assembly

或者,如果您还有其他需要处理的特殊事项,则可以选择其他目标之一。所有要包含的JAR文件都由Maven的依赖解析器获取。如果您使用shade插件,它通常是安装目标的一部分,在一个特定项目中,我现在要做

mvn install
mvn assembly:single

assembly:single目标是解决问题的寿命,在这种情况下,在一个春天的应用。



8

ProGuard不只是收拾你的JAR文件合并为一个,但它也可以优化,清理或混淆您的类文件,使所产生的JAR文件不是所有的JAR文件之前总和小得多。

我实际上是使用JRST工具尝试过ProGuard的,正如您所报告的那样。我试图找出问题所在,并发现它与jrst引用的ICU4J库中的错误有关。问题是,使用的ICU版本现在已经过时了。因此,我icu.jar用ICU4J 3.2版替换了该文件。现在,ProGuard可以通过JRST库找到许多其他有关不兼容的错误/警告。

我的猜测是ProGuard可以按预期工作,但是jrst的库并不统一。除了与开发人员交谈外,我不知道您能做更多的事情,因为他们应该检查并更新项目的依赖关系。


谢谢!我下载并尝试过,但是在这个特殊的领域中,它在icu4j-2.6.1.jar上用未知的常数场轰炸,
tovare

7

(基于Andrian的):

<jar id="files" jarfile="all.jar">
  <zipgroupfileset dir="${library.dir}" includes="*.jar" excludes="test-helper.jar"/>
  <zipfileset src="first.jar" includes="**/*.java **/*.class"/>
  <zipfileset src="second.jar" includes="**/*.java **/*.class"/>
  <fileset dir=".">
    <include name="LICENSE"/>
    <include name="NOTICE"/>
  </fileset>
</jar>

5

One-JAR 0.97刚刚在http://one-jar.sourceforge.net上发布,并且已经扩展了对SpringGuice等框架的支持,这可能给其他方法带来麻烦。它还处理classloader-inversion-One-JAR外部的某些JAR文件(例如JDBC)可能未捆绑提供的驱动程序)。

One-JAR是命令行,带有AntMaven 2插件。仅使用“ jar”工具进行构建也很简单。

我还可以推荐Ference Hechler在上面写的Eclipse Jar Exporter(可运行):他在提出一种简单的包装一组JAR文件的方法方面做得很好。他和我从事One-JAR的开发,但Jar导出器基于不同的代码库。


3

有一个名为autojar的工具,它将扫描您的字节码并使用找到的类(包括引用的(导入的)类)编译.jar文件。

但是,并非总是与Spring之类的东西一起使用,在Spring中,您可以在配置中指定类名,然后由框架加载它。


感谢您的指导,似乎在此特定应用程序中的某些.jars使我有些头痛。
tovare


2

我认为您需要的工具是JarSplicehttp//ninjacave.com/jarsplice

要求Ant或Maven,有它自己的GUI,可以直接使用,并且你问到底是什么- >它结合了几个jar文件的内容到一个单一的一个(请注意,它仍然需要添加自己的类加载器)。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.