首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RMI绑定问题(从Windows RMI Server到Ubuntu RMI注册表)

RMI绑定问题(从Windows RMI Server到Ubuntu RMI注册表)
EN

Stack Overflow用户
提问于 2010-10-27 07:07:15
回答 2查看 3.5K关注 0票数 1

我有一个RMI服务器,当在localhost上运行时,它正确地绑定到RMI注册表(以证明设置是正确的)。这样做的代码是:

代码语言:javascript
复制
 private void exposeTickHistoryRemoteProvider(TickHistoryRemoteInterface aTickHistoryServer) {
        if (System.getSecurityManager() == null) {
            SecurityManager mySecurityManager = getSecurityManager();
   System.setSecurityManager(mySecurityManager);
        }
  String rmiServerHostname = System.getProperties().getProperty("java.rmi.server.hostname");
  try {
   TickHistoryRemoteInterface stub =
                (TickHistoryRemoteInterface) UnicastRemoteObject.exportObject(aTickHistoryServer, 0);
            Registry registry = LocateRegistry.getRegistry(rmiServerHostname);
            String[] services = registry.list();
            registry.rebind(RMI_SERVICENAME_REUTERS_TICKHISTORY_SERVER, stub);
            log.info(RMI_SERVICENAME_REUTERS_TICKHISTORY_SERVER + " bound");
        } catch (Exception e) {
         log.error(RMI_SERVICENAME_REUTERS_TICKHISTORY_SERVER + " exception:" + e.toString());
            e.printStackTrace();
        }
    }

我的本地主机使用以下版本的Java运行Windows:

代码语言:javascript
复制
C:\eclipse>java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)

现在,我的问题是,我想绑定到运行在另一台机器上的RMIRegistry (运行Ubuntu10.04,使用OpenJDK IcedTea6 1.8.1,java版本1.6.0_18)。

在这台Ubuntu机器上,我的CLASSPATH (回显$CLASSPATH)中没有任何内容,我正在运行OpenJDK RMIRegistry (与与Ubuntu绑定的RMIRegistry相反):

代码语言:javascript
复制
sudo /usr/lib/jvm/java-6-openjdk/jre/bin/rmiregistry &

现在,在上面的代码中,当变量rmiServerHostname是" localhost“而RMIRegistry在我的Windows上运行时,代码将正确工作(Registry代码绑定到RMIRegistry注册表)。然而,当rmiServerHostname是我的远程Ubuntu机器(“神”)时,我会在“重新绑定”调用中抛出以下异常:

代码语言:javascript
复制
 java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
 java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
 java.lang.ClassNotFoundException: com.relative.tickhistory.provider.TickHistoryRemoteInterface
 java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
 java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
 java.lang.ClassNotFoundException: com.relative.tickhistory.provider.TickHistoryRemoteInterface

如果我杀死了RMIRegistry,我会得到一个不同的错误消息(我希望如此):

代码语言:javascript
复制
 java.rmi.ConnectException: Connection refused to host: deity; nested exception is: 
 java.net.ConnectException: Connection refused: connect
 at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
 at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
 at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
 at sun.rmi.server.UnicastRef.newCall(Unknown Source)
 at sun.rmi.registry.RegistryImpl_Stub.list(Unknown Source)

我假设RMIRegistry的这些实现( Java6和Ubuntu OpenJDK 6)之间没有不兼容。但是,我不知道如何找出这件事的真相。特别是因为我知道代码工作正常(在第一个示例,Windows/localhost中)。

迄今取得的进展

非常感谢你的回答。我知道我被rmiServerHostname (运行在本地主机上)和rmiRegistryHostname (运行在‘神’上)搞混了。我已经用以下方法修改了代码,但仍然遇到了同样的问题(请注意"Registry = LocateRegistry.getRegistry(rmiRegistryHostname)"):“行中的更改)

代码语言:javascript
复制
    String rmiServerCodebase = System.getProperties().getProperty("java.rmi.server.codebase");
    String rmiServerHostname = System.getProperties().getProperty("java.rmi.server.hostname");
    String rmiRegistryHostname = "deity";
    System.out.println("rmiServerCodebase=" + rmiServerCodebase + "; rmiServerHostname=" + rmiServerHostname);
    try {
        TickHistoryRemoteInterface stub =
            (TickHistoryRemoteInterface) UnicastRemoteObject.exportObject(aTickHistoryServer, 0);
        Registry registry = LocateRegistry.getRegistry(rmiRegistryHostname);

打印语句的输出是(注意,我的本地主机是'RTPC-16')

代码语言:javascript
复制
"rmiServerCodebase=file:///C:/workspace/DEV/ReutersTickHistoryServer/ReutersTickHistoryInterface.jar; rmiServerHostname=RTPC-16"

该文件确实存在:

代码语言:javascript
复制
C:\>dir c:\workspace\DEV\ReutersTickHistoryServer\ReutersTickHistoryInterface.jar
 Volume in drive C is OS
 Volume Serial Number is 7AEB-A105

 Directory of c:\workspace\DEV\ReutersTickHistoryServer

22/10/2010  12:21 PM             9,467 ReutersTickHistoryInterface.jar
               1 File(s)          9,467 bytes

因此,再一次总结一下:

  • 当RMIRegistry和RMIServer位于同一个物理主机(例如,本地主机)时,此代码可以工作。
  • 当我试图只在一个单独的主机上运行 RMIRegistry进程时(即,RMIRegistry运行在‘神’上,而在本地主机‘RTPC-16’上运行RMIServer时,就会出现问题。)
  • 我将RMI接口代码库("ReutersTickHistoryInterface.jar")捆绑在客户机和服务器上,因此我并不期望RMI需要传输任何类定义- RMI只是在客户机上创建存根类并处理实际的RMI调用。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-10-27 07:36:51

您将得到此异常,因为rmiregistry无法定位远程对象的存根或存根所需的其他类。启动服务器时,需要指定java.rmi.server.codebase属性,将其设置为实现存根的位置。这是必需的,以便能够动态下载存根类到注册表。

有关此属性的详细信息,请参阅使用RMI动态下载代码教程。

票数 -1
EN

Stack Overflow用户

发布于 2010-10-27 08:05:22

此外,您也在滥用java.rmi.server.hostname。这不是为了什么。由于此代码绑定到注册表,而且只有在注册表在同一主机上运行时才能这样做,因此在获得用于绑定或取消绑定的注册表引用时,应该只使用"localhost“。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4030730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档