我想启动一个JavaFX应用程序,如果它还没有运行的话。
JavaFX应用程序打包在JAR容器中,该容器位于调用应用程序的类路径中。调用应用程序应该执行JavaFX应用程序。
如果调用应用程序被终止,则JavaFX应用程序不应终止。 (因此它需要在一个单独的过程中)
我尝试了以下方法,但即使uiProcess.isAlive()
返回true,JavaFX应用程序也永远不可见。
// caller main thread
String[] startOptions = new String[]{"java", "-jar", "javafx-ui.jar"};
Process uiProcess = new ProcessBuilder(startOptions).start();
+++++++++++++++++++++++++++++++++++++++
更新:
我创建了一个辅助类,它接受JAR名称并尝试执行它。不幸的是,这不起作用。但是,如果我复制记录的CLI命令并在终端中执行命令,则应用程序将按预期启动。如果我打印System.getProperty("java.class.path")
属性,我看到我的javafx-ui.jar在类路径上。
用法:
ProcessExecutor processExecutor = new ProcessExecutor();
processExecutor.executeJarByName("javafx-ui.jar");
执行人:
public class ProcessExecutor {
private List<Process> processes;
private static Logger logger = LoggerFactory.getLogger(ProcessExecutor.class);
/**
* Default constructor
*/
public ProcessExecutor() {
processes = new ArrayList<>();
}
/**
* Executes jar in a standalone process
*
* @param jarName
*/
public Process executeJarByName(String jarName) throws IOException {
String[] command = new String[]{"java", "-jar", jarName};
ProcessBuilder builder = createProcessBuilder(command);
Process process = builder.start();
processes.add(process);
if (process.isAlive()) {
Optional<ProcessHandle> processHandle = ProcessHandle.of(process.pid());
if (processHandle.isPresent()) {
ProcessHandle.Info processInfo = processHandle.get().info();
logger.info("COMMAND: {}", processInfo.command().orElse(""));
logger.info("CLI: {}", processInfo.commandLine().orElse(""));
logger.info("USER: {}", processInfo.user().orElse(""));
logger.info("START TIME: {}", processInfo.startInstant().orElse(null));
logger.info("TOTAL CPU: {}", processInfo.totalCpuDuration().orElse(null));
}
}
return process;
}
private ProcessBuilder createProcessBuilder(String[] command) {
return new ProcessBuilder(command);
}
/**
* Kills all executed processes
*/
public void killAll() {
processes.forEach(p -> p.destroy());
}
}
答案 0 :(得分:0)
如果我使用Java ProcessBuilder执行以下命令,我就可以了。 mainClassName
必须是类的完全限定类名,包含main()
方法。 (包括包名)
String separator = System.getProperty("file.separator");
String classpath = System.getProperty("java.class.path");
String javaHome = System.getProperty("java.home");
String java = javaHome + separator + "bin" + separator + "java";
String[] command = {java, "-cp", classpath, mainClassName};
ProcessBuilder builder = createProcessBuilder(command);