Java - start another class' main in a different process

a 夏天 提交于 2019-12-04 09:08:33
Roman Vottner

As on your request I summarize my comments in an answer.

Your first problem was that you tried to invoke java.exe on a Linux or Mac box, which does not stick to the Microsoft convention of including the file type into the name. Therefore Linux and Mac usually use java instead.

The path to the executable can vary also from computer to computer. Therefore the probably most generic way is to locate the java executable using the JAVA_HOME environment variable which can be fetched in Java via System.getenv("JAVA_HOME"); or via System.getProperty("java.home"); Note however that they might not obviously point to the desired directory. Especially some Linux distributions place all binary files inside /bin or /usr/bin and therefore ${JAVA_HOME}/bin/java might not be available. In that case you should create a (hard)link to the executable.

If the path is not set you can set it manually in the session of your console you are executing your application (on Windows set JAVA_HOME=C:\Program Files\Java (or setx on newer Windows versions) on Linux export JAVA_HOME=/opt/java). This can also be done with user-priviledges

It is further strongly recommended to take care of in- and output-streams when dealing with processes. The linked article explains in depth why you should take care of it - not only to catch exceptions thrown by the invoked process.

On invoking a process (especially with the Java executable) you have a couple of options: You can either invoke the Java process directly (assuming Java is on your PATH) with new ProcessBuilder("java", "-cp", "path/to/your/binaries", "package.ClassName"); or you can invoke the Java executable via a shell - on Linux f.e. you could also use new ProcessBuilder("/bin/bash", "-c", "java -cp path/to/your/binaries package.ClassName"); (though the primer one is obviously preferable).

On loading classes/libraries dynamically you have to use the fully qualified class name. So, if you invoke the Java process in the root-directory of your project and your building-tool generates the class-files inside of ./build/classes and your class Test is located in package testpackage you will end up with the following set: ./build/classes/testpackage/Test.class. To start a new Java process which invokes the main method included in your Test.class you have to use the following command: java -cp ./build/classes testpackage.Test else Java will not be able to find the class definition of Test and execute the main-method.

Missing dependencies have to be added to the classpath (-cp ...) segment of the invoking Java command. F.e: java -cp lib/jar1.jar;lib/jar2.jar;build/classes/* package.ClassName. Multiple archives or directories are separated by a ; and an asterisk * is also possible to include everything within a directory.

One note left: if you ever try to ship your "application" you will need to adapt this code to a more generic version (property file f.e) as this will probably fail with high probability as the path might be totally different.

If I have something forgotten, please let me know.

Did you try to run java.exe from command prompt if it does not work there as well you need to set you java path to the JAVA Installation this can be done by setting variable JAVA_PATH in system variables and this should point to your Jdk bin folder.

If this does not wok then I think you need to provide full path to JAVA.exe as the program is trying to find this file and it is not able to find the file and it gives error

On contrary you can try making threads that would be a better solution because threads use less resources and are more efficient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!