我正在开发一个用Java编写的程序,对于某些操作,它使用用户配置的命令行启动外部程序。当前它使用Runtime.exec()
并且不保留Process
引用(启动的程序是文本编辑器或存档实用程序,因此不需要系统输入/输出/错误流)。
但是,这有一个小问题,即当Java程序退出时,直到所有启动的程序都退出后,它才真正退出。
如果启动的程序完全独立于启动它们的JVM,我将更喜欢它。
目标操作系统是多个,最低要求是Windows,Linux和Mac,但是真正需要的是带有JVM的任何GUI系统(因此用户可以配置实际的命令行)。
有谁知道如何使启动的程序完全独立于JVM执行?
编辑以回应评论
启动代码如下。该代码可以启动位于特定行和列的编辑器,也可以启动档案查看器。在配置的命令行中,将引号值视为ECMA-262编码,然后对其进行解码,并去除引号以形成所需的exec参数。
启动发生在EDT上。
static Throwable launch(String cmd, File fil, int lin, int col) throws Throwable {
String frs[][]={
{ "$FILE$" ,fil.getAbsolutePath().replace('\\','/') },
{ "$LINE$" ,(lin>0 ? Integer.toString(lin) : "") },
{ "$COLUMN$",(col>0 ? Integer.toString(col) : "") },
};
String[] arr; // array of parsed tokens (exec(cmd) does not handle quoted values)
cmd=TextUtil.replace(cmd,frs,true,"$$","$");
arr=(String[])ArrayUtil.removeNulls(TextUtil.stringComponents(cmd,' ',-1,true,true,true));
for(int xa=0; xa<arr.length; xa++) {
if(TextUtil.isQuoted(arr[xa],true)) {
arr[xa]=TextDecode.ecma262(TextUtil.stripQuotes(arr[xa]));
}
}
log.println("Launching: "+cmd);
Runtime.getRuntime().exec(arr);
return null;
}
仅当从我的IDE启动该程序时,这似乎才发生。由于问题仅存在于我的开发环境中,因此我将结束这个问题。在生产中这不是问题。根据测试程序的答案之一,以及我进行的进一步测试,我很满意,这个问题不会在任何平台上被该程序的任何用户看到。
如果你发布一个重现问题所需的最少代码的测试部分,则可能会有所帮助。我在Windows和Linux系统上测试了以下代码。
public class Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws Exception {
Runtime.getRuntime().exec(args[0]);
}
}
并在Linux上进行了以下测试:
java -jar JustForTesting.jar /home/monceaux/Desktop/__TMP/test.sh
test.sh如下所示:
#!/bin/bash
ping -i 20 localhost
在Linux上也是如此:
java -jar JustForTesting.jar gedit
并在Windows上对此进行了测试:
java -jar JustForTesting.jar notepad.exe
所有这些都启动了预期的程序,但是Java应用程序没有问题。我报告了以下版本的Sun JVM java -version:
我还没有机会在Mac上进行测试。可能与你项目中的其他代码发生了一些交互作用,可能还不清楚。你可能需要尝试此测试应用程序,然后查看结果。
问题内容: 我正在尝试从python启动一个完全独立的进程。我不能使用像os.startfile这样的简单内容,因为我需要传递参数。目前,我正在使用subprocess.popen,它可以让我90%地到达那里。 将带有分离的创建标志和管道的popen用于std *确实会启动一个新进程,该进程在父进程死后仍然存在。这样就很好。问题在于,新的“子级”进程仍然为父级保留一个幻像句柄。因此,如果我尝试卸载
问题内容: 使用Java计时器,然后切换到ScheduledExecutorService,但我的问题未解决。由于系统时间更改之前安排的任务(通过ntpd)不会按指定的延迟执行。没有日志,什么也没有发生:(。 在64位Linux上的目标中使用jre 1.6.0_26 64位。 更新: ScheduledExecutorService在Windows上运行正常。问题仅存在于运行64位JVM的基于64
我正在使用Intellij IDEA 14.1,并试图调试最基本的独立Spring Boot 1.2.5应用程序。有人能告诉我怎么做吗? 我读过http://docs.spring.io/autorepo/docs/spring-boot/1.2.5.RELEASE/maven-plugin/usage.html但并没有成功地使其发挥作用。最简单的方法是禁用Spring Boot在调试时使用的分叉
我使用的是p=运行时。getRuntime()。exec(“myScript.sh”);作为按钮a的addActionListener(new ActionListener())的actionPerformed(ActionEvent evt)的一部分。 我想有一个方法来终止进程。我试图创建另一个按钮(按钮B)来调用p.destroy()。但是,看起来在单击按钮A后,它启动了进程,并且只有在进程完
我创建了以下示例。但我没有得到预期的结果。下面是我的代码: 1.应用程序.属性 下面是完整的堆栈跟踪:
问题内容: 我正在尝试使用Apache Camel从FTP服务器下载文件并路由文件。但是,很长一段时间内文件仅添加到FTP服务器一次,因此使程序连续运行似乎有些过分热心。相反,我希望有一个cronjob每周运行一次,并处理已添加到服务器的所有新文件。 一旦不再有任何新文件要处理,有什么方法可以让Camel自动关闭? 我当前的功能如下所示: 而有趣的部分是: 问题答案: 请参阅此常见问题解答,了解如