-
Bug
-
Resolution: Obsolete
-
Major
-
JBossAS-4.2.2.GA
-
None
-
None
When changing the identity within a server method (e.g. in a session bean or message-driven bean), the org.jboss.ejb.plugins.SecurityInterceptor causes a login without a corresponding logout ever happening. The result is a memory leak.
In order to trace this problem down, I put some code into my login-module that dumps stack traces of commit() methods having been called without corresponding logout() calls. Here's one example stack trace:
java.lang.Exception: StackTrace
at org.nightlabs.jfire.jboss.authentication.JFireServerLoginModule.commit(JFireServerLoginModule.java:280)
at sun.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:769)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:186)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
at javax.security.auth.login.LoginContext.login(LoginContext.java:580)
at org.jboss.security.plugins.JaasSecurityManager.defaultLogin(JaasSecurityManager.java:603)
at org.jboss.security.plugins.JaasSecurityManager.authenticate(JaasSecurityManager.java:537)
at org.jboss.security.plugins.JaasSecurityManager.isValid(JaasSecurityManager.java:344)
at org.jboss.ejb.plugins.SecurityInterceptor.checkSecurityAssociation(SecurityInterceptor.java:211)
at org.jboss.ejb.plugins.SecurityInterceptor.invokeHome(SecurityInterceptor.java:135)
at org.jboss.ejb.plugins.LogInterceptor.invokeHome(LogInterceptor.java:132)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invokeHome(ProxyFactoryFinderInterceptor.java:107)
at org.jboss.ejb.SessionContainer.internalInvokeHome(SessionContainer.java:637)
at org.jboss.ejb.Container.invoke(Container.java:981)
at org.jboss.ejb.plugins.local.BaseLocalProxyFactory.invokeHome(BaseLocalProxyFactory.java:359)
at org.jboss.ejb.plugins.local.LocalHomeProxy.invoke(LocalHomeProxy.java:133)
at $Proxy97.create(Unknown Source)
at org.nightlabs.jfire.asyncinvoke.AsyncInvokerBaseBean.onMessage(AsyncInvokerBaseBean.java:203)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.invocation.Invocation.performCall(Invocation.java:359)
at org.jboss.ejb.MessageDrivenContainer$ContainerInterceptor.invoke(MessageDrivenContainer.java:495)
at org.nightlabs.jfire.jboss.transaction.ForceRollbackOnExceptionInterceptor.invoke(ForceRollbackOnExceptionInterceptor.java:54)
at org.jboss.resource.connectionmanager.CachedConnectionInterceptor.invoke(CachedConnectionInterceptor.java:158)
at org.jboss.ejb.plugins.MessageDrivenInstanceInterceptor.invoke(MessageDrivenInstanceInterceptor.java:116)
at org.jboss.ejb.plugins.CallValidationInterceptor.invoke(CallValidationInterceptor.java:63)
at org.jboss.ejb.plugins.AbstractTxInterceptor.invokeNext(AbstractTxInterceptor.java:121)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:350)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:181)
at org.jboss.ejb.plugins.RunAsSecurityInterceptor.invoke(RunAsSecurityInterceptor.java:109)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:205)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:138)
at org.jboss.ejb.MessageDrivenContainer.internalInvoke(MessageDrivenContainer.java:402)
at org.jboss.ejb.Container.invoke(Container.java:960)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker.invoke(JMSContainerInvoker.java:987)
at org.jboss.ejb.plugins.jms.JMSContainerInvoker$MessageListenerImpl.onMessage(JMSContainerInvoker.java:1287)
at org.jboss.jms.asf.StdServerSession.onMessage(StdServerSession.java:266)
at org.jboss.mq.SpyMessageConsumer.sessionConsumerProcessMessage(SpyMessageConsumer.java:891)
at org.jboss.mq.SpyMessageConsumer.addMessage(SpyMessageConsumer.java:170)
at org.jboss.mq.SpySession.run(SpySession.java:323)
at org.jboss.jms.asf.StdServerSession.run(StdServerSession.java:194)
at EDU.oswego.cs.dl.util.concurrent.PooledExecutor$Worker.run(PooledExecutor.java:761)
at java.lang.Thread.run(Thread.java:619)
The org.nightlabs.jfire.asyncinvoke.AsyncInvokerBaseBean.onMessage(...) does the following:
1) Create a LoginContext and perform login().
2) Obtain an EJB's LocalHome.
3) Obtain the EJB proxy from the LocalHome.
4) Call the EJB method.
5) logout() - corresponding to step 1.
Here's the source:
loginContext = new LoginContext(
LoginData.DEFAULT_SECURITY_PROTOCOL, createAuthCallbackHandler(ism, envelope));
loginContext.login();
try {
AsyncInvokerDelegateLocal invokerDelegate = null;
try
{ invokerDelegate = AsyncInvokerDelegateUtil.getLocalHome().create(); }catch (Exception x)
{ logger().fatal("Obtaining stateless session bean AsyncInvokerDelegateLocal failed!", x); messageContext.setRollbackOnly(); } if (invokerDelegate != null)
doInvoke(envelope, invokerDelegate);
} finally
{ loginContext.logout(); }In a similar scenario (not the stack trace above), I worked around this problem by manually pushing a RunAsIdentity into the SecurityAssociation (and popping it before logout). When a RunAsIdentity is present, the SecurityInterceptor does not perform a login.