Java RMI 客户端尝试加载实现而不是接口

Java RMI client tries to load implementation instead of interface

我的 RMI 客户端有问题 class 加载行为:

我的 RMI 服务器端应用程序使用单一方法导出一个 ISessionFactory 对象:

ISessionToken createSession(String username, String password) throw RemoteException;

ISessionFactory 扩展了 RemoteISessionTokenSerializeable

我有三个项目:Client、Server(包含*Impl)和Facade(包含ISession*)。

服务器启动正常,我可以查找 ISessionFactory。出于测试目的,我添加了一个 doSomething 方法,该方法通过 System.out 在服务器端打印出一个字符串,这也可以正常工作。然而,调用 createSession() 不会,但会给出异常:

Exception in thread "main" java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
java.lang.ClassNotFoundException: rmiserver.SessionTokenImpl (no security manager: RMI class loader disabled)
   at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:198)
   at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
   at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
   at com.sun.proxy.$Proxy0.createSession(Unknown Source)
   at rmiclient.Client.main(Client.java:14)
 Caused by: java.lang.ClassNotFoundException: 
   rmiserver.SessionTokenImpl (no security manager: RMI class loader disabled)
   at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:396)
   at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:186)
   at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:637)
   at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
   at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:214)
   at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1613)
   at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
   at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
   at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
   at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
   at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:326)
   at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:175)
   ... 4 more

我知道如果不导出 ISessionToken 它将被序列化并传递给客户端,所以我必须验证传递给服务器的每个会话令牌。

不明白的是客户端感觉需要加载token的Implclass。就我而言,通过了解界面应该可以做得很好吗?我错过了什么?

I understand that without export of ISessionToken it will be serialized and passed to the client.

正确。

What I don't understand is that the client feels the need to load the Impl class of the token.

因为你没有导出,所以会序列化传给客户端。你自己说的。

As far as I am concerned it should be doing fine by knowing the interface?

仅当您将其导出时。即便如此,客户端实际上会收到一个 实现 接口的存根。你不能只发送一个没有实现它的接口。

What am I missing?

你没有导出它。