views:

517

answers:

1

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.

+2  A: 

Answers:
1. You cannot inject a resource into a static field. Injection into member fields occurs during object construction, static fields are not part of the object (only part of the class). In addition EJBs and servlets are threaded objects so this could possibly be dangerous to do.
2. If splitting the processing up into multiple EJB(s) makes sense do it that way, otherwise processing in onMessage() is perfectly valid.

One additional suggestion that I can give, is that you should take a look at CDI which is a new addition to the EE 6 specification and provides rich dependency injection.

Are you using an MDB to perform asynchronous operations, Servlet 3.0 has some neat asynchronous capabilities. I suggest you watch the entire presentation if you are not familiar with Servlet 3.0.

Justin
Thank you, Justin.
kislo_metal
My servlet is GWT servlet in reality, so I will need to test if GWT compatible with Servlet 3.0 async method. In reality gwt has it`s own GWT.runAsync() method, haven`t look inside yet if it naturally support the same async method as servlet 3.0 or if it working by servlet`s 3.0 async methods.
kislo_metal
Ok, Looks like I could handle all I need without MDB in my case.About GWT.runAsync() - it is different.Excellent presentation , thank you!
kislo_metal