【发布时间】:2018-01-13 23:09:31
【问题描述】:
我正在尝试从here 运行示例
我们有一个远程接口:
package example.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
然后我们有一个服务器:
package example.hello;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
System.out.println("Server started");
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
// Bind the remote object's stub in the registry
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();
}
}
}
然后我们有一个客户,虽然这并不重要,因为目前它不是我想要运行的。 我按照链接中的所有说明进行操作,并想出了这样的结构:
.
├── example
│ └── hello
│ ├── Client.java
│ ├── Hello.java
│ └── Server.java
└── target
└── classes
└── example
└── hello
├── Client.class
├── Hello.class
└── Server.class
在启动服务器之前,我从项目文件夹中运行rmiregistry。然后,要运行我尝试过的服务器,也可以从项目文件夹中运行:
java -cp ./target/classes -Djava.rmi.server.codebase=file:///Users/myself/Desktop/rmi/target/classes/ example.hello.Server
我也尝试了file:/ 和file://,但在所有情况下它都给了我:
Server exception: java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: example.hello.Hello
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: example.hello.Hello
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:421)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:272)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
at example.hello.Server.main(Server.java:26)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: example.hello.Hello
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:411)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:272)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: example.hello.Hello
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1207)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1221)
at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:731)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:674)
at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:611)
at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:265)
at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1566)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
... 15 more
据我所知,它找不到课程,就像我给出了错误的路径。
如果我从target/classes 开始rmiregistry,无论如何,一切正常。
我的问题是,如何使用相对路径设置java.rmi.server.codebase 属性(包括格式),以便可以从不同于类所在的文件夹运行rmiregistry?
【问题讨论】:
-
为什么?如果类存在于本地主机上,为什么不只使用类路径?你正在用锤子敲碎坚果。
-
我只是在重做 RMI 的 Java 介绍中的内容,但理想情况下,客户端和服务器将位于两个不同的主机中。
-
RMI???你看过日历了吗——现在是 2018 年。
-
那么,如果它们将位于两个不同的主机中,为什么要在同一主机上运行它们?为什么你认为你需要使用代码库功能?究竟什么是“RMI 简介”?
-
@AbhijitSarkar 听起来很糟糕吗? :) 我必须以同步的方式分发一些操作,不需要将 API 暴露给外部世界,所以我正在考虑一些想法。我也在考虑 RESTful API 和 gRPC。你有什么建议吗?