代码之家  ›  专栏  ›  技术社区  ›  Hank Gay

如何替换当前的Java进程,如unix风格的exec?

  •  2
  • Hank Gay  · 技术社区  · 17 年前

    理想情况下,我可以通过一个unix风格的exec()调用来停止当前版本并运行新版本来实现这一点。我如何才能最好地完成这一点?

    5 回复  |  直到 17 年前
        1
  •  1
  •   Powerlord    17 年前

    据我所知,在Java中没有办法做到这一点。

    我想您可以使用Java来解决这个问题 Runtime.exec ProcessBuilder 的start()命令(启动新进程),然后让当前的一端。。。文件状态

    没有更多的参考文献 进程对象,而不是 子进程继续执行 异步的。

    捕获是运行时。exec的进程将不再具有有效的in、out和err流。

        2
  •  1
  •   Darron    17 年前

    这是一种复杂但便携的方法。

    将代码拆分为两个jar。有一个非常小的jar用于管理流程启动。它创建一个类加载器,将另一个jar保存在它的类路径上。

    当您想要加载一个新版本时,终止所有运行旧jar代码的线程。从旧jar中删除对类实例的所有引用。清空对加载旧jar的类加载器的所有引用。此时,如果没有遗漏任何内容,则旧类和类加载器应该可以进行垃圾收集。

    现在,使用指向新jar的新类加载器实例重新开始,并重新启动应用程序代码。

        3
  •  1
  •   ddimitrov    17 年前

    Java Service Wrapper 做这个,还有更多。

        4
  •  0
  •   Arjan Tijms Mike Van    13 年前

    其他选项包括OSGi和您自己的类加载功能。

        5
  •  -2
  •   gnud    17 年前

    一般做法:

    import java.io.BufferedInputStream;
    import java.util.Arrays;
    
    public class ProcessSpawner {    
    public static void main(String[] args) {
        //You can change env variables and working directory, and
        //have better control over arguments.
        //See [ProcessBuilder javadocs][1]
        ProcessBuilder builder = new ProcessBuilder("ls", "-l");
    
        try {
            Process p = builder.start();
            //here we just echo stdout from the process to java's stdout.
            //of course, this might not be what you're after.
            BufferedInputStream stream = 
                new BufferedInputStream(p.getInputStream());
            byte[] b = new byte[80];
            while(stream.available() > 0) {                 
                stream.read(b);
                String s = new String(b);
                System.out.print(s);
                Arrays.fill(b, (byte)0);
            }
            //exit with the exit code of the spawned process.
            System.exit(p.waitFor());
    
        } catch(Exception e) {
            System.err.println("Exception: "+e.getMessage());
            System.exit(1);
        }
      }
    }