RMI动态类加载

时间:2017-12-13 13:47:17

标签: java rmi

我正在努力学习RMI。管理启动一个简单的例子,但我无法实现动态加载类。

Hello.java

package com.example;

import java.rmi.Remote; 
import java.rmi.RemoteException;  

public interface Hello extends Remote {
   String greet(String name) throws RemoteException;
}

HelloImpl.java

package com.example;

public class HelloImpl implements Hello {  
   public String greet(String name) {
      System.out.println("Call from " + name);
      return "Hello " + name + "!";
   }  
}

Server.java

package com.example;

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends HelloImpl {
   public Server() {}

   public static void main(String args[]) {
      System.setSecurityManager(new SecurityManager());
      try {
         HelloImpl greeter = new HelloImpl();

         Hello stub = (Hello) UnicastRemoteObject.exportObject(greeter, 0);
         Registry registry = LocateRegistry.getRegistry();
         registry.bind("Hello", stub);

         System.err.println("Server ready");
      } catch (Exception e) {
         System.err.println("Server exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

Client.java

package com.example;

import java.rmi.Naming; 

public class Client {
   private Client() {}

   public static void main(String[] args) {
      System.setSecurityManager(new SecurityManager());
      try {
         Hello stub = (Hello) Naming.lookup("//localhost/Hello");

         System.out.println(stub.greet(args[0]));
      } catch (Exception e) {
         System.err.println("Client exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

rmi.policy

grant {
    permission java.security.AllPermission;
};

我开始使用rmiregistry,web-server并执行java -Djava.security.policy=rmi.policy com.example.Server。当我尝试使用命令

启动客户端应用程序时
java -Djava.rmi.server.codebase=http://localhost:8000/ -Djava.security.policy=rmi.policy com.example.Client Hivemaster

网络服务器获取请求

127.0.0.1 - - [13/Dec/2017 14:06:45] "GET /com/example/Hello.class HTTP/1.1" 200

但程序获得异常

Exception in thread "main" java.lang.NoClassDefFoundError: com/example/Hello
        at com.example.Client.main(Client.java:17)
Caused by: java.lang.ClassNotFoundException: com.example.Hello
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
        at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
        ... 1 more

为什么?

1 个答案:

答案 0 :(得分:0)

如果客户端按名称使用Hello接口,则它必须存在于其类路径中。与编译时相同。

代码库功能适用于从远程接口中提到的派生的类。在这种情况下,根本不需要使用代码库功能:但如果这样做,则需要在发送这些类的实例的JVM上设置codebase属性。