我正在努力学习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
为什么?
答案 0 :(得分:0)
如果客户端按名称使用Hello
接口,则它必须存在于其类路径中。与编译时相同。
代码库功能适用于从远程接口中提到的派生的类。在这种情况下,根本不需要使用代码库功能:但如果这样做,则需要在发送这些类的实例的JVM上设置codebase属性。