【问题标题】:execute a wrapped jar file within a jar在 jar 中执行一个包装好的 jar 文件
【发布时间】:2013-05-23 12:16:09
【问题描述】:

我正在尝试围绕可运行的 .jar 文件创建一个包装器,以便为 JVM 传递参数。 我的包装器的相关代码是:

public static void main(String[] args) throws IOException
      String[] cmdArray = {"java",
        System.getProperty("os.arch").contains("64") ? "-d64" : "",
        "-XX:+AggressiveHeap",       
        "-jar",
        "/lib/A.jar"  //replace with jar name 
            };
      Runtime.getRuntime().exec(cmdArray);
}

A.jar 文件是我的 Wrapper 项目中的一个引用库(在构建路径和类路径中添加)。示例:

 Wrap
   >src
       >org
           >Wrapper.java
   >lib
       >A.jar

当我从 Wrapper 项目(我们称之为 B.jar)创建第二个 jar 文件时,它的内容是

lib
   >A.jar
org
   >eclipse
          >jdt
             >... (i.e., all the files for the jarinjarloader)
   >Wrapper.class
META-INF
       >MANIFEST.MF

第二个 jar 中的清单文件如下所示:

Manifest-Version: 1.0
Rsrc-Class-Path: lib/A.jar
Class-Path: .
Rsrc-Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Main-Class: org.Wrapper

当我启动 B.jar 文件时,它显示进程已启动,但未调用/启动 A.jar 文件。没有错误,没有例外。该过程开始和终止。尝试通过命令行启动它并双击。

如果我将 MANIFEST.MF 文件修改为

Rsrc-Class-Path: A.jar

以及Wrapper.java的main方法中来自cmdArray的元素来自

"/lib/A.jar" to "A.jar"

我在我的 wrapper jar 所在的文件夹(例如 B.jar)中制作了 A.jar 的副本,它完美启动,调用了第二个 jar。 我究竟做错了什么?我想如何将类路径传递给内部 jar 文件? 任何帮助将不胜感激。

【问题讨论】:

    标签: java jvm wrapper executable-jar


    【解决方案1】:

    虽然严格来说这不是对您问题的回答,但我想我可以为您提出一种更好的方法来解决您的原始问题(即向 jvm 添加 args)。

    This article 讨论如何在保留 jvm、命令行和其他启动选项的情况下重新启动 java 应用程序。

    为什么这可能会让您感兴趣?好吧,稍微调整一下,你可以做的是摆脱在你的主 jar 周围添加包装器并在你的 main 中做这样的事情:

    1. 检查是否存在一些命令行参数,这些参数告诉应用程序是使用经过调整的 vm 选项运行的,并且:
    2. 如果存在 - 让应用完成它的工作
    3. 在不 - 重新启动应用程序中,调整 jvm 选项以及传递步骤 1 中提到的命令行参数

    我在过去的一个项目中做过类似的事情,与包装 jar 方法相比,它有助于简化构建/打包和调试。

    希望这会有所帮助。

    【讨论】:

    • 感谢您的快速回复。事实上,应用程序将被分发到不同的客户端、不同的操作系统和/或 java 配置。您的解决方案是一种非常优雅的方式,但我现在不提前他们使用的是什么 JVM。尽管过去几年有无数的需求,但这个问题(在创建 jar 时设置 JVM 参数)没有得到解决,这很烦人。无论如何,为您的建议 +1。
    • @Marius 关于您提到的不同操作系统/JVM的问题:您的包装器将遇到完全相同的问题。事实上,我看到的唯一区别是你使用普通的java 命令来运行你包装的 jar,并且在提到的文章中,java 命令是使用System.getProperty("java.home") + "/bin/java" 从当前 jvm 确定的。如果您对此更有信心,我认为您没有理由不能更改这段特定的代码来支持您的运行变体。
    • 顺便说一句:我可以确认重新启动的方法对于 Windows 和 Linux 上的 HotSpot 来说是一种魅力。
    • 老实说,我并不真正信任 System.getProperty("bla"),因为我在使用 System.getProperty("os.arch") 或 System.getProperty("sun .cpu.isalist") 在我的机器上,它有一个英特尔架构,它返回我 amd64。
    猜你喜欢
    • 2017-12-21
    • 1970-01-01
    • 2014-12-31
    • 2014-09-23
    • 2012-02-25
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多