0

I have learned a lot about EJB3.1 lately, but apparently not enough. Here's my tale of woe...

I have a war with servlet to which batch files can be uploaded. The servlet validates the file, stores the file data in a database and sends a message to queue that a new batch has been received. This all works fine.

I have an ear with an ejb-jar deployed which has an MDB that listens for the new batch received messages.

It also has a stateful EJB (using the no-interface view) that does the actual batch processing. The EJB has references to stateless JPA entity service beans and therefore needs to be container managed to get container injected EntityManagers.

I need to create an instance of the stateful processor bean whenever a message is received by the MDB. I haven't been able to find any examples/tutorials which cover this scenario.

I have tried injecting the stateful bean into the MDB, but it doesn't work:

[#|2011-11-24T13:25:45.470-0700|SEVERE|glassfish3.1.1|javax.enterprise.system.container.ejb.mdb.com.sun.ejb.containers|_ThreadID=21;_ThreadName=Thread-2;|MDB00050: Message-driven bean [MyProcessor-ear-1.0:MyMDB]: Exception in creating message-driven ejb : [com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=my.package.MyMDB/myEJB,Remote 3.x interface =my.package.MyEJB,ejb-link=null,lookup=,mappedName=,jndi-name=my.package.MyEJB,refType=Session into class my.package.MyMDB: Lookup failed for 'java:comp/env/my.package.MyMDB/myEJB' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}]|#]

Apparently this a bad design approach anyway because MDBs are inherently stateless so stateful EJBs shouldn't be injected. This makes sense.

My question is how else can I instantiate my stateful EJB when the MDB receives a message and ensure that the EJB is container managed?

sdoca
  • 7,832
  • 23
  • 70
  • 127

3 Answers3

0

If you need to maintain a single state for batch processing as you pointed out above (running, paused, cancelled) independently of the batches, i.e. the state applies to all MDBs consuming in certain moment: why don't you implement the EJB as a @Singleton? This way you could have that state in an instance variable in your EJB and your MDB reading from it.

  • The state doesn't apply to the MDB, it applies to a given EJB. The MDB receives a message that a new batch has been received and needs to create/start a processing EJB. The procssing EJB receives state change messages via another MDB to which it is a registered listener. – sdoca Nov 25 '11 at 15:23
0

We redesigned the classes and merged them so that the onMessage method of the MDB does the processing. The state of the individuals batches are being stored in a static map on the MDB.

sdoca
  • 7,832
  • 23
  • 70
  • 127
0

You can use javax.jms.QueueBrowser to inspect the state of Messages in Queue, and you could use a selector and a property message to locate the concrete batch process.

angelcervera
  • 3,699
  • 1
  • 40
  • 68