3

我陷入了一个非常普遍的问题。

我将我的 jar(对第三方供应商有很多依赖项)插入到应用程序服务器 lib 目录中。如果我只是将我的 jar 及其依赖项复制到服务器库中,那么服务器类路径会变得很长,因此服务器无法工作。因此,我想将这个 Jar 及其所有依赖项打包在一个 jar 中,这样服务器的类路径就不会变得太长。我在各种论坛上发现有一个实用程序可以做到这一点,即 OneJar。但是这个实用程序适用于可执行 jar。就我而言,我的最终 jar 将无法执行。

我还尝试了 ANT 提供的 ZIPFileSetGroup 实用程序,但这会导致清单文件出现安全问题。

你能帮我解决这个问题吗?

谢谢!

4

3 回答 3

3

如果使用maven构建,可以使用maven依赖插件,使用copy-dependency任务。它会在创建它时将所有依赖项复制到您的 jar 文件中。

如果手动将 jar 添加到 jar 文件中,则需要确保 jar 文件中包含 Manifest.mf 文件并在其中指定主类和类路径。

Manifest-Version: 1.0
Main-Class: com.mypackage.MainClass
Class-Path: my.jar log4j.jar

另一种选择可能是构建一个 .ear 文件,这通常是您在将特定 jar 文件与它们打包时看到企业应用程序或 Web 应用程序的 .war 文件的方式。听起来您正在使用服务器,因此其中一种格式可能更适合您。

于 2012-12-29T16:11:37.333 回答
0

当你说

子进程从 server/lib 目录中获取类路径

这是一个在你控制之下的过程吗?如果父进程要指定类路径,就像

server/lib/*

(即文字*)然后目标java进程将枚举lib目录本身中的 jar 文件——它们并不都需要在类路径中命名。

但是,如果父进程显式枚举server/lib/*.jar以构建-cp值,那么即使 JAR 不是“可执行”,您也可以利用Class-PathJAR 清单中的 in 生效这一事实。您可以使用这样的节来创建仅清单 JAR 文件

<!-- location of your 300 dependency JAR files, file1.jar ... file300.jar -->
<property name="lib.dir" location="lib" />
<fileset id="dependencies" dir="${lib.dir}" includes="*.jar" />

<pathconvert property="manifest.classpath" dirsep="/" pathsep=" "
             refid="dependencies">
  <map from="${lib.dir}" to="myapp" />
</pathconvert>

<jar destfile="myapp-manifest.jar">
  <manifest>
    <attribute name="Class-Path" value="${manifest.classpath}" />
  </manifest>
</jar>

这将生成一个名为的 JAR 文件myapp-manifest.jar,其清单包含

Class-Path: myapp/file1.jar myapp/file2.jar ... myapp/file300.jar

你把这个文件server/lib和 300 个依赖项放到一个新目录server/lib/myapp中。现在生成的-cp将只包含一个文件 ( myapp-manifest.jar),但生成的 java 进程将拥有所有 300 个myappJAR 文件。

于 2012-12-29T21:32:32.917 回答
0

zipgroupfileset在 ANT 中的 jar 任务中使用是最简单的方法。

<jar destfile="MyApplication.jar" filesetmanifest="mergewithoutmain">
  <zipgroupfileset dir="lib" includes="*.jar" /> 
  <!-- other options -->
  <manifest>
    <attribute name="Main-Class" value="Main.MainClass" />
  </manifest>
</jar>

请注意,设置为 mergewithoutmain 的filesetmanifest标志会合并除清单的 Main 部分之外的所有内容。

签名的 jar 导致需要手动处理的SecurityException 。如果与签名 jar 相关的任何类作为一个整体验证 jar 上的签名,那么这些将在运行时失败。针对特定文件的摘要签名将毫无问题地添加到清单中。由于问题是您的类路径变得太大,您可能无法将所有 jar 包捆绑到一个 jar 中,而是将它们中的大部分合并,使 CLASSPATH 易于管理。

还有:http ://code.google.com/p/jarjar/

使用所有依赖的 jar 创建目标目录。接下来将 10 个 jar 移动到临时目录中,并继续以 10 个为一组移动 jar,每次尝试从该组创建单个 jar。当您收到安全异常时,您可以确定是哪一个导致了问题。尝试分而治之的方法。如果你有 300 个罐子,那么只需要这样做 30 次。

于 2012-12-29T15:44:37.087 回答