Java如何持久化进程引用,以便我可以运行process.destroy()

时间:2013-08-14 18:01:33

标签: java processbuilder procrun

我想通过我创建的可执行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()(通过使用arguemnt stop调用main方法)来杀死进程时,我得到一个空指针异常,我假设因为这是jvm的新实例,所以它没有从我打电话start开始就知道这个过程。什么是保持这个过程对象或pid或其他东西的最佳方法,当我去调用stop时,我可以找到并杀死正在运行的webservice(java进程)?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

选项:

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

  • 您可以设计一种方法远程发信号通知其他应用程序 ......即使它们都在同一台机器上运行。这很容易通过一个简单的网络套接字来完成,这是一种非常常见的方法。 (查看Tomcat的启动/停止命令处理示例......虽然它比您需要的更复杂。)总结一下......一旦运行,主程序就会侦听服务器套接字。随后的“停止程序”作为客户端连接到该服务器套接字,以通知它应该停止的主程序。

  • 您可以使用底层操作系统工具来查找和停止该程序。请参阅此答案:How to find and kill running Win-Processes from within Java?。虽然很难跨平台和一般。

虽然您想要做什么以及为什么通过ProcessBuilder将Web服务作为单独的程序执行,但这并不是很清楚。根据您的要求,也许你可以做这样的事情:

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

当然,那会开始你的服务,然后你可以控制-c结束程序。