Freitag, 4. Juli 2008

How to create several instances of one message driven bean with different configurations

Starting with EJB 3.0 you can write Message Driven Beans using Java 1.5 annotations without having to write an XML deployment descriptor file, e.g.:

@MessageDriven(activationConfig =  {
        @ActivationConfigProperty(propertyName = "destinationType",
            propertyValue = "javax.jms.Topic"),
        @ActivationConfigProperty(propertyName = "destination",
            propertyValue = "JMS/Topic"),
        @ActivationConfigProperty(propertyName = "messageSelector",
            propertyValue = "example = 'TestValue'"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode",
            propertyValue = "Auto-acknowledge"),
        @ActivationConfigProperty(propertyName = "subscriptionDurability",
            propertyValue = "Durable"),
        @ActivationConfigProperty(propertyName = "clientId",
            propertyValue = "ExampleBean"),
        @ActivationConfigProperty(propertyName = "subscriptionName",
            propertyValue = "ExampleBean")
    })
public class ExampleBean implements MessageListener {
    // ...
}

You can create several instances of the same Bean class, e.g. to have several instances for different message selectors or to listen on more than one Topic. To achieve this, move the properties out of the annotations and put them into an XML deployment descriptor.

The class file reduces to:

    @MessageDriven
    public class ExampleBean implements MessageListener {
        // ...
    }

Now create a file ejb-jar.xml (“New ► Standard Deployment Descriptor” in Netbeans). It has to end up in the META-INF/ directory in the deployment .jar file (Netbeans automatically creates ant rules for this).

The outer frame is:

<?xml version="1.0" encoding="UTF-8"?>
<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
         version = "3.0"
         xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd">;
    <enterprise-beans>
    </enterprise-beans>
</ejb-jar>

Inside the <enterprise-beans> tag, for each Bean instance create one <message-driven> section:

<message-driven>
    <ejb-name>AnotherExampleBean</ejb-name>
    <ejb-class>package.path.to.ExampleBean</ejb-class>
    <transaction-type>Container</transaction-type>
    <activation-config>
        
    </activation-config>
</message-driven>

Gotcha

You can choose the <ejb-name> for the instances freely, but one of the instances must be called exactly like the Bean class (ExampleBean in the example).

Inside <activation-config>, for each of the properties in the annotations above (destinationType etc.) create an <activation-config-property>:

<activation-config-property>
    <activation-config-property-name>destinationType</activation-config-property-name>
    <activation-config-property-value>JMS/Topic</activation-config-property-value>
</activation-config-property>

... comment