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

时间:2015-02-15 21:12:40

标签: java rmi rpc

我遇到了RMI客户端类加载行为的问题:

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

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

ISessionFactory延伸RemoteISessionTokenSerializeable

我有三个项目:客户端,服务器(包含*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类。据我所知,它应该通过了解界面做得很好?我错过了什么?

1 个答案:

答案 0 :(得分:1)

  

据我所知,如果不导出ISessionToken,它将被序列化并传递给客户端。

正确。

  

我不明白的是客户感觉需要加载令牌的Impl类。

因为您没有将其导出,所以它将被序列化并传递给客户端。你自己就这么说了。

  

就我而言,通过了解界面应该可以做得很好吗?

仅在您导出时。即使这样,客户端实际上也会收到实现接口的存根。你不能只是在没有实现它的东西的情况下发送一个接口。

  

我错过了什么?

您没有将其导出。