Docker容器中的Java RMI服务器

在一台服务器上,我正在使用RMI-server jar文件运行我的docker容器。 我已经尝试了几种不同的configuration,但我不能得到它的工作。 我的服务器:

public class Main extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello World from docker in RMI"; public Main() throws RemoteException { super(0); // required to avoid the 'rmic' step, see below } public String getMessage() { return MESSAGE; } public static void main(String args[]) throws Exception { System.out.println("RMI server started"); System.setProperty("java.rmi.server.hostname", "<host-ip-address>"); try { //special exception handler for registry creation LocateRegistry.createRegistry(1099); System.out.println("java RMI registry created."); } catch (RemoteException e) { LocateRegistry.getRegistry(); System.out.println("java RMI registry already exists."); } //Instantiate RmiServer Main obj = new Main(); // Bind this object instance to the name "RmiServer" Naming.rebind("RmiServer", obj); System.out.println("PeerServer bound in registry"); } 

}

我的客户:

 public class Main { public Main() { } public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException { RmiServerIntf obj = (RmiServerIntf) Naming.lookup("rmi://<my-host-address>:4023/RmiServer"); System.out.println(obj.getMessage()); } 

}

他们都分享“RmiServerIntf”

我的Dockerfile:

 FROM ubuntu:latest 

运行echo“更新ubuntu映像”运行apt-get update && apt-get install -y \ openjdk-8-jre EXPOSE 1099 COPY RMIServer.jar /home/RMIServer.jar CMD [“java”,“-jar”,“/家用/ RMIServer.jar“]

(对不起,它不会格式化)

我启动我的容器:docker run –name rmitest -d -p 4023:1099 rmitestimage

客户抛出我:

 Exception in thread "main" java.rmi.ConnectException: Connection refused to host: <my-host-address>; nested exception is: java.net.ConnectException: Connection refused (Connection refused) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227) at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179) at com.sun.proxy.$Proxy0.getMessage(Unknown Source) at com.company.Main.main(Main.java:19) 

如果您从同一个JVM的同一个端口上导出registry和远程对象,您将克服端口问题。 您不需要使用套接字工厂。

 static Registry registry; // ... registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT); // ... public Main() throws RemoteException { super(Registry.REGISTRY_PORT); // ... } // .... Main main = new Main(); registry.rebind("RmiServer", main); 

据我所知,rmi只使用rmiregistry-port来初始化连接,而实际的数据传输是在随机端口上进行的。

因为docker只允许连接到你明确链接到主机的端口,所以RMI服务器端的初始化正在发生,但方法调用的实际数据传输是“阻塞的”。 这个问题应该可以通过定制的RMI套接字工厂来克服。 如果我成功了,将会回答。