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
扩展了 Remote
,ISessionToken
是 Serializeable
。
我有三个项目: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?
你没有导出它。
我的 RMI 客户端有问题 class 加载行为:
我的 RMI 服务器端应用程序使用单一方法导出一个 ISessionFactory
对象:
ISessionToken createSession(String username, String password) throw RemoteException;
ISessionFactory
扩展了 Remote
,ISessionToken
是 Serializeable
。
我有三个项目: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?
你没有导出它。