我使用无状态bean作为JMS消息生成器:
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";
}
}
我的MDB如下:
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();
}
}
}
我使用远程客户端调用无状态bean:
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如下:
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;
}
}
我面临的问题是,我可以从Hermen Jms监控工具中调用此MDB。但是当我运行上面提到的EJBClient时,我在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
控制台中没有其他行。在这种情况下,MDB不会被调用。
更多信息: 服务器 - JBOSS EAP 6.1
独立描述符 - standalone-full.xml
我试图找出实际问题,但不能。如果你知道这里有什么问题,请告诉我。 感谢。
答案 0 :(得分:3)
我找到了这个神秘问题的解决方案。我将HelloWorldBean中的create session语句修改为:
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
中找到了以下参考资料
它说:
如果transacted设置为true,则会话将使用本地事务,该事务随后可以通过调用会话的提交或回滚方法来提交或回滚。参数acknowledgeMode被忽略。
如果transacted设置为false,则会话将不进行交易。在这种情况下,参数acknowledgeMode用于指定如何确认此会话接收的消息。允许的值是Session.CLIENT_ACKNOWLEDGE,Session.AUTO_ACKNOWLEDGE和Session.DUPS_OK_ACKNOWLEDGE。有关这些确认模式含义的定义,请参阅以下链接。
希望这个解决方案能够帮助他人。
[注意:我仍然收到警告说已收到频道结束通知。但正如迈克米尔所指出的那样,这个消息是无害的。感谢mikemil的合作。]