Classloader problem with SimpleRemoteStatelessSessionProxy
I have the following problem, my remote EJB has one method, with a custom parameter:
void doit(Person aPerson);
If I try to execute this method with the SimpleRemoteStatelessSessionProxyFactoryBean I get the following exception:
[Servlet Error]-[EJBTest]: java.lang.NoSuchMethodException: doit
at java.lang.Class.getMethod0(Native Method)
at java.lang.Class.getMethod(Class.java:928)
at org.springframework.remoting.rmi.RmiClientIntercep torUtils.doInvoke(RmiClientInterceptorUtils.java:1 02)
at org.springframework.ejb.access.SimpleRemoteSlsbInv okerInterceptor.doInvoke(SimpleRemoteSlsbInvokerIn terceptor.java:76)
at org.springframework.ejb.access.AbstractRemoteSlsbI nvokerInterceptor.invoke(AbstractRemoteSlsbInvoker Interceptor.java:78)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :144)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy3.doit(Unknown Source)
at jdbcTest.EJBTest.doGet(EJBTest.java:70)
the setup is the following: Websphere 5.0 Test environment, the EJB is in a separate EAR (EAR 1) and the client
code is in a separate EAR (EAR 2). I CAN call methods which have just simple parameters (like Integer etc.).
I think I figured out what the problem is, Spring does not use PortableRemoteObject.narrow(). It looks like the
narrow method changes the classloader for my stub:
If I just look up the home stub in the jndi tree (as spring does) and do not use the narrow method, then the
classloader for my stub is EAR 1. when I use narrow the classloader for the stub is EAR2 (just try getClass().getClassloader()).
Now if spring tries to find the method doit(Person aPerson) it can't find the method because it compares persons
with different classloaders (i.e. it compares the person from EAR1 with the Person from EAR2).
So it looks like it is a bug in Spring, i.e. that no narrowing of the stub is used. I don't know really how this
can be fixed as the SimpleRemoteStatelessSessionProxyFactoryBean does not know the home class (everything is done via
reflection).
What Spring is implicitly trying to do is the following:
(PersonMgr) mgr = (PersonMgr) initialContext.lookup("java:comp/env/ejb/PersonMgr");
which is not really allowed (direct cast).
Peter