有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaRMI服务器不会从其HTTP代码库服务器动态加载缺少的类

上下文

这是一个使用Java RMI的应用程序,具有:

  • 主机A上的客户端和主机B上的服务器
  • 作为主机A上的HTTP服务器,它保存客户端和服务器使用的所有类的副本
  • RMI注册表是从服务器代码创建的,它共享服务器JVM和类路径

对于服务器和客户端应用程序:

  • java.rmi.server.codebase属性(在代码中)设置为HTTP服务器URL
  • 安全管理器具有适当的策略
  • java.rmi.server.hostname被设置为LAN地址

方法调用:

  • 服务器方法是使用类型为WorkRequest(抽象类)的参数定义的
  • 客户端使用子类WorkRequestSquare调用此方法
  • ^服务器代码中从未提到{}

服务器代码

Object execute(WorkRequest work) throws RemoteException { return work.execute(); }

客户端代码:

try { servant.execute(new WorkRequestSquare(123)); }
catch (RemoteException e) {
    System.out.println("Error while submitting work request:");
    e.printStackTrace();
}

当服务器在类路径中有所有相关的类,并且不需要动态加载时,此代码可以工作

问题

从服务器端的类路径中删除WorkRequestSquare会在客户端引发异常(服务器端不会引发任何异常):

Error while submitting work request:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: WorkRequestSquare
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    ...

WorkRequestSquare由于服务器代码中从未明确提到过,因此它应该是可动态加载的,但这种情况不会发生

旁路

Stuart Marks让我知道属性java.rmi.server.useCodebaseOnly应该设置为false

此属性的默认值已从false更改为truein JDK 7u21useCodebaseOnly设置为true可防止JVM从任何位置动态加载类,使用java.rmi.server.codebase在本地定义的位置除外。这意味着useCodebaseOnlytrue的服务器将忽略客户机JVM在编组WorkRequestSquare参数时设置的代码基值

当服务器上的useCodebaseOnly设置为false并且从服务器类路径中删除WorkRequestSquare类时,服务器现在从HTTP服务器获取类定义。这是一个有效的旁路

问题

由于客户端和服务器的codebase属性值相同,因此仍然存在异常

useCodebaseOnly被默认为true时,服务器JVM应该忽略添加到RMI流中的客户端codebase,但无论如何,它应该使用自己的codebase来检索WorkRequestSquare

无论如何,这应该是成功的,因为客户机和服务器的codebase值是相同的

有人能解释一下那件事吗


共 (1) 个答案

  1. # 1 楼答案

    What is the minimal set of classes that need to be in the classpath?

    在客户端代码中按名称实际使用的类。例如,远程接口、形式参数和结果的类型、远程方法签名中命名的异常类型

    / what are the classes that can be missing in the classpath, provided they are available using the codebase server?

    实现上述类或接口且在客户端代码中不按名称使用的类

    Is there a tool to debug RMI communication (e.g. Eclipse plugin) and avoid using a network sniffer?

    确实有一个eclipse插件,我很多年前就看到了,但我从来没有真正需要过