代码之家  ›  专栏  ›  技术社区  ›  Brad

从另一个罐子里打开罐子

  •  0
  • Brad  · 技术社区  · 14 年前

    同样的老问题。。。我想用高内存分配在Mac或Linux上运行jar。我不希望用户打开终端并写入 java-XMx512-jar MainJar.jar 手动操作。

    我看到了很多解决办法。。。但我想知道这是否可行:“ 执行终端命令 java-XMx512-jar MainJar.jar 在Jar(B)中初始化具有512 MB内存分配的Jar(A)。 ".

    在Jar(B)中,我尝试了这段代码来运行Jar(A),它运行得很好:

    public static void main(String[] args) throws Exception{
       String jarName = "MainJar.jar";  // Jar(A) name.
       Desktop.getDesktop().open( new File( jarName ) );
    }
    

    但是,当从Jar(B)初始化时,我仍然没有为Jar(A)分配内存,所以我可以在Jar(B)中编写代码来运行终端并给它执行命令: " java-XMx512-jar MainJar.jar " ?

    ------------------------------按要求编辑以更清晰。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Mark Peters    14 年前

    你可以用 Runtime.exec() 或者一个ProcessBuilder来完成这个任务。

    Process proc = new ProcessBuilder("java", "-XMx512M", "-jar", "MainJar.jar").start();
    int result = proc.waitFor();
    

    但老实说,我认为这是一个糟糕的解决方案。我更喜欢像InstallAnywhere这样的安装包。如果失败,我将使用shell脚本来启动Jar。把它封装在一个不能编辑的Jar中对用户来说很烦人,现在你有了并行的依赖关系,而不是一个单独的文件。

    如果您要走这条路,那么可以将同一个Jar用于这两个目的。将要使用正确参数启动的类文件添加到Jar中,例如 AppLauncher.class . 我们假设你的程序真正的代码从 Main.class .

    public class AppLauncher {
         public static void main(String... args) {
            Process proc = new ProcessBuilder("java", "-XMx512M", "-cp", "MyJar.jar", "Main").start();
            int result = proc.waitFor();
         }
    }
    

    那么你会 have your Manifest file of the jar point to this main class :

     Main-Class: AppLauncher
    

    然后通过

    java -jar MyJar.jar
    

    或通过文件关联(双击)。

    当它运行时,它执行命令 java -Xmx512M -cp MyJar.jar Main 它运行jar主类的main方法。两次调用都使用同一个jar:第一次自动运行时 AppLauncher.main() 通过清单文件,第二次 Main.main() 通过显式的进程调用。

    当然,这仍然很脆弱。首先,它假设工作目录设置为包含jar文件的文件夹。这并不总是真的。

    编辑 :以防您不确定是否要执行其他操作,而是实际采用ProcessBuilder路径,这不仅仅是我注意到的。 There are pitfalls to avoid . 例如,我没有读取进程的输出流(使用 Process.getInputStream() )因此,如果子Java进程向stdout输出任何内容,那么当OS缓冲区填满时,它将冻结。