1

我想通过我创建的可执行 jar 启动 web 服务(这样我最终可以使用 procrun 让它作为 Windows 服务启动)。Web 服务当前通过调用类的 main 方法通过命令行启动。

到目前为止,这是我的代码:

public class test 
{    
    private static boolean stop = false;
    private static Process process;

    public static void start(String[] args) 
    {
        String classpath = "my\\classpath\\test.jar";

        ProcessBuilder processBuilder = new ProcessBuilder("C:\\java\\jdk1.6.0_43\\bin\\java", 
                                                           "-cp", classpath, 
                                                           "com.test.theJavaWebServiceWithAMainMethod");
        try
        {
            process = processBuilder.start();
        }
        catch (IOException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

    public static void stop(String[] args)
    {
        stop = true;

        process.destroy();
    }

    public static void main(String[] args)
    {
        if (args != null && args.length > 0)
        {
            String command = args[0];

            if ("start".equals(command))
            {
                start(args);
            }
            else if ("stop".equals(command))
            {
                stop(args);
            }
        }
        else
        {
            throw new IllegalArgumentException("command missing");
        }
    }

}

启动工作正常。我在任务管理器中看到进程启动,我现在可以拉起 WSDL。但是,当我通过process.destroy()(通过调用 main 方法stop)杀死进程时,我得到一个空指针异常,我认为这是因为这是 jvm 的一个新实例,所以它不知道我调用时的进程start。什么是保持这个进程对象或 pid 或其他东西的最佳方法,所以当我去调用停止时,我可以找到并终止正在运行的 web 服务(java 进程)?

4

2 回答 2

0

您可以将程序转换为作为 Windows 服务启动,而不是像您那样启动可运行的 jar。然后它将能够对基于 Windows 的关闭请求作出反应。

于 2013-08-14T18:09:46.543 回答
0

您正在执行两次“测试”程序,这会导致两个完全独立的程序实例,并且它们彼此之间没有引用。因此,当您使用停止命令调用“测试”程序时,该process变量为空,因为未在当前程序中创建变量。

选项:

  • 将你的 main 方法重写为 block,等待“停止”命令。这意味着启动/停止不是单独的异步程序执行。您将启动程序,然后它会在退出之前等待您输入停止命令。

  • 您可以设计一种“远程”向其他应用程序发出信号的方法……即使它们都在同一台机器上运行。这很容易通过一个简单的网络套接字来实现,并且是一种非常常见的方法。(以 Tomcat 的启动/停止命令处理为例……尽管它比您需要的要复杂。)总而言之……一旦运行,主程序就会在服务器套接字上进行侦听。随后的“停止程序”作为客户端连接到该服务器套接字,以通知主程序它应该停止。

  • 您可以使用底层操作系统工具来查找和停止程序。请参阅此答案:如何从 Java 中查找并终止正在运行的 Win-Processes?. 虽然很难跨平台和通用。

不过,目前还不清楚您想要做什么以及为什么要通过 ProcessBuilder 将 Web 服务作为单独的程序执行。根据您的要求,也许您可​​以改为执行以下操作:

public void start(String[] args) 
{
    try
    {
        com.test.theJavaWebServiceWithAMainMethod.main(args);
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }
}

当然,这将启动您的服务,然后您可以 control-c 结束程序。

于 2013-08-14T18:18:12.453 回答