如何从另一个java应用程序运行一个java应用程序并在主程序返回后保持运行?

Posted

技术标签:

【中文标题】如何从另一个java应用程序运行一个java应用程序并在主程序返回后保持运行?【英文标题】:How to run a java application from another java application and keep it running after the master program returns? 【发布时间】:2013-05-12 11:26:21 【问题描述】:

我正在尝试从我的 java 应用程序运行 ApacheDS 实例。 我使用 ScriptWrapper 类的 run() 方法来执行 ApacheDS 附带的脚本来运行它:

public class ScriptWrapper implements Serializable 
    private String scriptPath;

    protected Process run(List<String> params) throws IOException 
        LOGGER.debug("Executing script="+scriptPath);
        params.add(0, scriptPath);

        if(workDir != null) 
            return Runtime.getRuntime().exec(params.toArray(new String[params.size()]), envp.toArray(new String[envp.size()]), new File(workDir));
         else 
            return Runtime.getRuntime().exec(params.toArray(new String[params.size()]));
        
    

但问题是,当运行此应用程序的 tomcat 被终止和/或 ScriptWrapper 被垃圾收集时,ApacheDS 的实例也会终止。如何让它保持活力?

编辑:感谢您的回答。我决定以不同的方式解决这个问题,并使用带有二进制 ApacheDS 安装的脚本来守护进程。

【问题讨论】:

问题已解决,如果是,请分享解决方案。 【参考方案1】:

您的主进程应该在结束之前等待它的子进程。

对象 Process 有一个方法 waitFor()。您可以创建一个新线程,然后运行并等待任何其他进程。

【讨论】:

【参考方案2】:

我想知道通过调用 shell 或 windows 上的命令来执行你的命令会起作用吗?

Runtime.getRuntime().exec( "/bin/bash -c yourCommand yourOptions &" ).waitFor();

Bash &(和号)是一个内置的控制操作符,用于分叉进程。在 Bash 手册页中,“如果命令被控制运算符 & 终止,则 shell 在子 shell 的后台执行命令”。

我不确定 windows 会如何工作,也许试试

Runtime.getRuntime().exec( "command.exe yourCommand yourOptions" ).waitFor();

【讨论】:

【参考方案3】:

从技术上讲,您可以通过持有ScriptWrapper 的引用来防止您的对象被垃圾回收。

您可以使用单例来保存引用。由于您的对象被主动引用,它不会被 GC 收集。

public class ScriptWrapper 
  private static ScriptWrapper uniqueInstance;

  private ScriptWrapper () 
    

  public static synchronized ScriptWrapper getInstance() 
    if (uniqueInstance == null) 
      uniqueInstance = new ScriptWrapper ();
    
    return uniqInstance;
  

  protected Process run(List<String> params) throws IOException 
        LOGGER.debug("Executing script="+scriptPath);
        params.add(0, scriptPath);

      if(workDir != null) 
             return Runtime.getRuntime().exec(params.toArray(new String[params.size()]), envp.toArray(new String[envp.size()]), new File(workDir));
        else 
         return Runtime.getRuntime().exec(params.toArray(new String[params.size()]));
      
  

希望这对你有帮助!

【讨论】:

Java API for Process 说:当没有更多对 Process 对象的引用时,子进程不会被杀死,而是子进程继续异步执行【参考方案4】:

在windows中是这样的

Process p = Runtime.getRuntime().exec( "cmd /c yourCommand yourOptions");

你不需要把p.waitFor()..

【讨论】:

以上是关于如何从另一个java应用程序运行一个java应用程序并在主程序返回后保持运行?的主要内容,如果未能解决你的问题,请参考以下文章

Java:如何从另一个线程启动 UI 对话框,例如对于身份验证器

从另一个节点上的另一个java程序控制java程序

如何从另一个应用程序访问 django 数据库

如何从另一个微服务 Java 使用 JWT 安全微服务

从另一个活动中删除计时器

java中TimerTask 如何才能停止呢