Docker容器中的Java RMI服务器
在服务器中,我使用RMI服务器jar文件运行docker容器。 我已经尝试了几种不同的配置,但我就是不能让它工作。 我的服务器端:Docker容器中的Java RMI服务器,java,docker,rmi,dockerfile,Java,Docker,Rmi,Dockerfile,在服务器中,我使用RMI服务器jar文件运行docker容器。 我已经尝试了几种不同的配置,但我就是不能让它工作。 我的服务器端: public class Main extends UnicastRemoteObject implements RmiServerIntf { public static final String MESSAGE = "Hello World from docker in RMI"; public Main() throws Remote
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");
}
我以以下内容开始我的容器:
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)
线程“main”java.rmi.ConnectException中的异常:连接拒绝承载:;嵌套异常是:
java.net.ConnectException:拒绝连接(拒绝连接)
位于sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
位于sun.rmi.transport.tcp.tcpcchannel.createConnection(tcpcchannel.java:216)
位于sun.rmi.transport.tcp.tcpcchannel.newConnection(tcpcchannel.java:202)
位于sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
位于java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
位于java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
位于com.sun.proxy.$Proxy0.getMessage(未知源)
位于com.company.Main.Main(Main.java:19)
据我所知,rmi仅使用rmi注册表端口初始化连接,实际数据传输在随机端口上进行 由于docker只允许连接到显式链接到主机的端口,因此RMI服务器端的初始化正在进行,但方法调用的实际数据传输被“阻止”。
在定制RMI套接字工厂的帮助下,应该可以克服此问题。如果成功,将返回答案。据我所知,rmi仅使用rmi注册表端口初始化连接,而实际的数据传输是在随机端口上进行的 由于docker只允许连接到显式链接到主机的端口,因此RMI服务器端的初始化正在进行,但方法调用的实际数据传输被“阻止”。
在定制RMI套接字工厂的帮助下,应该可以克服此问题。如果我成功,将返回答案。如果从同一JVM导出同一端口上的注册表和远程对象,您将克服端口问题。您不需要使用插座工厂
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);
如果从同一JVM导出同一端口上的注册表和远程对象,您将克服端口问题。您不需要使用插座工厂
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);
成功执行
LocateRegistry.getRegistry()代码>不能证明注册表存在,因为它不执行任何网络操作。如果调用LocateRegistry.createRegistry()
则必须将结果存储到静态变量中代码>不能证明注册表存在,因为它不执行任何网络操作。如果调用LocateRegistry.createRegistry()
,则必须将结果存储到静态变量中。这是不正确的。RMI使用注册表获取存根,并通过连接来实现。然后存根通过同一个或另一个连接与远程对象通信到同一个或另一个端口。这是不正确的。RMI使用注册表获取存根,并通过连接来实现。然后存根通过相同或其他连接与远程对象通信到相同或其他端口。非常感谢。这个答案昨天应该是黄金。最后,我对UnicastRemoteObject.exportObject(obj,端口)进行了更为复杂的解决。但是你的头发看起来干净多了。以后我会试试的。非常感谢。这个答案昨天应该是黄金。最后,我对UnicastRemoteObject.exportObject(obj,端口)进行了更为复杂的解决。但是你的头发看起来干净多了。我以后会试一试的。
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);