如何将多个JAR文件合并为一个?

13

我已经阅读了许多关于此问题的文章和解释,花费了太多时间,但是一切都太笼统或太具体。

这个问题实际上只适用于我制作的一个小应用程序。它包含一个类,并需要另外两个Jar库。我已经将它们包含在项目中(多个项目,因为我尝试过在Netbeans和Eclipse中进行尝试......重新创建一个单一类项目很容易)。所有这一切的目的是我的HTML/网页项目不必处理超过一个Jar文件或引用它们。这并不是一个非常复杂的小应用程序/项目。

最初,我是在Netbeans中创建的。它有主要的程序包,在添加了2个Jars之后,它们被放置在“Libraries”区域(“resources”文件夹)中。构建完成后,Netbeans会为我的一个包/类创建一个Jar文件,然后将另外两个库放在其旁边的“lib”目录中。我希望它们可以在一个可分发的Jar文件中。从我看过的许多内容中,我尝试在build.xml中添加以下内容:

<target name="YourBigJar" depends="-post-jar">
  <jar destfile="dist/BigJar.jar">
    <zipfileset src="dist/cxapplet.jar"/>
    <zipfileset src="resources/dpotapi.jar"/>
    <zipfileset src="resources/dpotjni.jar"/>
  </jar>
</target>

但它没有产生任何东西。我从NetBeans - deploying all in one jar得到了这个。我不知道/理解如何使用build.xml,所以如果出现问题(显然),我不会感到惊讶,但我没有收到错误/警告消息。

当我在Eclipse中制作它时,它有效地将它们组合在一起,但当我在我的实际Web项目中使用Jar时,它说它找不到来自其他两个Jars的类。我不明白如何修复它,但它是一个Classpath问题吗?在Eclipse中,我创建了一个名为"lib" 的新目录,并将Jars放入其中。然后,我右键单击项目,转到"Java Build Path",并添加Jars,还在"Order and Export"选项卡下检查它们。从我读过的东西来看,我右键单击项目,选择"Export",选择"Jar",取消选中".classpath "和".project "文件,只选中"Export generated class files and resources",然后允许它生成清单文件。像我说的那样,这将生成一个Jar,但其内容是我的包和一个具有另外2个Jars的 "lib" 目录。清单在那里,但它非常空,没有引用任何文件(不确定是否重要)。当我把它放在我的Web应用程序中时,它说小程序无法找到其他类。

它看起来很简单-一个包/类,两个外部Jars...在构建发布为小程序时将它们组合成一个Jar。有什么想法吗?

更新:

自从我们开始使用Maven以来,有人研究了使用Maven插件的方法。所以我们最终创建了一个新项目来容纳小程序(因为它在多个项目中使用),并在我们的pom.xml中使用了这个:

<build>
  <resources>
    <resource>
      <directory>${basedir}/applet</directory>
      <excludes>
        <exclude>codesignstore</exclude>
      </excludes>
    </resource>
    <resource>
      <directory>${basedir}/src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <artifactId>maven-assembly-plugin</artifactId>
      <version>2.2-beta-5</version>
      <configuration>
        <descriptorRefs>
          <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <finalName>cxapplet</finalName>
        <archive>
          <index>true</index>
          <manifest>
            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
          </manifest>
        </archive>
        <appendAssemblyId>false</appendAssemblyId>
      </configuration>
      <executions>
        <execution>
          <id>make-my-applet-jar</id>
          <phase>package</phase>
          <goals>
            <goal>single</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jarsigner-plugin</artifactId>
      <version>1.2</version>
      <executions>
        <execution>
          <id>sign</id>
          <goals>
            <goal>sign</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <keystore>${basedir}/applet/codesignstore</keystore>
        <alias>codesigncert</alias>
        <storepass>HIDDEN</storepass>
        <keypass>HIDDEN</keypass>
      </configuration>
    </plugin>
  </plugins>
</build>

这很好,因为它允许我们使用我们的代码签名证书来自动签名。


1
所有这一切的重点是,我的HTML/web项目不应该处理超过一个Jar。将其设置为浏览器可以处理是微不足道的。你有什么想法吗?按照通常的方式部署Jars(这比你当前的策略更有优势),并节省时间。 - Andrew Thompson
最好将一个jar的依赖关系制作到另一个jar中。许多jar制作工具可以让您的工作更加轻松。 - joey rohan
@joeyrohan 我不确定你的意思,但这就是为什么我试图使用Netbeans和Eclipse的构建工具来完成它。 - Ian
@AndrewThompson,我提出这个问题的主要原因是我在签署Jars和浏览器识别此问题方面遇到了困难。我知道,第一步应该是确定签署的问题,但是如果我提取并查看Jar中的每个内容,一切都很正常,所以我有点担心多个Jars可能会引起问题。不确定那是否是真正的原因,但我认为如果我把所有东西组合起来,可能可以更好地组织并且能够运行。 - Ian
@Ian 我不是在谈论IDE,而是关于制作jar的工具,请Google一下。 - joey rohan
2个回答

5
首先,让我说一下,没有必要将jar文件组合在一起-您可以使用类文件(而不是jar文件)和其独立的依赖项来部署小程序。
但是,如果您觉得必须将类及其所有依赖项合并为一个大的jar文件,则可以这样做。
无法将jar文件放入另一个jar文件中 - jar文件不起作用。您需要提取所有jar文件的内容,然后再将其压缩成一个jar文件。
如果要这样做,建议使用Maven构建工具来完成此操作。一旦您使用Maven设置了构建,就可以配置Maven Assembly Plugin来为您构建一个大的jar文件。
我知道Eclipse支持Maven,我认为NetBeans也是如此。

抱歉,我知道简单地组合Jars不起作用,正如您提供的原因一样。所以我想我的观点是希望在您选择的场景中(Eclipse、Netbeans、Maven等)得到一个简单的代码/工作/逻辑示例,以解释如何实现我想要的功能。所以,正如您建议使用Maven一样,我不知道您是否能提供一些步骤来完成这个过程。我会查看第二个链接(因为我已经安装了Maven,并在另一个项目中使用它,尽管我不是管理者)。所以谢谢 :) - Ian

-1
从您的bin目录开始,为什么不尝试:
jar.exe -cvf cxapplet.jar *

将外部 jar 文件放置在您的 bin 目录中的适当位置,并手动使用外部 jar 文件打包您的类文件。

或者,参见this thread,可能会为您提供更多信息。


“为什么不试试” - 因为我没有想到 :) 它从未在我的脑海中出现过,我也不知道如何有效地使用jar工具,或者想到在bin上使用它。此外,在bin目录中唯一的东西是我的主类编译后的代码(通过其包),那么我该如何将lib目录中的内容(位于bin旁边),即两个外部JAR文件,包含并与bin目录的内容合并? - Ian
(我是根据我大约4个月前尝试过的内容记忆来做这个的)在构建项目后,只需将lib目录复制到构建目录即可。另外,请查看我的编辑答案。 - AerusDar
天啊,我不知道为什么我没想到这个。所以当我尝试它时,它确实将它们组合在一起,但它只是将两个外部Jars放入新Jar的根目录中...但似乎我真正需要的是从外部Jars中提取所有内容,然后将它们全部压缩在一起。这有意义吗?Netbeans实际上正在执行与您提供的相同的操作,但还将它们添加到清单文件中的类路径中,以便它们可以被识别(或者无论它是如何工作的)。 - Ian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接