Injecting jms resource in servlet & best practice for MDB
- by kislo_metal
using ejb 3.1, servlet 3.0 (glassfish server v3)
Scenario:
I have MDB that listen to jms messages and give processing to some other session bean (Stateless).
Servelet injecting jms resource.
Question 1: Why servlet can`t inject jms resources when they use static declaration ?
@Resource(mappedName = "jms/Tarturus")
private static ConnectionFactory connectionFactory;
@Resource(mappedName = "jms/StyxMDB")
private static Queue queue;
private Connection connection;
and 
@PostConstruct
    public void postConstruct() {
        try {
            connection = connectionFactory.createConnection();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    @PreDestroy
    public void preDestroy() {
        try {
            connection.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
The error that I get is :
  [#|2010-05-03T15:18:17.118+0300|WARNING|glassfish3.0|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=35;_ThreadName=Thread-1;|StandardWrapperValve[WorkerServlet]:
  PWC1382: Allocate exception for
  servlet WorkerServlet
  com.sun.enterprise.container.common.spi.util.InjectionException:
  Error creating managed object for
  class
  ua.co.rufous.server.services.WorkerServiceImpl
    at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:312)
    at
  com.sun.enterprise.web.WebContainer.createServletInstance(WebContainer.java:709)
    at
  com.sun.enterprise.web.WebModule.createServletInstance(WebModule.java:1937)
    at
  org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1252)
  Caused by:
  com.sun.enterprise.container.common.spi.util.InjectionException:
  Exception attempting to inject
  Unresolved Message-Destination-Ref
  ua.co.rufous.server.services.WorkerServiceImpl/[email protected]@null
  into class
  ua.co.rufous.server.services.WorkerServiceImpl
    at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:614)     at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:384)
    at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:141)
    at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:127)
    at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:306)
    ... 27 more Caused by:
  com.sun.enterprise.container.common.spi.util.InjectionException:
  Illegal use of static field private
  static javax.jms.Queue
  ua.co.rufous.server.services.WorkerServiceImpl.queue
  on class that only supports
  instance-based injection  at
  com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:532)     ... 31 more |#]
my MDB :
/**
 * asadmin commands
 * asadmin create-jms-resource --restype javax.jms.ConnectionFactory jms/Tarturus
 * asadmin create-jms-resource --restype javax.jms.Queue jms/StyxMDB
 * asadmin list-jms-resources
 */
@MessageDriven(mappedName = "jms/StyxMDB", activationConfig =
{
    @ActivationConfigProperty(propertyName = "connectionFactoryJndiName", propertyValue = "jms/Tarturus"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class StyxMDB implements MessageListener {
    @EJB
    private ActivationProcessingLocal aProcessing;
    public StyxMDB() {
   }
    public void onMessage(Message message) {
        try {
            TextMessage msg = (TextMessage) message;
            String hash = msg.getText();
            GluttonyLogger.getInstance().writeInfoLog("geted jms message hash = " + hash);
        } catch (JMSException e) {
        }
    }
}
everything work good without static declaration:
@Resource(mappedName = "jms/Tarturus")
    private ConnectionFactory connectionFactory;
    @Resource(mappedName = "jms/StyxMDB")
    private Queue queue;
    private Connection connection;
Question 2:
 what is the best practice for working with MDB : processing full request in onMessage() or calling another bean(Stateless bean in my case) in onMessage() method that would process it.
Processing including few calls to soap services, so the full processing time could be for a 3 seconds. 
Thank you.