我一直在使用常规的ActiveMQConnectionFactory来创建与队列的连接并推送我的消息。 ActiveMQ连接通过SSL连接,需要用户名和密码。只要我指定了用户名和密码,这对我来说非常有用。
最近我改变了我的设计并决定使用PooledConnectionFactory为我自己的线程池创建连接和会话。我希望能够在我的池中重用连接和会话,以便我可以调整我的应用程序上的负载并扩展连接和扩展。会议视需要。
除了最初创建池之外,我的其余流程与之前完全相同。但是现在当我尝试连接时,我得到一个NullPointerException和这个返回跟踪:
javax.jms.JMSException: java.lang.NullPointerException
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:54)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1420)
at org.apache.activemq.ActiveMQSession.syncSendPacket(ActiveMQSession.java:2018)
at org.apache.activemq.ActiveMQMessageProducer.<init>(ActiveMQMessageProducer.java:124)
at org.apache.activemq.ActiveMQSession.createProducer(ActiveMQSession.java:1048)
at org.apache.activemq.jms.pool.SessionHolder.getOrCreateProducer(SessionHolder.java:62)
at org.apache.activemq.jms.pool.PooledSession.getMessageProducer(PooledSession.java:393)
at org.apache.activemq.jms.pool.PooledSession.createProducer(PooledSession.java:368)
at com.xyleo.app.App.createProducer(App.java:95)
at com.xyleo.app.App.sendTestMessage(App.java:55)
at com.xyleo.app.App.main(App.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.NullPointerException
at com.intuit.platform.integration.messaging.server.security.QBaseSecurityBrokerFilter.addProducer(QBaseSecurityBrokerFilter.java:265)
at org.apache.activemq.broker.MutableBrokerFilter.addProducer(MutableBrokerFilter.java:112)
at org.apache.activemq.broker.MutableBrokerFilter.addProducer(MutableBrokerFilter.java:112)
at org.apache.activemq.broker.TransportConnection.processAddProducer(TransportConnection.java:565)
at org.apache.activemq.command.ProducerInfo.visit(ProducerInfo.java:108)
at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:294)
at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:148)
at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)
at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:270)
at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:214)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:196)
at java.lang.Thread.run(Thread.java:744)
我尝试使用SSL凭据找到池的使用示例,并且很难在网络上找到任何有用的内容。但我真的没有看到我使用PooledConnectionFactory有什么问题。
我编写了一个独立的例子,显示了我想要做的事情。 注意当我使用createRegularConnectionFactory时,一切都很完美。但是,当我使用createPooledFactory时,程序会抛出上述异常。
public class App
{
private static Logger LOG;
private static Properties mqProps;
private static ConnectionFactory _connectionFactory;
private static Session _session;
private static TextMessage _textMessage;
private static Connection _connection;
private static MessageProducer _producer;
private static String appid;
private static String appsecret;
private static String queueName;
private static String brokerUrl;
public static void main( String[] args )
{
System.setProperty("application-name", "mq_pool_test");
LOG = LoggerFactory.getLogger(App.class);
LOG.info("======== STARTING MQ TEST ==========");
int status = 0;
try {
populateTestConfig();
sendTestMessage();
} catch (JMSException e) {
e.printStackTrace();
status = 1;
}
System.exit(status);
}
public static void sendTestMessage() throws JMSException {
// createRegularConnectionFactory(brokerUrl);
createPooledFactory(brokerUrl);
createConnectionAndSession(appid, appsecret);
createProducer(queueName);
prepareTextMessage();
sendMessage(queueName);
}
private static void createPooledFactory(String brokerUrl) {
System.out.println("Creating pooled factory with connection to " + brokerUrl);
ActiveMQConnectionFactory factory = getActiveMQConnectionFactory(brokerUrl);
PooledConnectionFactory pooledFactory = new PooledConnectionFactory();
pooledFactory.setConnectionFactory(factory);
pooledFactory.setMaxConnections(10);
pooledFactory.start();
_connectionFactory = pooledFactory;
}
private static void createRegularConnectionFactory(String brokerUrl) {
System.out.println("Creating factory with connection to " + brokerUrl);
ActiveMQConnectionFactory factory = getActiveMQConnectionFactory(brokerUrl);
_connectionFactory = factory;
}
private static ActiveMQConnectionFactory getActiveMQConnectionFactory(String brokerUrl) {
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);
factory.setUserName(appid);
factory.setPassword(appsecret);
return factory;
}
private static void createConnectionAndSession(String appid, String appsecret) throws JMSException {
System.out.println("Connection with AppID = " + appid +
" and appsecret = " + appsecret);
_connection = _connectionFactory.createConnection();
_connection.start();
_session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
private static void createProducer(String queueName) throws JMSException {
Destination destination = _session.createQueue(queueName);
System.out.println("Creating producer for " + destination);
_producer = _session.createProducer(destination);
}
private static void prepareTextMessage() throws JMSException {
_textMessage = _session.createTextMessage("Test");
}
private static void sendMessage(String queueName) throws JMSException {
System.out.println("Sending message to " + queueName);
_producer.send(_textMessage);
}
private static void populateTestConfig() {
mqProps = getPropertiesFromFile("mq_test.properties");
appid = mqProps.getProperty("appid");
appsecret = mqProps.getProperty("appsecret");
queueName = mqProps.getProperty("queuename");
brokerUrl = mqProps.getProperty("brokerurl");
}
private static Properties getPropertiesFromFile(String propFile) {
Properties properties = new Properties();
InputStream input = null;
try {
input = App.class.getClassLoader().getResourceAsStream(propFile);
if (input == null) {
System.err.format("Sorry, unable to find {}", propFile);
}
properties.load(input);
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return properties;
}
}
希望这是足够的细节。提前谢谢。