I have two projects (client and server) trying to exchange some objects thru Spring RMI in Eclipse Helios. The client only knows their interfaces. A similar program passing Strings works fine.
I'm following Spring In Action's 3rd edition examples, and instead of Spitter preferred Twitter :) The objects work fine at the server, and no one knows the implementations, just Spring. What is odd is that it throws a ClassNotFoundException, seeming that the client is complaining he doesn't know TwitterImpl!
Thanks in advance for any help!
Stack trace:
Exception in thread "main" org.springframework.remoting.RemoteAccessException: Could not access remote service [rmi://localhost/TwitterService];
nested exception is java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
java.lang.ClassNotFoundException: twitter.domain.TwitterImpl (no security manager: RMI class loader disabled)
at org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(RmiClientInterceptorUtils.java:193)
at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:347)
at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:259)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy1.getTwitter(Unknown Source)
at twitter.Retrieve.getTwits(Retrieve.java:31)
at twitter.Main.main(Main.java:30)
Client rmi.xml
<bean class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
id="twitterService">
<property name="serviceUrl"
value="rmi://localhost/TwitterService">
</property>
<property name="serviceInterface"
value="twitter.service.TwitterService">
</property>
</bean>
<bean id="retrieve" class="twitter.Retrieve">
<property name="twitterService" ref="twitterService"></property>
</bean>
Server rmi.xml
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="service" ref="twitterService" />
<property name="serviceName" value="TwitterService" />
<property name="serviceInterface" value="twitter.service.TwitterService" />
</bean>
<bean class="twitter.service.TwitterServiceImpl" id="twitterService">
<property name="twits">
...
</property>
<property name="twitters">
...
</property>
</bean>
I noobily misunderstood the concept of RMI. I thought the client shouldn't even know the class implementation, receiving the bytecodes from the server. In fact, the aim of remoting is accessing a remote object's state, and the client needs to know the implementation. Throwing a ClassNotFound exception is no surprise.