简体   繁体   中英

@MessageDriven doesn't work in JBoss AS 5

The code as given below throws a javax.naming.NameNotFoundException . I think that it might be some kind of problem with JBoss AS 5.

package web;
import java.util.Properties;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
import javax.naming.InitialContext;

import org.jboss.jms.server.connectionfactory.ConnectionFactory;

public class MyMDBClient {

    public static void main(String[] args) {
        QueueConnection cnn = null;
        QueueSender sender = null;
        QueueSession session = null;
        InitialContext ctx;
        try {
            Properties props = new Properties();
            props.setProperty("java.naming.factory.initial",
                    "org.jnp.interfaces.NamingContextFactory");
            props.setProperty("java.naming.factory.url.pkgs",
                    "org.jboss.naming");
            props.setProperty("java.naming.provider.url", "127.0.0.1:1099");

            ctx = new InitialContext(props);
            Queue queue = (Queue) ctx.lookup("jms/txt");
            QueueConnectionFactory factory = (QueueConnectionFactory)new ConnectionFactory();
            cnn = factory.createQueueConnection();
            session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
            TextMessage msg = session.createTextMessage("Hello World");
            sender = session.createSender(queue);
            sender.send(msg);
            System.out.println("Message sent successfully to remote queue.");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

and mdb:

package web;

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

@MessageDriven(mappedName="jms/txt",
        activationConfig = { @ActivationConfigProperty(
                propertyName = "destinationType", propertyValue = "javax.jms.Queue"
        ) })
public class FirstMDB implements MessageListener {

    public void onMessage(Message message) {


    }

}

should i create that on server personally?i think it created automaticly by this nottation??is not true?

The destinationName is missing which indicates for which topic/queue the MDB will listen the messages.

@MessageDriven(mappedName = "jms/txt", activationConfig =  {
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destinationName", propertyValue = "jms/txt")
    }   
)

Also verify whether the particular queue is created on the server in admin console, lookup is being failed.

The nameNotFoundException indicates that the name you're trying to lookup in JNDI doesn't exists. So, either you don't have a queue defined at all, or you're using the wrong name.

Can you show the xml file where you define the queue?

Furthermore, as Nayan also indicates, the destination property is missing. This is required. Additionally, your usage of the mappedName annotation attribute is completely wrong here and should be omitted. Additionally, as the MDB is using the default container managed transactions the acknowledgeMode is being ignored and thus does not need to be specified.

The code should look like this:

@MessageDriven( 
    activationConfig = {        
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), 
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "/queue/yourQueue") 
    }
)
public class FirstMDB implements MessageListener {

    public void onMessage(Message message) {    

    }    
}

As for your client, typically you also need to lookup the ConnectionFactory from remote JNDI and don't forgot to close the connection obtained from it. For JBoss AS 5.x and 6.x the JNDI name of this factory is simply /ConnectionFactory .

As an idiomatic example of sending a JMS message:

ConnectionFactory factory = getFactoryFromJNDI();
Connection connection = null;
try {
    try {
        connection = factory.createConnection();

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

        MessageProducer sender = session.createProducer(destination);    
        Message message = session.createTextMessage("Hello World");

        sender.send(message);        
    }
    finally {
        if (connection != null) {
            connection.close();
        }
    }
}
catch (JMSException e) {
    // ...
}

Where getFactoryFromJNDI() and getDestinationFromJNDI() simply wrap the JNDI lookup code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM