5 Replies Latest reply on Dec 5, 2007 6:50 AM by pmuir

    Injection not working when using thirdparty JMS library

    raoul.schmidiger

      Hi List,

      I use Seam 2 with JBoss AS. My problem is that I want to use a thirdparty JMS library from within Seam.

      I have a class that implements the javax.jms.MessageListener interface and that class is correctly hooked into my thridparty JMS lib. So far so good. But I also would like to inject a service class through seam into that same class. So that when a message is received, some stuff gets done on the database level. And as i need the @PersistenceContext, the service object has to be managed by the container...

      This however only happens when Seam is involved in the calling.

      This is not the case when the method onMessage(javax.jms.Message m) method is invoked by the thirdparty lib. Then

      Is there a way for letting Seam do the creation of my MessageListener impl and have a property injected in a persistent style, aka only once at creation?

      I played around with the @In(scope=SESSION) attribute, but without any success.

      Thanks a lot, regards raoul

        • 1. Re: Injection not working when using thirdparty JMS library
          pmuir

          Post the code for your message listener impl.

          • 2. Re: Injection not working when using thirdparty JMS library
            pmuir

            And more importantly, is it declared as an MDB?

            • 3. Re: Injection not working when using thirdparty JMS library

              It may be generally a good practice to do the business logic in a session bean instead of using JPA directly in your MDB.

              However, this is currently a problem when your app is deployed with messages already in the queue: http://jira.jboss.org/jira/browse/JBSEAM-2286

              • 4. Re: Injection not working when using thirdparty JMS library
                raoul.schmidiger

                Hi Pete,

                No, it is not declared as a MDB. It is clear to me, that this is not the usual way to go. But what about thirdparty libs in general, well yes, that start off some threads and do callbacks on my code? I know it is not considered "good" practice but then again...

                @Stateful
                @Name("jmsListener")
                @Scope (ScopeType.SESSION)
                public class JmsMessageListener implements MessageListener, IJmsMessageListener {
                
                 // factor out into properties
                 private static final String SEND_QUEUE = "IN";
                 private static final String RECEIVE_QUEUE = "OUT";
                
                 private ASyncSender asyncSender;
                 //private SyncSender syncSender;
                
                 @In(create=true, required=true)
                 private IUnderlyingService underlyingService;
                 private IUnderlyingService underlyingServiceHack;
                
                 @In(create=true, required=true)
                 private IConnectionProvider connectionFactoryProvider;
                
                 public JmsMessageListener() {
                 System.out.println("constructor: JmsMessageListener");
                 }
                
                 @Remove @Destroy
                 public void remove() {
                 System.out.println("destroyed: JmsMessageListener");
                 }
                
                 @Create
                 public void init() throws JMSException {
                 MessageSessionProvider messageSessionProvider = new MessageSessionProvider(connectionFactoryProvider.getConnectionFactory());
                 asyncSender = new ASyncSender(messageSessionProvider, SEND_QUEUE);
                 messageSessionProvider.setMessageListener(RECEIVE_QUEUE, this);
                 //syncSender = new SyncSender(messageSessionProvider, SEND_QUEUE);
                 messageSessionProvider.startConnection();
                
                 if(underlyingService == null) {
                 System.out.println("at init, underlyingService is null");
                 } else {
                 System.out.println("at init, underlyingService is not null");
                 underlyingServiceHack = underlyingService;
                 }
                 }
                
                 @Override
                 public void onMessage(Message message) {
                 if(message instanceof ObjectMessage) {
                 try {
                 System.out.println("got a message: " + ((ObjectMessage) message).getObject());
                 } catch (JMSException e) {
                 e.printStackTrace();
                 }
                 } else {
                 System.out.println("got a message: " + message);
                 }
                 if (message instanceof ObjectMessage) {
                 ObjectMessage objectMessage = (ObjectMessage) message;
                 try {
                 //...
                 }
                 } catch (JMSException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
                 }
                 }
                 }
                
                }
                


                • 5. Re: Injection not working when using thirdparty JMS library
                  pmuir

                  Well you need to integrate them into Seam. Seam uses EJB3 interceptors to intercept all requests to MDB (and SLSB, SFSB) and wrap them in Seam's contexts etc. If you are just calling the object directly (which I think you are) you'll need to set up the contexts yourself. You can look at the ContextHttpServletRequest for an example of how to do this for requests coming in from a servlet.