首页 > 解决方案 > Docker 中的 Java RMI

问题描述

一段时间以来,我一直试图让 Java RMI 应用程序在 docker 中作为测试工作。

当两个组件都在同一台 PC 上时,应用程序可以工作,而“服务器”不在 docker 中。

如何执行已 docker 化的远程方法?

我的客户有一个片段:

Registry registry = LocateRegistry.getRegistry(DOCKER_EXPOSED_PORT);

     // this prints any found registry names
     String[] s = registry.list();
     System.out.println(s[0]);

     CommonInterface stub = (CommonInterface) registry.lookup("RegisteredStub");
     int response = stub.CommonMethod();

还有我的“服务器”:

CommonInterface stub = (CommonInterface) UnicastRemoteObject.exportObject(obj, 2000);

  LocateRegistry.createRegistry(2000);
  Registry registry = LocateRegistry.getRegistry(2000);
  registry.bind("RegisteredStub", stub);

我还System.out.println(Inet4Address.getLocalHost().getHostAddress()); 用来获取两个组件的 IP 地址,它们在本地运行时是相同的,但当服务器按预期位于 docker 中时它们是不同的。

我的客户能够从 docker 容器中“读取”已注册的存根,所以如果我将其重命名为RegisteredStub2then

String[] s = registry.list();
System.out.println(s[0]);

以某种方式打印RegisteredStub2,我的客户可以在 docker 中看到注册表,但无法访问远程方法。

客户端崩溃:java.net.ConnectException:连接超时:连接 java.rmi.ConnectException:连接拒绝主机:DOCKER IP;

int response = stub.CommonMethod();当我从桌面客户端调用远程方法时。

这是我的 docker 文件命令:

EXPOSE 2000
CMD ["./rmiregistry 2000"]
CMD ["./rmid -J-Djava.security.policy=rmid.policy -port 2000"]

谢谢!

标签: javadockerrmi

解决方案


可能为时已晚,但我最近刚刚为大学作业构建了一个多模块 maven 项目并将其 docker 化。

docker-compose.yml应该看起来像这样:

version: '3'
services:
    server:
      build: server
    client:
      build: client
      environment: 
          SERVER_HOST: server
      depends_on:
      - server

你的服务器Dockerfile是这样的:

FROM openjdk:8-jre-alpine
COPY target/server-jar-with-dependencies.jar /server.jar
CMD /usr/bin/java -jar /server.jar

你的客户Dockerfile是这样的:

FROM openjdk:8-jre-alpine
ENV SERVER_HOST=localhost
COPY target/client-jar-with-dependencies.jar /client.jar
CMD /usr/bin/java -jar /client.jar $SERVER_HOST

注意传递给客户端的 $SERVER_HOST 变量,这将允许您在客户端代码中执行以下操作:

Registry registry = LocateRegistry.getRegistry(args[0]);

推荐阅读