从另一个罐子打开罐子 [英] Open jar from another jar

查看:171
本文介绍了从另一个罐子打开罐子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我已经看到很多解决方案来解决这个问题......但我想知道这是否可行:执行终端命令 java - Jar(B)中的XMx512 -jar MainJar.jar 用512 MB内存分配初始化Jar(A)。



在Jar中(B)我试过这个代码运行Jar(A)并且工作正常:

  public static void main(String [ ] args)抛出异常{
String jarName =MainJar.jar; // Jar(A)名字。
Desktop.getDesktop()。open(new File(jarName));
}

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



------------------------------编辑为要求更清楚。

解决方案

您可以使用 Runtime.exec()或ProcessBuilder来完成此任务。

 进程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();
}
}

然后你会让jar的清单文件指向此主要类

  Main-Class:AppLauncher 

然后你将通过

  java -jar MyJar.jar 


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



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



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



编辑:如果您不相信其他情况,并且实际采用ProcessBuilder路线,还有更多它不仅仅是我所说的。 要避免陷阱。例如,我没有从进程的输出流中读取(使用 Process.getInputStream()),因此如果子Java进程向stdout输出任何内容,它将在操作系统时冻结缓冲区已填满。


The same old problem ... I want to run my jar on Mac or Linux with high memory allocation. I do not want the user to open the Terminal and write java -XMx512 -jar MainJar.jar manually.

I have seen a lot of solutions to fix this ... But i was wondering if this might work : "Executing the Terminal command java -XMx512 -jar MainJar.jar in Jar(B) to initialize Jar(A) with 512 MB memory allocation.".

In Jar(B) i have tried this code to run Jar(A) and it worked fine :

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

But still i did not allocate memory for Jar(A) when initialized from Jar(B), so can i write a code in Jar(B) to run the Terminal and give it the command to execute it : "java -XMx512 -jar MainJar.jar" ?

------------------------------ Edited as requested to be more clear.

解决方案

You can use Runtime.exec() or a ProcessBuilder to accomplish this.

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

But honestly I think it's an awful solution. I would favour an installation package like InstallAnywhere. Failing that I would use a shell script to launch the Jar. Encapsulating it in a Jar where it can't be edited is annoying to users and now you have parallel dependencies rather than a single file.

If you were going to take this route, it would be possible to use the same Jar for both purposes. Add your class file to launch with the correct parameters to the Jar, say AppLauncher.class. We'll assume your program's real code starts at 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();
     }
}

Then you would have your Manifest file of the jar point to this main class:

 Main-Class: AppLauncher

You would then execute this jar via

java -jar MyJar.jar

Or through file associations (double click).

When it runs, it executes the command java -Xmx512M -cp MyJar.jar Main which runs the main method of the Main class of your jar. The same jar is used in both invocations: the first time it automatically runs AppLauncher.main() via the manifest file, the second time Main.main() via an explicit process call.

This is still fragile of course. For one thing, it assumes that the working directory is set to the folder that contains your jar file. That's not always true.

Edit: Just in case you're not convinced to do otherwise, and actually take the ProcessBuilder route, there's more to it than just what I noted. There are pitfalls to avoid. For instance, I didn't read from the process's output stream (using Process.getInputStream()) so if child Java process outputs anything to stdout, it will freeze when the OS buffer is filled.

这篇关于从另一个罐子打开罐子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆