Markus Jung created TOMEE-4712:
----------------------------------

             Summary: MDB endpoints are activated before the application's 
other EJBs are started
                 Key: TOMEE-4712
                 URL: https://issues.apache.org/jira/browse/TOMEE-4712
             Project: TomEE
          Issue Type: Bug
            Reporter: Markus Jung


{{Assembler.startEjbs()}} deploys all beans of an application first and starts 
them afterwards. {{MdbContainer.deploy()}} and {{MdbInstanceManager.deploy()}} 
(for {{Pool=true}}) activate the message endpoint right away, so the resource 
adapter can deliver messages during the deploy pass. The other beans of the 
application are not started yet at that point: stateless beans get their 
instance pool in {{StatelessContainer.start()}}, {{@Startup}} singletons are 
initialized in {{SingletonContainer.start()}}.

Messages that are already waiting on the destination (for example because the 
server was stopped with unprocessed messages) are therefore delivered to an MDB 
whose injected stateless bean has no pool yet:

{code}java.lang.NullPointerException: Cannot invoke 
"org.apache.openejb.core.stateless.StatelessInstanceManager$Data.poolPop()" 
because "data" is null
    at 
org.apache.openejb.core.stateless.StatelessInstanceManager.getInstance(StatelessInstanceManager.java:218)
    at 
org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:204)
    ...
    at 
org.apache.openejb.core.mdb.MdbContainer$MdbActivationContext.start(MdbContainer.java:689)
    at org.apache.openejb.core.mdb.MdbContainer.deploy(MdbContainer.java:251)
    at 
org.apache.openejb.assembler.classic.Assembler.startEjbs(Assembler.java:1690)
{code}

It also lets messages reach the application before its {{@Startup}} singletons 
are initialized, which Jakarta Enterprise Beans 4.0 Core, [4.8.1 Singleton 
Session Bean 
Initialization|https://jakarta.ee/specifications/enterprise-beans/4.0/jakarta-enterprise-beans-spec-core-4.0.html#singleton-session-bean-initialization]
 forbids:

bq. The container must initialize all such startup-time singleton session beans 
before any external client requests (that is, client requests originating 
outside of the application) are delivered to any enterprise bean components in 
the application.

Jakarta Connectors 2.1, [14.4.4 Application 
Server|https://jakarta.ee/specifications/connectors/2.1/jakarta-connectors-spec-2.1.html#a2765]
 explicitly allows a resource adapter to deliver during {{endpointActivation}}:

bq. Note, a resource adapter may attempt to deliver messages during the 
endpointActivation method call.

Reported on the [users 
list|https://lists.apache.org/thread/pg3vv6xr9yd19wowj6lg31b4w4w19bnn] against 
TomEE 10.2.0: an MDB with an injected {{@Stateless}} bean logs these NPEs on 
startup while messages from before the shutdown are pending on its topic.

Fix: activate the endpoint in {{start()}} of both MDB containers instead of 
{{deploy()}}. {{Assembler}} sorts MDBs to the end of the start pass, so every 
session bean of the application is started before the first message is 
delivered. {{MdbActiveOnStartup}}/{{DeliveryActive=false}} keep working as 
before.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to