下面给出的代码会抛出javax.naming.NameNotFoundException
。我认为这可能是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();
}
}
}
和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) {
}
}
我应该亲自在服务器上创建吗?我认为它是通过这种注释自动创建的?不是真的吗?
答案 0 :(得分:0)
缺少destinationName
,表示MDB将侦听消息的主题/队列。
@MessageDriven(mappedName = "jms/txt", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationName", propertyValue = "jms/txt")
}
)
同样验证是否在管理控制台中的服务器上创建了特定队列,查找失败。
答案 1 :(得分:0)
nameNotFoundException
表示您尝试在JNDI中查找的名称不存在。因此,要么根本没有定义队列,要么使用错误的名称。
您能显示定义队列的xml文件吗?
此外,正如Nayan所指出的那样,destination
属性丢失了。这是必需的。此外,您对mappedName
注释属性的使用在这里完全错误,应该省略。此外,由于MDB使用默认的容器管理事务,acknowledgeMode
被忽略,因此不需要指定。
代码应如下所示:
@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) {
}
}
对于您的客户端,通常您还需要从远程JNDI查找ConnectionFactory
,并且不要忘记关闭从中获取的连接。对于JBoss AS 5.x和6.x,该工厂的JNDI名称只是/ConnectionFactory
。
作为发送JMS消息的惯用示例:
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) {
// ...
}
getFactoryFromJNDI()
和getDestinationFromJNDI()
只需包装JNDI查找代码。