Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configurable values to MDB annotations

I'm trying to use this method for receiving mail in our EJB3 app. In short, that means creating an MDB with the following annotations:

@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "mailServer", propertyValue = "imap.company.com"),
    @ActivationConfigProperty(propertyName = "mailFolder", propertyValue = "INBOX"),
    @ActivationConfigProperty(propertyName = "storeProtocol", propertyValue = "imap"),
    @ActivationConfigProperty(propertyName = "debug", propertyValue = "false"),
    @ActivationConfigProperty(propertyName = "userName", propertyValue = "username"),
    @ActivationConfigProperty(propertyName = "password", propertyValue = "pass") })
@ResourceAdapter("mail-ra.rar")
@Name("mailMessageBean")
public class MailMessageBean implements MailListener {
    public void onMessage(final Message msg) {
       ...snip...
    }
}

I have this working, but the situation is less than ideal: The hostname, username and password are hardcoded. Short of using ant and build.properties to replace those values before compilation, I don't know how to externalize them.

It would be ideal to use an MBean, but I have no idea how to get the values from the MBean to the MDB configuration.

How should I do this?

like image 462
Sietse Avatar asked Nov 21 '08 08:11

Sietse


People also ask

What is MDB in JMS?

A message-driven bean (MDB) is a consumer of messages from a Java™ Message Service (JMS) provider. An MDB is invoked on arrival of a message at the destination or endpoint that the MDB services. MDB instances are anonymous, and therefore, all instances are equivalent when not actively servicing a client message.

What is MDB in ejb?

A message-driven bean (MDB) is an EJB 3.0 or EJB 2.1 enterprise bean component that functions as an asynchronous message consumer. An MDB has no client-specific state but may contain message-handling state such as an open database connection or object references to another EJB.

Can MDB listen multiple queues?

Once instantiated, an MDB can only listen to the resource specified in their destination ActivationConfigProperty, however you can create multiple instances of the same MDB with different destinations (queues, in your case).

What is MDB in Jboss?

With an MDB, Java EE applications process messages asynchronously. An MDB functions as a JMS or JCA message listener. The messages can be sent by a Java EE component, for example an application client, or another enterprise bean, or by a non-Java EE application.


2 Answers

You can externalise the annotations into the ejb-jar.xml that you deploy in the META-INF of your jar file as follows:

<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar version="3.0">
    <enterprise-beans>
        <message-driven>
            <ejb-name>YourMDB</ejb-name>
            <ejb-class>MailMessageBean</ejb-class>        
            <activation-config>
                <activation-config-property>
                   <activation-config-property-name>username</activation-config-property-name>
                   <activation-config-property-value>${mdb.user.name}</activation-config-property-value>
                </activation-config-property>
...
...
            </activation-config>
        </message-driven>
    </enterprise-beans>

Then you can set the mdb.user.name value as a system property as part of the command line to your application server using -Dmdb.user.name=theUserName and it will magically get picked up by the mdb.

Hope that helps.

like image 153
Brett Hannah Avatar answered Sep 19 '22 23:09

Brett Hannah


As of JBoss AS 5.1 at least, you can use AOP to configure the @ActivationConfigProperties. I discovered this by looking at the examples that jboss provides here. This is useful if you do not want your username and passwords available to the entire container in a systems property, or if you are like me and never, I repeat NEVER, want to deploy an artifact with a username/password in it. Any how, here is the jist...

Annotate the mdb like this...

...
@MessageDriven
@AspectDomain("TestMDBean")
public class TestMDBean implements MessageListener {
...

Then add a ${whatever}-aop.xml to the deploy dir with internals like below. I left the original comments in there in case Jaikiran does make the changes mentioned...

Note: the annotation must be on one line only.

<?xml version="1.0" encoding="UTF-8"?>
<aop xmlns="urn:jboss:aop-beans:1.0">
   <!-- TODO: Jaikiran - These interceptor declarations need not be here since they 
   are already declared through the ejb3-interceptors-aop.xml. Duplicating them leads to
   deployment errors. However, if this custom-ejb3-interceptors-aop.xml needs to be 
   independent, then we must find a better way of declaring these. Right now, commenting these
   out, can be looked at later. -->
   <!--    
   <interceptor class="org.jboss.ejb3.AllowedOperationsInterceptor" scope="PER_VM"/>
   <interceptor class="org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor" scope="PER_VM"/>
   <interceptor factory="org.jboss.ejb3.security.RunAsSecurityInterceptorFactory" scope="PER_CLASS"/>
   <interceptor class="org.jboss.ejb3.stateless.StatelessInstanceInterceptor" scope="PER_VM"/>

   <interceptor factory="org.jboss.ejb3.interceptor.EJB3InterceptorsFactory" scope="PER_CLASS_JOINPOINT"/>
   <interceptor factory="org.jboss.aspects.tx.TxInterceptorFactory" scope="PER_CLASS_JOINPOINT"/>
   -->
   <domain name="TestMDBean" extends="Message Driven Bean" inheritBindings="true">
      <annotation expr="!class(@org.jboss.ejb3.annotation.DefaultActivationSpecs)">
         @org.jboss.ejb3.annotation.DefaultActivationSpecs (value={@javax.ejb.ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), @javax.ejb.ActivationConfigProperty(propertyName="destination", propertyValue="queue/MyQueue"), @javax.ejb.ActivationConfigProperty(propertyName="user", propertyValue="testusr"), @javax.ejb.ActivationConfigProperty(propertyName="password", propertyValue="testpwd")})
      </annotation>
   </domain>
</aop>
like image 39
Joseph Valerio Avatar answered Sep 22 '22 23:09

Joseph Valerio