如何创建一个可以作为窗口服务运行的java应用程序?

时间:2013-05-22 06:52:17

标签: java service rmi

我需要您关于创建可用于作为服务运行的Java应用程序的建议。我正在使用Java服务包装器在Windows中安装和运行它作为服务。 我有2个类ServiceApp.java& RMIService.java。 ServiceApp有main方法,RMIService将是一个运行服务器以接受来自客户端的连接..

现在这是我的问题。从我的main方法,一旦我创建RMIService,主线程将退出并且应用程序停止正确。由于我想阻止主线程将其作为服务运行,因此我创建了一个SocketServer和Socket对象并调用了Socket.accept()。这工作正常,服务正在运行,因为主线程被阻止,但我不相信这是正确的方法。请为我提供正确的方法。这是一段代码:

public class ServiceApp {
    public static void main(String[] args) {
        System.out.println("Starting RMI server");
        {
            RMIService rmiService;
            try {
                rmiService = new RemoteServerService();
                Registry registry = LocateRegistry.createRegistry(1099); 
                registry.rebind("RMIServer", rmiService);
                System.out.println("RMI server running");
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        ServerSocket serverSocket = null;
        Socket socket = null;
        try {
            serverSocket = new ServerSocket( 7000 );
            while ( true )
            {
                socket = serverSocket.accept(); //This will block the main thread

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally
        {
            try {
                if (socket != null)
                    socket.close();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }
    }
}

PS:我在这些问题上搜索了Stackoverflow,但找不到符合我要求的任何问题。

3 个答案:

答案 0 :(得分:2)

导出任何远程对象(包括注册表)时,会创建一个或多个非守护程序侦听器线程以侦听相关端口。这些将阻止进程退出。你不需要做任何进一步的事情,你当然不需要一个毫无意义的ServerSocket.

但是,您确实需要防止导出的远程对象被垃圾回收,这将取消导出它们。您需要对Registry和您自己的远程对象保持静态引用。

答案 1 :(得分:0)

以下是修改后的代码以使其正常工作。感谢EJP的解决方案。

<强> ServiceApp.java

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ServiceApp {
  public static RMIService rmiService;
  public static Registry registry;

    public static void main(String[] args) {
    System.out.println("Starting RMI server");
    {

        try {
            rmiService = new RMIService();
             registry = LocateRegistry.createRegistry(1099); 
            registry.rebind("RMIServer", rmiService);
            System.out.println("RMI server running");
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

  }
}

<强> RMIService.java

import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;



public class RMIService extends UnicastRemoteObject implements IRemoteServerService
{
private static final long serialVersionUID = 1L;


public RMIService() throws RemoteException {
    super();
     // Install a security manager.
    System.setSecurityManager(new RMISecurityManager());

}
public String pingTest()
{
    return "Server says hi";
}
@Override
public boolean resetService() throws RemoteException {
    // TODO Auto-generated method stub
    return false;
}

}

<强> IRemoteServerService

import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRemoteServerService extends Remote {


boolean resetService() throws RemoteException;
String pingTest() throws RemoteException;

}

答案 2 :(得分:-1)

如果我错了,请纠正我,但是当你将RMIService绑定到注册表时,你不需要阻止main,因为rmiservice会被守护进程。所以你只需要阻止主线程。