5

我有一个用 Java 编写的服务器,它作为 Windows 服务运行(感谢 Install4J)。我希望这个服务能够下载它运行的 JAR 文件的最新版本,并开始运行新代码。针是我不希望 Windows 服务完全退出。

理想情况下,我会通过 unix 风格的 exec() 调用来停止当前版本并运行新版本来完成此操作。我怎样才能最好地做到这一点?

4

5 回答 5

1

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

我想您可以通过使用 JavaRuntime.execProcessBuilderstart() 命令(启动新进程)然后让当前进程结束来解决它……文档状态

当没有更多对 Process 对象的引用时,子进程不会被终止,而是子进程继续异步执行。

我假设如果父级完成并且被垃圾收集也是如此。

问题是 Runtime.exec 的进程将不再有有效的输入、输出和错误流。

于 2008-10-13T16:29:06.833 回答
1

这是一种复杂但可移植的方式。

将您的代码分成两个罐子。一个非常小的罐子只是用来管理进程启动。它创建一个 ClassLoader,在其类路径中保存另一个 jar。

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

现在,您从一个指向新 jar 的新 ClassLoader 实例重新开始,并重新启动您的应用程序代码。

于 2008-10-13T17:49:08.497 回答
1

Java Service Wrapper可以做到这一点以及更多。

于 2008-10-13T23:51:52.897 回答
0

您可以使用内置的重新加载功能,例如 Tomcat、Jetty 或 JBoss,它们可以作为服务运行,您不必将它们用作 Web 容器或 Java EE 容器。

其他选项是 OSGi,以及您自己的类加载功能。

但请注意在生产环境中重新加载。它并不总是最好的解决方案。

于 2008-10-13T17:55:17.780 回答
-2

一般的做法:

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);
    }
  }
}
于 2008-10-13T16:59:09.033 回答