Question

I'm new to J2EE - MDB but I'm trying to create a Message Driven Bean (MDB) that simply listens to a queue (read the messages), then process that message and push it to a different queue. I have found several working examples on Google to achieve these two tasks in a separate fashion, but I've been having issues trying to do them both on the same MDB.

This is the code for my MDB

    @MessageDriven(mappedName = "jms/propuestasQ")
public class ObtenerNumPolizaBean implements MessageListener {

    @Resource(name="jms/polizasQCF")
    private QueueConnectionFactory connectionFactory;

    private Connection connection;

    @Resource(name = "jms/polizasQ")
    private Destination targetQueue;

    @PostConstruct
    private void initJMS() {
        try {
            connection = connectionFactory.createConnection();
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }

    @PreDestroy
    private void closeJMS() {
        try {
            connection.close();
        } catch (JMSException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @see MessageListener#onMessage(Message)
     */
    @Override
    public void onMessage(Message message) {
        //validate the received message type
        if (message instanceof FolioEntity) {
            try {
                //generate Web Service proxy
                GenerarFoliosImplService serviceGenerarFolios = new GenerarFoliosImplService();
                GenerarFoliosImplDelegate delGenerarFolios = serviceGenerarFolios.getGenerarFoliosImplPort();

                //call the method with the object
                FolioEntity responseFolio = delGenerarFolios.generarFolios((FolioEntity)message);

                System.out.println("Bean generated the following FolioNumber: " + responseFolio.getNumeroFolio());

                //put the message on the next queue
                putMessage(responseFolio);
            }
            catch (JMSException e) {
                throw new RuntimeException(e);
            }
        }
        else {
            throw new IllegalArgumentException("Message must be of type FolioEntity");
        }
    }

    private void putMessage(final FolioEntity folio) throws JMSException {
         final Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
         final MessageProducer producer = session.createProducer(targetQueue);
         final ObjectMessage objectMessage = session.createObjectMessage();
         producer.send(objectMessage);
         session.close();
    }

Here is the content of my ejb-jar.xml file

    <?xml version="1.0" encoding="UTF-8"?>
<ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 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">
  <display-name>MDBRenovarPolizaEJB </display-name>
  <enterprise-beans >

    <message-driven>
        <ejb-name>ObtenerNumPolizaBean</ejb-name>
        <message-destination-ref>
            <description />

            <message-destination-ref-name>
                jms/polizasQ
            </message-destination-ref-name>
            <message-destination-type>
                javax.jms.Queue
            </message-destination-type>
            <message-destination-usage>
                ConsumesProduces
            </message-destination-usage>
            <message-destination-link>
                jms/polizasQ
            </message-destination-link>
        </message-destination-ref>
        <message-destination-ref>
            <description />

            <message-destination-ref-name>
                jms/polizasQCF
            </message-destination-ref-name>
            <message-destination-type>
                javax.jms.QueueConnectionFactory
            </message-destination-type>
            <message-destination-usage>
                ConsumesProduces
            </message-destination-usage>
            <message-destination-link>
                jms/polizasQCF
            </message-destination-link>
        </message-destination-ref>

The issue I'm having is that I can't set the "Message Driven Bean listener bindings" on WAS Console 8.5.5, when I try to set the activation specification I'm getting the error:

MDBRenovarPolizaModelEJB.jar\META-INF\ejb-jar_merged.xml (The system cannot find the file specified.)

I don't know what this exception means. I've always set the "Activation specification" this way to listen to a particular queue, so I have no idea what is this file: "ejb-jar_merged.xml".

Any clue? Thanks in advance.

Or if anyone has a working example to achieve this with step by step to make it work under WebSphere that would be useful.

Was it helpful?

Solution

I just solved similar problem (WAS 8.5.5, but MDB, EJB, servlet - all stuffed into one war module)

It is clearly a bug in WAS. This is workaround:

  1. Ensure Run server with resources on Server

  2. Publish to repeat an error (but this time with resources on server)

  3. Find directory where WAS expects "ejb-jar_merged.xml":

    • Locate WAS SystemErr.log
    • There are messages about missing "ejb-jar_merged.xml".
    • You are looking for directory name of missing file.
  4. Goto to the found directory. (something like .IBM/WebSphere/AppServer/profiles/AppSrv01/wstemp/0/workspace/... ....deployments /.....-INF/

  5. copy ejb-jar.xml ejb-jar_merged.xml

In case of missing web_merged.xml just copy web.xml into web_merged.xml.

The problem will not appear again at application updates, it has to be reapplied sometimes after app remove/install.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top