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 fi开发者_如何学运维ne :
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.
精彩评论