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)