1

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.

user613114
  • 2,731
  • 11
  • 47
  • 73
  • Does initial message make it to the queue? Depending on how you have JBoss configured, you might be able to look in the database tables, if using the db for the message persistence. – mikemil Feb 15 '14 at 21:13
  • I am not using any DB connection for persistence. Code is as simple as shown above. I am just trying to print message inside MDB. When I invoke this MDB from HermenJMS, it works. When I try to invoke from stateless bean as shown above, it does not. During debugging I see that MDS is injected in stateless bean without any issue. I do not see any exceptions in client console. – user613114 Feb 15 '14 at 21:19
  • I am bit confused by your comments. What do you mean by 'I see that MDS is injected in stateless bean without any issue"? Number 1) I am guessing you mean MDB? 2) I don't think MDBs get injected into a stateless bean. The MDB gets configured at deployment time. When a new message hits the jms/HelloWorldQueue, then JMS should be triggering a call the onMessage() in your HelloWorldMDB. Your stateless session bean just triggers the process by adding something to the queue. Am I missing something? – mikemil Feb 16 '14 at 03:49
  • Sorry for the confusion. I meant "destination queue" is injected successfully into stateless bean. MDB is successfully deployed. I verified this by sending message to MDB using HermenJMS. My problem is from stateless bean I am sending message to MDB. I do not see any exception in client. At the same time I do not receive message in MDB. I see only one line in console saying that channel end notification is received. I will correct the question to remove confusion. – user613114 Feb 16 '14 at 04:55
  • Reading this posting, http://www.jboss.org/jdf/quickstarts/jboss-as-quickstart/helloworld-jms/ it sounds like that error message is not really an error. I also found this https://issues.jboss.org/browse/AS7-1338 too. – mikemil Feb 17 '14 at 04:02
  • Thanks mikemil. You are right. This message is harmless. Actual issue and solution I have mentioned as a answer. – user613114 Feb 18 '14 at 15:47

1 Answers1

3

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.]

user613114
  • 2,731
  • 11
  • 47
  • 73