Executing a Java application in a separate process

2019-01-02 20:27发布

Can a Java application be loaded in a separate process using its name, as opposed to its location, in a platform independent manner?

I know you can execute a program via ...

Process process = Runtime.getRuntime().exec( COMMAND );

... the main issue of this method is that such calls are then platform specific.


Ideally, I'd wrap a method into something as simple as...

EXECUTE.application( CLASS_TO_BE_EXECUTED );

... and pass in the fully qualified name of an application class as CLASS_TO_BE_EXECUTED.

9条回答
牵手、夕阳
2楼-- · 2019-01-02 21:19

Expanding on @stepancheg's answer the actual code would look like so (in the form of a test).

import org.junit.Test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.stream.Collectors;

public class SpinningUpAJvmTest {
    @Test
    public void shouldRunAJvm() throws Exception {
        String classpath = Arrays.stream(((URLClassLoader) Thread.currentThread().getContextClassLoader()).getURLs())
                .map(URL::getFile)
                .collect(Collectors.joining(File.pathSeparator));
        Process process = new ProcessBuilder(
                System.getProperty("java.home") + "/bin/java",
                "-classpath",
                classpath,
                MyMainClass.class.getName()
                // main class arguments go here
        )
                .inheritIO()
                .start();
        int exitCode = process.waitFor();
        System.out.println("process stopped with exitCode " + exitCode);
    }
}
查看更多
素衣白纱
3楼-- · 2019-01-02 21:21

A problem that occurs when you run this from a java GUI is it runs in the background. So you cannot see the command prompt at all.

To get around this, you have to run the java.exe through "cmd.exe" AND "start". I dont know why, but if you put "cmd /c start" infront it shows the command prompt as it runs.

However, the problem with "start" is that if there is a space in the path to the application (which the path to the java exe usually have as it is in C:\Program Files\Java\jre6\bin\java.exe or similar), then start just fails with "cannot find c:\Program"

So you have to put quotes around C:\Program Files\Java\jre6\bin\java.exe Now start complains about parameters that you pass to java.exe: "The system cannot find the file -cp."

Escaping the space in "Program Files" with a backslash also does not work. So the idea is to not use space. Generate a temporary file with the bat extension and then put your command with spaces in there and run the bat. However, running a bat through start, does not exit when done, so you have to put "exit" at the end of the batch file.

This still seems yucky.

So, looking for alternatives, I have found that using quote space quote in the space of "Program Files" actually works with start.

In the EXECUTE class above change the string builder appends to:

append( "cmd /C start \"Some title\" " ).
append( java.lang.System.getProperty( "java.home" ).replaceAll(" ", "\" \"") ).
append( java.io.File.separator ).
append( "bin" ).
append( java.io.File.separator ).
append( "java" ).
append( " " ).
append( new java.io.File( "." ).getAbsolutePath() ).
append( java.io.File.separator ).
append( CLASS_TO_BE_EXECUTED ).
查看更多
千与千寻千般痛.
4楼-- · 2019-01-02 21:25

Did you check out the ProcessBuilder API? It's available since 1.5

http://java.sun.com/javase/6/docs/api/java/lang/ProcessBuilder.html

查看更多
登录 后发表回答