Geronimo
  1. Geronimo
  2. GERONIMO-3780

MDB unable to access JNDI in ejbPostCreate

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.1, 2.0.2, 2.1
    • Fix Version/s: 2.0.3, 2.1.1, 2.2
    • Component/s: OpenEJB
    • Security Level: public (Regular issues)
    • Labels:
      None
    • Environment:

      All

    • Patch Info:
      Patch Available

      Description

      An MDB is unable to access JNDI in ejbPostCreate if there are messages in the queue to which it is listening during server startup, say after a server crash

      1. G3780-r628632.patch
        2 kB
        Manu T George
      2. G3780-r628632.patch
        2 kB
        Manu T George

        Activity

        Hide
        Manu T George added a comment -

        This error occurs with the following stacktrace

        14:17:43,562 ERROR [OpenEJB] The bean instance threw a system exception:java.la
        g.NullPointerException
        java.lang.NullPointerException
        at org.apache.xbean.naming.context.ContextFlyweight.lookup(ContextFlywe
        ght.java:44)
        at org.apache.xbean.naming.context.ContextFederation.getFederatedBindin
        (ContextFederation.java:71)
        at org.apache.xbean.naming.context.AbstractFederatedContext.getBinding(
        bstractFederatedContext.java:63)
        at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte
        t.java:129)
        at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte
        t.java:611)
        at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte
        t.java:152)
        at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte
        t.java:597)
        at javax.naming.InitialContext.lookup(InitialContext.java:351)
        at com.mxi.mx.common.geronimo.ejb.DummyMessageDrivenBean.ejbCreate(Dumm
        MessageDrivenBean.java:38)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl
        java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcce
        sorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invo
        ation.invoke(ReflectionInvocationContext.java:146)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proc
        ed(ReflectionInvocationContext.java:129)
        at org.apache.openejb.core.interceptor.InterceptorStack.invoke(Intercep
        orStack.java:67)
        at org.apache.openejb.core.mdb.MdbInstanceFactory.constructBean(MdbInst
        nceFactory.java:249)
        at org.apache.openejb.core.mdb.MdbInstanceFactory.createInstance(MdbIns
        anceFactory.java:117)
        at org.apache.openejb.core.mdb.EndpointHandler.<init>(EndpointHandler.j
        va:79)
        at org.apache.openejb.core.mdb.EndpointFactory.createEndpoint(EndpointF
        ctory.java:68)
        at org.apache.activemq.ra.ServerSessionPoolImpl.createEndpoint(ServerSe
        sionPoolImpl.java:90)
        at org.apache.activemq.ra.ServerSessionPoolImpl.createServerSessionImpl
        ServerSessionPoolImpl.java:76)
        at org.apache.activemq.ra.ServerSessionPoolImpl.getServerSession(Server
        essionPoolImpl.java:116)
        at org.apache.activemq.ActiveMQConnectionConsumer.dispatch(ActiveMQConn
        ctionConsumer.java:136)
        at org.apache.activemq.ActiveMQConnection.onCommand(ActiveMQConnection.
        ava:1479)
        at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseC
        rrelator.java:95)
        at org.apache.activemq.transport.TransportFilter.onCommand(TransportFil
        er.java:65)
        at org.apache.activemq.transport.vm.VMTransport.syncOneWay(VMTransport.
        ava:96)
        at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java
        83)
        at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.j
        va:47)
        at org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorr
        lator.java:60)
        at org.apache.activemq.broker.TransportConnection.dispatch(TransportCon
        ection.java:1138)
        at org.apache.activemq.broker.TransportConnection.processDispatch(Trans
        ortConnection.java:805)
        at org.apache.activemq.broker.TransportConnection.dispatchSync(Transpor
        Connection.java:770)
        at org.apache.activemq.broker.region.PrefetchSubscription.dispatch(Pref
        tchSubscription.java:404)
        at org.apache.activemq.broker.region.QueueSubscription.dispatch(QueueSu
        scription.java:172)
        at org.apache.activemq.broker.region.PrefetchSubscription.add(PrefetchS
        bscription.java:129)
        at org.apache.activemq.broker.region.Queue.addSubscription(Queue.java:1
        1)
        at org.apache.activemq.broker.region.AbstractRegion.addConsumer(Abstrac
        Region.java:233)
        at org.apache.activemq.broker.region.RegionBroker.addConsumer(RegionBro
        er.java:337)
        at org.apache.activemq.broker.BrokerFilter.addConsumer(BrokerFilter.jav
        :86)
        at org.apache.activemq.advisory.AdvisoryBroker.addConsumer(AdvisoryBrok
        r.java:78)
        at org.apache.activemq.broker.BrokerFilter.addConsumer(BrokerFilter.jav
        :86)
        at org.apache.activemq.broker.MutableBrokerFilter.addConsumer(MutableBr
        kerFilter.java:96)
        at org.apache.activemq.broker.TransportConnection.processAddConsumer(Tr
        nsportConnection.java:586)
        at org.apache.activemq.command.ConsumerInfo.visit(ConsumerInfo.java:313

        at org.apache.activemq.broker.TransportConnection.service(TransportConn
        ction.java:294)
        at org.apache.activemq.broker.TransportConnection$1.onCommand(Transport
        onnection.java:185)
        at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseC
        rrelator.java:95)
        at org.apache.activemq.transport.TransportFilter.onCommand(TransportFil
        er.java:65)
        at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.jav
        :201)
        at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner
        java:117)
        at org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRun
        er.java:26)
        at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.j
        va:44)
        at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wo
        ker.runTask(ThreadPoolExecutor.java:665)
        at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wo
        ker.run(ThreadPoolExecutor.java:690)
        at java.lang.Thread.run(Thread.java:595)

        The reason for this is that EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class); return ejbDeployment as null in the GeronimoThreadContextListener. The reason for this being that
        EjbDeployment is set in the CoreDeploymentInfo in the start() method of EjbDeployment which is called by the EjbDeploymentGbean in the main thread. However before this thread does this the VMTransport thread starts accepting messages from the queue and creates Mdb instances which then throw the exception given above

        To replicate this error create an mdb and do a resource lookup in the ejbPostCreate. Put a large no of messages in the queue that the mdb listens on and kill the server before all the messages are processed.
        Restart the server to get the error. This is a timing error so you may need to do it many times before it can be reproduced.

        Show
        Manu T George added a comment - This error occurs with the following stacktrace 14:17:43,562 ERROR [OpenEJB] The bean instance threw a system exception:java.la g.NullPointerException java.lang.NullPointerException at org.apache.xbean.naming.context.ContextFlyweight.lookup(ContextFlywe ght.java:44) at org.apache.xbean.naming.context.ContextFederation.getFederatedBindin (ContextFederation.java:71) at org.apache.xbean.naming.context.AbstractFederatedContext.getBinding( bstractFederatedContext.java:63) at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte t.java:129) at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte t.java:611) at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte t.java:152) at org.apache.xbean.naming.context.AbstractContext.lookup(AbstractConte t.java:597) at javax.naming.InitialContext.lookup(InitialContext.java:351) at com.mxi.mx.common.geronimo.ejb.DummyMessageDrivenBean.ejbCreate(Dumm MessageDrivenBean.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcce sorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invo ation.invoke(ReflectionInvocationContext.java:146) at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proc ed(ReflectionInvocationContext.java:129) at org.apache.openejb.core.interceptor.InterceptorStack.invoke(Intercep orStack.java:67) at org.apache.openejb.core.mdb.MdbInstanceFactory.constructBean(MdbInst nceFactory.java:249) at org.apache.openejb.core.mdb.MdbInstanceFactory.createInstance(MdbIns anceFactory.java:117) at org.apache.openejb.core.mdb.EndpointHandler.<init>(EndpointHandler.j va:79) at org.apache.openejb.core.mdb.EndpointFactory.createEndpoint(EndpointF ctory.java:68) at org.apache.activemq.ra.ServerSessionPoolImpl.createEndpoint(ServerSe sionPoolImpl.java:90) at org.apache.activemq.ra.ServerSessionPoolImpl.createServerSessionImpl ServerSessionPoolImpl.java:76) at org.apache.activemq.ra.ServerSessionPoolImpl.getServerSession(Server essionPoolImpl.java:116) at org.apache.activemq.ActiveMQConnectionConsumer.dispatch(ActiveMQConn ctionConsumer.java:136) at org.apache.activemq.ActiveMQConnection.onCommand(ActiveMQConnection. ava:1479) at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseC rrelator.java:95) at org.apache.activemq.transport.TransportFilter.onCommand(TransportFil er.java:65) at org.apache.activemq.transport.vm.VMTransport.syncOneWay(VMTransport. ava:96) at org.apache.activemq.transport.vm.VMTransport.oneway(VMTransport.java 83) at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.j va:47) at org.apache.activemq.transport.ResponseCorrelator.oneway(ResponseCorr lator.java:60) at org.apache.activemq.broker.TransportConnection.dispatch(TransportCon ection.java:1138) at org.apache.activemq.broker.TransportConnection.processDispatch(Trans ortConnection.java:805) at org.apache.activemq.broker.TransportConnection.dispatchSync(Transpor Connection.java:770) at org.apache.activemq.broker.region.PrefetchSubscription.dispatch(Pref tchSubscription.java:404) at org.apache.activemq.broker.region.QueueSubscription.dispatch(QueueSu scription.java:172) at org.apache.activemq.broker.region.PrefetchSubscription.add(PrefetchS bscription.java:129) at org.apache.activemq.broker.region.Queue.addSubscription(Queue.java:1 1) at org.apache.activemq.broker.region.AbstractRegion.addConsumer(Abstrac Region.java:233) at org.apache.activemq.broker.region.RegionBroker.addConsumer(RegionBro er.java:337) at org.apache.activemq.broker.BrokerFilter.addConsumer(BrokerFilter.jav :86) at org.apache.activemq.advisory.AdvisoryBroker.addConsumer(AdvisoryBrok r.java:78) at org.apache.activemq.broker.BrokerFilter.addConsumer(BrokerFilter.jav :86) at org.apache.activemq.broker.MutableBrokerFilter.addConsumer(MutableBr kerFilter.java:96) at org.apache.activemq.broker.TransportConnection.processAddConsumer(Tr nsportConnection.java:586) at org.apache.activemq.command.ConsumerInfo.visit(ConsumerInfo.java:313 at org.apache.activemq.broker.TransportConnection.service(TransportConn ction.java:294) at org.apache.activemq.broker.TransportConnection$1.onCommand(Transport onnection.java:185) at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseC rrelator.java:95) at org.apache.activemq.transport.TransportFilter.onCommand(TransportFil er.java:65) at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.jav :201) at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner java:117) at org.apache.activemq.thread.PooledTaskRunner.access$100(PooledTaskRun er.java:26) at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.j va:44) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wo ker.runTask(ThreadPoolExecutor.java:665) at edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor$Wo ker.run(ThreadPoolExecutor.java:690) at java.lang.Thread.run(Thread.java:595) The reason for this is that EjbDeployment ejbDeployment = deploymentInfo.get(EjbDeployment.class); return ejbDeployment as null in the GeronimoThreadContextListener. The reason for this being that EjbDeployment is set in the CoreDeploymentInfo in the start() method of EjbDeployment which is called by the EjbDeploymentGbean in the main thread. However before this thread does this the VMTransport thread starts accepting messages from the queue and creates Mdb instances which then throw the exception given above To replicate this error create an mdb and do a resource lookup in the ejbPostCreate. Put a large no of messages in the queue that the mdb listens on and kill the server before all the messages are processed. Restart the server to get the error. This is a timing error so you may need to do it many times before it can be reproduced.
        Hide
        Manu T George added a comment -

        Fix for this issue. This is for the trunk
        https://svn.apache.org/repos/asf/geronimo/server/trunk.

        Show
        Manu T George added a comment - Fix for this issue. This is for the trunk https://svn.apache.org/repos/asf/geronimo/server/trunk .
        Hide
        Jarek Gawor added a comment -

        If I'm understanding the code correctly, there is a chance with this patch where the notifyAll() is called before another thread enters wait() and therefore that thread will block until another notifyAll() is called.
        Assume thread A gets suspended just before executing "deploymentInfo.set(EjbDeployment.class, this);" line and thread B gets suspended right after executing "if (deploymentInfo.get(EjbDeployment.class) == null ){" line. Now, A gets awaken and it finishes executing the start() method (and notifyAll() is called) then thread B awakens and continues executing and it enters the wait() method. Since notifyAll() was already called, thread B will just block until some other thread calls notifyAll() (which might not happen for a while or at all).

        Show
        Jarek Gawor added a comment - If I'm understanding the code correctly, there is a chance with this patch where the notifyAll() is called before another thread enters wait() and therefore that thread will block until another notifyAll() is called. Assume thread A gets suspended just before executing "deploymentInfo.set(EjbDeployment.class, this);" line and thread B gets suspended right after executing "if (deploymentInfo.get(EjbDeployment.class) == null ){" line. Now, A gets awaken and it finishes executing the start() method (and notifyAll() is called) then thread B awakens and continues executing and it enters the wait() method. Since notifyAll() was already called, thread B will just block until some other thread calls notifyAll() (which might not happen for a while or at all).
        Hide
        Manu T George added a comment -

        Yes you are right. It eats up threads slowly. . Putting a timeout will solve that but I guess that is not the way to go forward here.
        Will re-look at the issue afresh its a bit dicey to fix since openejb initialises before the gbean does and the gbean requires openejb to be initialized before it starts. Any advise will be appreciated

        Show
        Manu T George added a comment - Yes you are right. It eats up threads slowly. . Putting a timeout will solve that but I guess that is not the way to go forward here. Will re-look at the issue afresh its a bit dicey to fix since openejb initialises before the gbean does and the gbean requires openejb to be initialized before it starts. Any advise will be appreciated
        Hide
        Manu T George added a comment -

        Changing to

        synchronized(deploymentInfo)

        { deploymentInfo.set(EjbDeployment.class, this); deploymentInfo.notifyAll(); }

        and

        //Fix for GERONIMO-3780
        if (deploymentInfo.get(EjbDeployment.class) == null) {
        synchronized (deploymentInfo) {
        if (deploymentInfo.get(EjbDeployment.class) == null) {
        if (!deploymentInfo.isDestroyed()) {
        try

        { deploymentInfo.wait(); }

        catch (InterruptedException e)

        { log.warn("Wait on deploymentInfo interrupted unexpectedly"); }

        }
        }
        }
        }

        Show
        Manu T George added a comment - Changing to synchronized(deploymentInfo) { deploymentInfo.set(EjbDeployment.class, this); deploymentInfo.notifyAll(); } and //Fix for GERONIMO-3780 if (deploymentInfo.get(EjbDeployment.class) == null) { synchronized (deploymentInfo) { if (deploymentInfo.get(EjbDeployment.class) == null) { if (!deploymentInfo.isDestroyed()) { try { deploymentInfo.wait(); } catch (InterruptedException e) { log.warn("Wait on deploymentInfo interrupted unexpectedly"); } } } } }

          People

          • Assignee:
            Donald Woods
            Reporter:
            Manu T George
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development