我正在将JavaLite Async从Artemis 2.3.0迁移到2.11.0版本。 JavaLite Async不使用任何文件基础配置,而是依靠代码。
在2.3.0和2.11.0版之间,JMS管理API现在已不可用/已弃用,我们建议使用Core Management API。
很遗憾,我找不到方法:
这里是一个例子(为简洁起见,保留了进口):
class QueueLookup {
private static final String LOCATION = "./target/artemis";
private static EmbeddedActiveMQ server;
public static void main(String[] args) throws Exception {
try{
Configuration configuration = new ConfigurationImpl()
.setPersistenceEnabled(true)
.setBindingsDirectory(LOCATION + "/bindings")
.setJournalDirectory(LOCATION + "/journal")
.setLargeMessagesDirectory(LOCATION + "/largemessages")
.setPagingDirectory(LOCATION + "/paging")
.setSecurityEnabled(false)
.addAcceptorConfiguration("invm", "vm://0")
.setJournalBufferTimeout_AIO(100)
.setJournalBufferTimeout_NIO(100)
.setJournalType(JournalType.NIO)
.setMaxDiskUsage(90);
//the following three lines have no effect
CoreQueueConfiguration coreQueueConfiguration = new CoreQueueConfiguration();
coreQueueConfiguration.setName("Queue123").setDurable(true);
configuration.addQueueConfiguration(coreQueueConfiguration);
server = new EmbeddedActiveMQ();
server.setConfiguration(configuration);
server.start();
TransportConfiguration transportConfiguration = new TransportConfiguration(InVMConnectorFactory.class.getName());
ConnectionFactory connectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
Hashtable<String, String> jndi = new Hashtable<>();
jndi.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
jndi.put("connectionFactory.ConnectionFactory", "vm://0");
//# queue.[jndiName] = [physicalName]
jndi.put("queue.queue/Queue123", "Queue123");
InitialContext initialContext = new InitialContext(jndi);
Queue jmsQueue = (Queue) initialContext.lookup("queue/Queue123");
try (Connection connection = connectionFactory.createConnection()) {
try(Session jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)){
MessageProducer producer = jmsSession.createProducer(jmsQueue);
connection.start();
TextMessage message = jmsSession.createTextMessage("Hello, Artemis!");
producer.send(message);
System.out.println("Message sent: " + message.getText());
}
} catch (Exception ex){
ex.printStackTrace();
}
}finally {
server.stop();
}
}
}
这些行无效:
CoreQueueConfiguration coreQueueConfiguration = new CoreQueueConfiguration();
coreQueueConfiguration.setName("Queue123").setDurable(true);
configuration.addQueueConfiguration(coreQueueConfiguration);
但是,如果我删除此行:
jndi.put("queue.queue/Queue123", "Queue123");
然后,JNDI无法找到队列。
表面上,我似乎可以通过将其名称添加到JNDI来“创建”队列:
jndi.put("queue.queue/Queue123", "Queue123");
但是,这仅部分起作用,队列似乎已经存在,发送和接收消息,而QueueControl
和QueueBrtowser
都找不到。
有人可以在代码中解释我如何做到这一点(无XML配置:
可以在此处找到带有GUI版本的完整示例:https://github.com/ipolevoy/artemis-sanbox/blob/master/src/main/java/examples/
非常感谢您的帮助!
这里似乎有一些误会...
首先,当您说添加CoreQueueConfiguration
无效时,您的意思不清楚。 ActiveMQ Artemis测试套件使用相同的模式来配置核心队列。我的猜测是,它似乎对您没有影响,因为默认情况下,核心JMS客户端会自动创建其所需的目标,因此无论您指定了CoreQueueConfiguration
,在JNDI属性中配置的任何内容都会自动创建。如果您不想自动创建JMS目标所需的基础地址和队列,则应使用相应的地址设置禁用此功能。还有一些设置可以在不再使用时自动删除地址和队列,您也可能要禁用它们。这是一个例子:
server.getAddressSettingsRepository().addMatch("#", new AddressSettings()
.setAutoCreateQueues(false)
.setAutoDeleteQueues(false)
.setAutoCreateAddresses(false)
.setAutoDeleteAddresses(false));
请记住,JMS目标(即JMS队列和主题)以特定方式映射到基础核心资源。在the documentation中对此进行了描述。
第二,JNDI配置在this bit of documentation中进行了解释:
JMS目的地通常也通过JNDI查找。与连接工厂一样,可以在JNDI上下文环境中使用特殊属性来配置目标。属性name应该遵循以下模式:
queue.<jndi-binding>
或topic.<jndi-binding>
。属性value应该是Apache ActiveMQ Artemis服务器托管的队列的名称。
这说明了为什么需要此行:
jndi.put("queue.queue/Queue123", "Queue123");
还可以查找在JNDI上下文环境中未显式配置的JMS目标。使用查询字符串中的
dynamicQueues/
或dynamicTopics/
可以做到这一点。例如,如果客户想要查找上述“ OrderQueue”,则可以简单地通过使用字符串“ dynamicQueues / OrderQueue”来查找。注意,dynamicQueues/
或dynamicTopics/
后面的文本必须与服务器上目标的名称完全一致。
这意味着您可以省略上述行,而使用这种查找:
Queue jmsQueue = (Queue) initialContext.lookup("dynamicQueues/Queue123");
就是说,不清楚为什么要在这里使用JNDI而不是简单地使用JMS API实例化目的地。您可以删除所有JNDI代码,从而大大简化该代码,例如:
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://0");
try (Connection connection = connectionFactory.createConnection();
Session jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) {
MessageProducer producer = jmsSession.createProducer(jmsSession.createQueue("Queue123"));
connection.start();
TextMessage message = jmsSession.createTextMessage("Hello, Artemis!");
producer.send(message);
System.out.println("Message sent: " + message.getText());
} catch (Exception ex) {
ex.printStackTrace();
}
要获得队列的控件,请使用类似以下内容:
QueueControl coreQueueControl = (QueueControl) server.getManagementService().getResource(org.apache.activemq.artemis.api.core.management.ResourceNames.QUEUE + "Queue123");
要浏览队列,您可以使用javax.jms.QueueBrowser
。网络上有很多教程。
最后,在添加了对AMQP,MQTT和OpenWire的支持之后,决定不赞成使用JMS配置和管理位是在发布2.0.0版本之前。那时,将配置和管理简化为仅核心资源(即地址,队列和路由类型)是有意义的。具有JMS的所有核心内容plus对应的配置和管理肯定会给用户造成混乱,并且也很难维护。我们花了很多时间来更新文档,以解释所有东西如何从受支持的各种协议和API到核心资源进行映射。 javax.jms.QueueBrowser
提供了可能对您有所帮助的概述。