我遇到了RMI客户端类加载行为的问题:
我的RMI服务器端应用程序使用单个方法导出ISessionFactory
对象:
ISessionToken createSession(String username, String password) throw RemoteException;
ISessionFactory
延伸Remote
,ISessionToken
为Serializeable
。
我有三个项目:客户端,服务器(包含*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$2.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
,它将被序列化并传递给客户端,因此我必须验证传递给服务器的每个会话令牌。
我不明白的是客户感觉需要加载令牌的Impl类。据我所知,它应该通过了解界面做得很好?我错过了什么?
答案 0 :(得分:1)
据我所知,如果不导出ISessionToken,它将被序列化并传递给客户端。
正确。
我不明白的是客户感觉需要加载令牌的Impl类。
因为您没有将其导出,所以它将被序列化并传递给客户端。你自己就这么说了。
就我而言,通过了解界面应该可以做得很好吗?
仅在您导出时。即使这样,客户端实际上也会收到实现接口的存根。你不能只是在没有实现它的东西的情况下发送一个接口。
我错过了什么?
您没有将其导出。