我需要您关于创建可用于作为服务运行的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,但找不到符合我要求的任何问题。
答案 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会被守护进程。所以你只需要阻止主线程。