WebLogic, SimpleRemoteStatelessSessionProxyFactoryBean, and InitialContext
I am using the SimpleRemoteStatelessSessionProxyFactoryBean to access a remote EJB on a WebLogic server. The server is setup to require authentication. I have found that the server is setup in such a way that not only does the EJBHome lookup require execution "inside" the context (i.e. with the context open and active in the current thread), but also the create, method invocation and remove calls also require execution "inside" the context.
However, looking through the Spring 1.2.5 classes, it appears that the only method that is called inside the context is the EJB home lookup. Once the home is looked up, the context is not used again. This means that the create call, invoke, and remove call all fail, giving the exception:
java.lang.SecurityException: Authentication for user weblogic denied in realm wl_realm
(note that the user defaults back to "weblogic" rather than using the value from the context)
For now I have worked around this by extending SimpleRemoteStatelessSessionProxyFactoryBean as follows:
Code:
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean;
import org.springframework.jndi.JndiCallback;
import javax.ejb.EJBObject;
import javax.naming.Context;
import javax.naming.NamingException;
import java.lang.reflect.InvocationTargetException;
/**
* The Spring classes do not seem to execute the create, invoke, and remove methods inside the scope of an InitialContext,
* which is unfortunately required by WebLogic to properly pass authentication information. This class overrides the normal
* create, invoke, and remove methods to run inside the scope of an initial context.
*/
public class WebLogicSimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteStatelessSessionProxyFactoryBean {
protected Object create() throws NamingException, InvocationTargetException {
try {
return getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(Context context) throws NamingException {
try {
return WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.create();
} catch (InvocationTargetException ite) {
throw new RuntimeException(ite);
}
}
});
} catch (RuntimeException re) {
throw (InvocationTargetException)re.getCause();
}
}
protected void removeSessionBeanInstance(final EJBObject ejbObject) {
try {
getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(Context context) throws NamingException {
WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.removeSessionBeanInstance(ejbObject);
return null;
}
});
} catch (NamingException e) {
throw new RuntimeException(e);
}
}
protected Object doInvoke(final MethodInvocation methodInvocation) throws Throwable {
try {
return getJndiTemplate().execute(new JndiCallback() {
public Object doInContext(Context context) throws NamingException {
try {
return WebLogicSimpleRemoteStatelessSessionProxyFactoryBean.super.doInvoke(methodInvocation);
} catch (Throwable t) {
if(t instanceof NamingException) {
throw (NamingException)t;
} else {
throw new RuntimeException(t);
}
}
}
});
} catch (RuntimeException re) {
throw re.getCause();
}
}
}
Since the overrides use the jndiTemplate to execute the super method inside the callback, this resolves the issue.
However, this is kind of messy and I can't believe other WebLogic users have not run into this. Is there a better solution? Would anyone like to see a Spring issue created for this?
Cheers,
Raman Gupta
WL 9.1 and user <anonymous>
I had the same problem and this worked like a champ. Thanks for the fix :). Any chance this will be in a future Spring release?
Franz
Security Exception - Second Time
I am new to Spring and any help will be greatly appreciated.
I am using Spring 2.0 (in Weblogic 9.2)and I talk to a WebLogic 8.1 remote server. When I use SimpleRemoteStatelessSessionProxyFactoryBean in the config file it works fine the first time (after restarting the WebLogic 9.2). But when I make any more calls to the EJB the second time I get the following error:
java.lang.SecurityException: [Security:090398]Invalid Subject: principals=[weblogic, Administrators]
at weblogic.rjvm.ResponseImpl.unmarshalReturn(Respons eImpl.java:195)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(C lusterableRemoteRef.java:338)
at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(C lusterableRemoteRef.java:252)
at com.tcs.business.tad.ejb.searches.businessSearchMa nagerEJB_mv5wg5_HomeImpl_814_WLStub.create(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.ejb.access.AbstractSlsbInvoker Interceptor.create(AbstractSlsbInvokerInterceptor. java:177)
at org.springframework.ejb.access.AbstractRemoteSlsbI nvokerInterceptor.newSessionBeanInstance(AbstractR emoteSlsbInvokerInter
ceptor.java:205)
at org.springframework.ejb.access.SimpleRemoteSlsbInv okerInterceptor.getSessionBeanInstance(SimpleRemot eSlsbInvokerIntercept
or.java:108)
at org.springframework.ejb.access.SimpleRemoteSlsbInv okerInterceptor.doInvoke(SimpleRemoteSlsbInvokerIn terceptor.java:74)
at org.springframework.ejb.access.AbstractRemoteSlsbI nvokerInterceptor.invoke(AbstractRemoteSlsbInvoker Interceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :176)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:210)
at $Proxy102.executeString(Unknown Source)
:
:
:
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.remoting.rmi.RmiClientIntercep torUtils.doInvoke(RmiClientInterceptorUtils.java:1 03)
at org.springframework.ejb.access.SimpleRemoteSlsbInv okerInterceptor.doInvoke(SimpleRemoteSlsbInvokerIn terceptor.java:75)
at org.springframework.ejb.access.AbstractRemoteSlsbI nvokerInterceptor.invoke(AbstractRemoteSlsbInvoker Interceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :176)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:210)
at $Proxy33.handle(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.aop.support.AopUtils.invokeJoi npointUsingReflection(AopUtils.java:281)
at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:199)
at $Proxy33.handle(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.xfire.service.invoker.AbstractInvoker .invoke(AbstractInvoker.java:54)
at org.codehaus.xfire.service.binding.ServiceInvocati onHandler.sendMessage(ServiceInvocationHandler.jav a:271)
at org.codehaus.xfire.service.binding.ServiceInvocati onHandler$1.run(ServiceInvocationHandler.java:84)
at org.codehaus.xfire.service.binding.ServiceInvocati onHandler.execute(ServiceInvocationHandler.java:13 2)
at org.codehaus.xfire.service.binding.ServiceInvocati onHandler.invoke(ServiceInvocationHandler.java:107 )
at org.codehaus.xfire.handler.HandlerPipeline.invoke( HandlerPipeline.java:131)
at org.codehaus.xfire.transport.DefaultEndpoint.onRec eive(DefaultEndpoint.java:64)
at org.codehaus.xfire.transport.AbstractChannel.recei ve(AbstractChannel.java:38)
at org.codehaus.xfire.transport.http.XFireServletCont roller.invoke(XFireServletController.java:301)
at org.codehaus.xfire.transport.http.XFireServletCont roller.doService(XFireServletController.java:130)
at org.codehaus.xfire.spring.remoting.XFireServletCon trollerAdapter.handleRequest(XFireServletControlle rAdapter.java:67)
at org.codehaus.xfire.spring.remoting.XFireExporter.h andleRequest(XFireExporter.java:48)
at org.springframework.web.servlet.mvc.SimpleControll erHandlerAdapter.handle(SimpleControllerHandlerAda pter.java:45)
at org.springframework.web.servlet.DispatcherServlet. doDispatch(DispatcherServlet.java:820)
at org.springframework.web.servlet.DispatcherServlet. doService(DispatcherServlet.java:755)
at org.springframework.web.servlet.FrameworkServlet.p rocessRequest(FrameworkServlet.java:396)
at org.springframework.web.servlet.FrameworkServlet.d oPost(FrameworkServlet.java:360)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet .java:856)
at weblogic.servlet.internal.StubSecurityHelper$Servl etServiceAction.run(StubSecurityHelper.java:223)
at weblogic.servlet.internal.StubSecurityHelper.invok eServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute( ServletStubImpl.java:283)
at weblogic.servlet.internal.ServletStubImpl.execute( ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$Ser vletInvocationAction.run(WebAppServletContext.java :3245)
at weblogic.security.acl.internal.AuthenticatedSubjec t.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(Se curityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.sec uredExecute(WebAppServletContext.java:2003)
at weblogic.servlet.internal.WebAppServletContext.exe cute(WebAppServletContext.java:1909)
at weblogic.servlet.internal.ServletRequestImpl.run(S ervletRequestImpl.java:1359)
at weblogic.work.ExecuteThread.execute(ExecuteThread. java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java :181)
When I used the WebLogicSimpleRemoteStatelessSessionProxyFactoryBe an, I get the following error the first time itself:
org.springframework.remoting.RemoteAccessException : Cannot access remote service [com.tcs.dataingest.export.datacontroller.Expo
rtControllerSessionHome]; nested exception is java.rmi.RemoteException: Error in ejbCreate:; nested exception is:
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'tadAccess' defined in class path res
ource [tadaccess-context.xml]: Cannot resolve reference to bean 'businessDataManager' while setting bean property 'businessDataManag
er'; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'businessDataManager
' defined in class path resource [tadaccess-context.xml]: Error setting property values; nested exception is org.springframework.bea
ns.NotWritablePropertyException: Invalid property 'jndiName' of bean class [com.tcs.spring.ejb.access.WebLogicSimpleRemoteStat e
lessSessionProxyFactoryBean]: Bean property 'jndiName' is not writable or has an invalid setter method. Does the parameter type of t
he setter match the return type of the getter?
Caused by:
java.rmi.RemoteException: Error in ejbCreate:; nested exception is:
org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'tadAccess' defined in class path res
ource [tadaccess-context.xml]: Cannot resolve reference to bean 'businessDataManager' while setting bean property 'businessDataManag
er'; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'businessDataManager
' defined in class path resource [tadaccess-context.xml]: Error setting property values; nested exception is org.springframework.bea
ns.NotWritablePropertyException: Invalid property 'jndiName' of bean class [com.tcs.spring.ejb.access.WebLogicSimpleRemoteStat e
lessSessionProxyFactoryBean]: Bean property 'jndiName' is not writable or has an invalid setter method. Does the parameter type of t
he setter match the return type of the getter?
at weblogic.ejb.container.internal.EJBRuntimeUtils.th rowRemoteException(EJBRuntimeUtils.java:95)
at weblogic.ejb.container.internal.BaseEJBObject.hand leSystemException(BaseEJBObject.java:713)
at weblogic.ejb.container.internal.BaseEJBObject.hand leSystemException(BaseEJBObject.java:681)
at weblogic.ejb.container.internal.BaseEJBObject.preI nvoke(BaseEJBObject.java:220)
at weblogic.ejb.container.internal.StatelessEJBObject .preInvoke(StatelessEJBObject.java:64)
If anyone can throw some light on this it will be great! Thanks in advance!