Send your JMS messages to the Event Delivery Network (EDN) with a simple MDB

If you have read some of my previous articles, you should know that I’m using the SOA Suite on my project as a BPM, based on the coordination of JMS messages.
I naturally went for the solution proposed by Oracle : the JMS adapter. But it took me some time to figure out how to make it work :) The official documentation is complete, but when you need to really implement the concept, it’s often too light.
Then I got it working, as demonstrated in a previous blogpost but it was quite disappointing. In fact, I found it quite strenuous and complex. To me, the need for JCA (and deployment plan)  is not mandatory : I just wanted to KISS (keep it simple & stupid)
Then I started looking for some content on that and I found some interesting stuff on Edwin’s blog & Guido’s blog. But once again, I could not go with a complete implementation. Then I tried several things, tested and finally, I came up with an implementation that was satisfying (and which is used every single day in production).
To keep you from going the same loong path I went, here is my code :

package fr.mbutton.blog.mdb;

import java.io.StringWriter;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.TextMessage;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
import javax.xml.namespace.QName;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import oracle.fabric.blocks.event.BusinessEventConnection;
import oracle.fabric.blocks.event.BusinessEventConnectionFactory;
import oracle.fabric.common.BusinessEvent;
import oracle.integration.platform.blocks.event.BusinessEventBuilder;
import oracle.integration.platform.blocks.event.jms.JmsRemoteBusinessEventConnectionFactory;
import oracle.integration.platform.blocks.event.saq.SAQRemoteBusinessEventConnectionFactory;
import oracle.soa.common.util.XMLUtil;
import org.w3c.dom.Document;

@MessageDriven(mappedName = "your.topic.jndi.name",
   activationConfig = { 
      @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
      @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
      @ActivationConfigProperty(propertyName = "topicMessagesDistributionMode", propertyValue = "One-Copy-Per-Application") })
public class JMSBridgeToEDN implements MessageListener {

    // EDN JMS environment
    private final String connFactName   = "jms/fabric/EDNConnectionFactory";
    private final String xaConnFactName = "jms/fabric/xaEDNConnectionFactory";
    private final String queueName      = "jms/fabric/EDNQueue";

    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
          TextMessage txt = (TextMessage) message;
          BusinessEventConnection connection = null;
          try {
            // You can choose between two methods : Oracle AQ or JMS
            // Default is Oracle AQ
            connection = getOracleAQConnection ();
            // But you can choose the other one :
            // connection = getWebLogicJMSConnection();
            // Publish to EDN
            BusinessEvent event = updateAndConvertBody(txt.getText());
            // System.out.println("Element : " + displayXMLDoc(event.getAsDoc()));
            connection.publishEvent(event, 3); // The number represents message priority (3 = default)
            } catch (Exception e) {
            } finally {

    private BusinessEventConnection getWebLogicJMSConnection () throws Exception {
      InitialContext context = new InitialContext();
      UserTransaction userTransaction = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
      QueueConnectionFactory queueConnectionFactory = ((QueueConnectionFactory)context.lookup(connFactName));
      QueueConnectionFactory xaQueueConnectionFactory = 
      Queue jmsQueue = ((Queue)context.lookup(queueName));
      BusinessEventConnectionFactory factory =
          new JmsRemoteBusinessEventConnectionFactory(queueConnectionFactory,
      return factory.createBusinessEventConnection();
    private BusinessEventConnection getOracleAQConnection () throws Exception {
      InitialContext context = new InitialContext();
      UserTransaction userTransaction = (UserTransaction) context.lookup("javax.transaction.UserTransaction");
      // Working with both EDN datasources (as seen in class SAQRemoteBusinessEventConnectionFactory)
      DataSource ds = (DataSource) context.lookup("jdbc/EDNDataSource");
      DataSource localTxDs = (DataSource) context.lookup("jdbc/EDNLocalTxDataSource");
      BusinessEventConnectionFactory factory = 
        new SAQRemoteBusinessEventConnectionFactory(ds, localTxDs, userTransaction);
      return factory.createBusinessEventConnection();

    private BusinessEvent updateAndConvertBody (String body) throws Exception {
      // [...]
      // Creation of the message to be sent over the EDN
      String TCEvenement = "TCEvenement";
      // A common mistake is to use the namespace of your message : IT'S NOT THE ONE YOU SHOULD USE !
      // You have to provide the namespace of your message as defined IN THE EDL FILE !
      String NameSpace = "http://fr.edf.doaat.coctos/events/edl/EventDefinition";
      BusinessEventBuilder builder = BusinessEventBuilder.newInstance();
      builder.setEventName(new QName(NameSpace, TCEvenement));
      return builder.createEvent();
    private String displayXMLDoc (Document doc) throws Exception {
      TransformerFactory transFactory = TransformerFactory.newInstance();
      Transformer transformer = transFactory.newTransformer();
      StringWriter buffer = new StringWriter();
      transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
      transformer.transform(new DOMSource(doc), new StreamResult(buffer));
      return buffer.toString();    

The method displayXMLDoc is completely optionnal : I used it to help me debug my code but that’s all.
Feel free to improve those codelines, as long as they help you, I’m glad.

Mots clés Technorati : ,,,

Useful links:


Praveen Kumar Jayaram said...


Is there a way to access SOA EDN queue outside the domain, say from another FMW server? I need to post a event to SOA's EDN queue based on some condition..


Praveen Kumar Jayaram said...


Thanks for all the great articles.
I followed this article to post an event to EDN.. It works perfectly!

But the Java client (Eclipse project) has dependency on following list of jars -




and XML parser jars.

I'm writing a piece of code which runs in another FMW server which would post events to EDN.
The problem is having all these dependencies in an Non-SOA middleware. Is there a way to get rid off these dependency?

Thanks in advance.