Java 在jar中执行包装好的jar文件

Java 在jar中执行包装好的jar文件,java,jvm,wrapper,executable-jar,Java,Jvm,Wrapper,Executable Jar,我试图在runnable.jar文件周围创建一个包装器,以便为JVM传递参数。 我的包装器的相关代码是: public static void main(String[] args) throws IOException String[] cmdArray = {"java", System.getProperty("os.arch").contains("64") ? "-d64" : "", "-XX:+AggressiveHeap",

我试图在runnable.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);
}
jar文件是我的包装器项目中的一个引用库(添加在构建路径和类路径中)。例如:

 Wrap
   >src
       >org
           >Wrapper.java
   >lib
       >A.jar
当我从包装器项目(我们称之为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"
我在我的包装器jar所在的文件夹中复制了一个.jar(例如,B.jar),它会完美地启动,调用第二个jar。 我做错了什么?我应该如何将类路径传递给内部jar文件?
任何帮助都将不胜感激。

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

讨论如何重新启动java应用程序,保留jvm、命令行和其他启动选项

为什么你会感兴趣?好吧,稍微调整一下,您可以做的是摆脱在主jar周围添加包装器,并在主jar中执行以下操作:

  • 检查是否存在一些命令行参数,这些参数告诉您应用程序是使用经过调整的vm选项运行的,并且:
  • 如果存在-让应用程序完成它的工作
  • 在不重新启动应用程序中,调整jvm选项并传递步骤1中提到的命令行参数
  • 我在过去的一个项目中做过类似的事情,与包装jar方法相比,它有助于简化构建/打包和调试


    希望这会有所帮助。

    谢谢您的快速回复。事实上,应用程序将被分发到不同的客户端、不同的操作系统和/或java配置。您的解决方案是一种非常优雅的方式,但我现在不知道他们在使用什么JVM。这个问题(在创建jar时设置JVM参数)没有得到解决,尽管在过去几年中有无数的需求,这是非常令人恼火的。无论如何,+1是你的建议。@Marius关于你提到的不同OS/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。