Question

I have using stateless bean as JMS message producer:

package com.cts.businesslogic;

import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;

import com.cts.business.HelloWorldBeanRemote;
import com.cts.to.Customer;

/**
 * Session Bean implementation class HelloWorldBean
 */
@Stateless(name = "HelloWorldBean")
@LocalBean
public class HelloWorldBean implements HelloWorldBeanRemote {

    @Resource(name = "java:/ConnectionFactory")
    private ConnectionFactory connectionFactory;

    @Resource(name = "java:/jms/HelloWorldQueue")
    private Queue destination;

    private Connection connection;

    private MessageProducer producer;

    /**
     * Default constructor.
     */
    public HelloWorldBean() {
    }

    @Override
    public String sayHello() {

        try {
            connection = connectionFactory.createConnection();
            Session session = connection.createSession(true,
                    Session.AUTO_ACKNOWLEDGE);

            producer = session.createProducer(destination);

            ObjectMessage message = session.createObjectMessage();
            Customer c = new Customer();
            c.setName("John");
            message.setObject(c);
            producer.send(destination, message);

            session.close();
            connection.close();

        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return "Hello World : First Ejb";
    }

}

My MDB is as follows:

package com.cts.businesslogic;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import com.cts.to.Customer;

/**
 * Message-Driven Bean implementation class for: HelloWorldMDB
 */
@MessageDriven(activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "jms/HelloWorldQueue") }, mappedName = "jms/HelloWorldQueue")
public class HelloWorldMDB implements MessageListener {

    /**
     * Default constructor.
     */
    public HelloWorldMDB() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {
        ObjectMessage o = (ObjectMessage) message;

        try {
            Customer c = (Customer) o.getObject();
            System.out.println("Hi " + c.getName()
                    + ". We received your message.");
        } catch (JMSException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

I am invoking stateless bean using remote client as:

package com.cts.ejbclient;

import javax.naming.Context;
import javax.naming.NamingException;

import com.cts.business.HelloWorldBeanRemote;

public class EjbClient {

    private static final String LOOKUP_STRING = "FIRST_EJB/HelloWorldBean!com.cts.business.HelloWorldBeanRemote";

    public static void main(String[] args) {
        HelloWorldBeanRemote bean = doLookup();
        // 3. Call business logic
        System.out.println(bean.sayHello());
    }

    private static HelloWorldBeanRemote doLookup() {
        Context context = null;
        HelloWorldBeanRemote bean = null;
        try {
            // 1. Obtaining Context
            context = ClientUtility.getInitialContext();
            // 2. Lookup and cast
            bean = (HelloWorldBeanRemote) context.lookup(LOOKUP_STRING);
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return bean;
    }
}

ClientUtility is as below:

package com.cts.ejbclient;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class ClientUtility {
    /*
     * location of JBoss JNDI Service provider the client will use. It should be
     * URL string.
     */
    private static final String PROVIDER_URL = "remote://localhost:4447";

    /*
     * Factory that creates initial context objects. fully qualified class name.
     */
    private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";

    private static Context initialContext;

    public static Context getInitialContext() throws NamingException {
        if (initialContext == null) {
            // Properties extends HashTable
            Properties prop = new Properties();
            prop.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
            //prop.put(Context.URL_PKG_PREFIXES, JNP_INTERFACES);
            prop.put(Context.PROVIDER_URL, PROVIDER_URL);
            prop.put("jboss.naming.client.ejb.context", true);
            prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
            prop.put(Context.SECURITY_PRINCIPAL, "admin");
            prop.put(Context.SECURITY_CREDENTIALS, "xxx");
            initialContext = new InitialContext(prop);
        }
        return initialContext;
    }
}

The problem I am facing is, I am able to call this MDB from Hermen Jms monitor tool. But when I run EJBClient mentioned above, I see server console in eclipse:

01:52:11,198 INFO  [org.jboss.as.naming] (Remoting "xxx-pc" task-1) JBAS011806: Channel end notification received, closing channel Channel ID 17efc189 (inbound) of Remoting connection 6b8a3fef to null

There is no other line in console. And in this case MDB is not getting called.

More information: Server - JBOSS EAP 6.1

standalone descriptor - standalone-full.xml

I am trying to find out the actual issue, but can not. Please let me know, if you know what is wrong here. Thanks.

Was it helpful?

Solution

I found the solution to this mysterious issue. I modified the create session statement in HelloWorldBean as:

Session session = connection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);

I found following reference in Oracle API Documentation

It says:

  • If transacted is set to true then the session will use a local transaction which may subsequently be committed or rolled back by calling the session's commit or rollback methods. The argument acknowledgeMode is ignored.

  • If transacted is set to false then the session will be non-transacted. In this case the argument acknowledgeMode is used to specify how messages received by this session will be acknowledged. The permitted values are Session.CLIENT_ACKNOWLEDGE, Session.AUTO_ACKNOWLEDGE and Session.DUPS_OK_ACKNOWLEDGE. For a definition of the meaning of these acknowledgement modes see the links below.

Hope this solution will help others.

[Note: I still receive the warning saying that Channel end notification received. But as mikemil pointed out this message is harmless. Thanks mikemil for your co-operation.]

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