当前位置: 首页 > 知识库问答 >
问题:

如何在代码中创建Apache Artemis队列并将其与JMS一起使用?

阳念
2023-03-14

我正在将JavaLite Async从Artemis 2.3.0迁移到2.11.0版本。JavaLite Async不使用任何文件基配置,而是依赖于代码。

在V2.3.0和2.11.0之间,JMS管理API现在已经消失/不推荐使用,我们被鼓励使用核心管理API。

不幸的是,我找不到办法:

    null
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找不到队列。

从表面上看,I似乎可以通过将队列名称添加到JNDI来“创建”队列:

jndi.put("queue.queue/Queue123", "Queue123");
    null

共有1个答案

公良英资
2023-03-14

这里似乎有几个误解...

首先,您的coRequeueConfiguration具有“无效”的原因是因为它无效。它无效,因为您没有指定队列将绑定到的地址的名称。当代理出现指示配置无效时,它应该记录如下内容:

WARN  [org.apache.activemq.artemis.core.server] AMQ222275: Failed to deploy queue <queue name>: null

正如JMS到核心映射文档中所指出的,JMS队列是一个核心地址和一个名称相同的选播核心队列。因此,您应该使用如下配置:

coreQueueConfiguration.setAddress("Queue123").setName("Queue123").setDurable(true).setRoutingType(org.apache.activemq.artemis.api.core.RoutingType.ANYCAST);
server.getAddressSettingsRepository().addMatch("#", new AddressSettings()
   .setAutoCreateQueues(false)
   .setAutoDeleteQueues(false)
   .setAutoCreateAddresses(false)
   .setAutoDeleteAddresses(false));
java prettyprint-override">jndi.put("queue.queue/Queue123", "Queue123");

文件还指出:

还可以查找尚未在JNDI上下文环境中显式配置的JMS目的地。可以在查找字符串中使用DynamicQueues/DynamicTopics/。例如,如果客户机想要查找前面提到的“OrderQueue”,它可以通过使用字符串“DynamicQueues/OrderQueue”来完成。注意,DynamicQueues/DynamicTopics/后面的文本必须与服务器上的目标名称完全对应。

这意味着您可以省略前面提到的行,而使用这种查找方式:

Queue jmsQueue = (Queue) initialContext.lookup("dynamicQueues/Queue123");
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");
 类似资料:
  • 我在域模式下运行Wildfly17。我们一直在手动添加JMS队列,但我宁愿将配置作为部署脚本的一部分添加。我可以使用创建服务器和数据源,但在队列方面似乎没有任何进展。我希望domain_config.xml的结尾如下所示: 我已经研究了如何在Wildfly中使用CLI设置消息传递子系统,但我得到的都是错误。 domain_config.xml的完整嵌套是:

  • 我认为最初的作者认为这将创建一个持久的队列,但显然不是。我找不到这方面的好文档,想知道是否有人能证实/否认这一点。 提前谢了。

  • 问题内容: 我需要为响应创建一个临时队列,但是我需要知道是否可以通过消息的setJMSReplyTo方法发送响应队列对象而不连接到临时队列,因为回复线程根本无法得到该对象。 问题答案: 我通过使用InitialContext对象将临时队列绑定到jndi,以便可以从需要使用临时队列的线程中查找临时队列。 要获取临时队列,您只需要在需要使用它的代码中查找它:

  • 如果要在spring integration jms上为消息发布者创建qpid目标。例如,我可以创建如下队列: 之后,我将此队列设置为通道适配器: 如果发布者发送第一条消息,将在消息代理上创建队列。 但是如果我想动态设置队列,我能做什么呢? 发布者看起来像: } publisher方法的第二个参数是目标的名称。如果我在发送消息之前在brokerside上创建队列,那么这是可行的。我当前的解决方案是

  • 现在,我正在Java EE 7应用程序上使用JMS 2.0和Artemis 1.2.0,我想用Camel做一些集成任务。 目前,在查看驼峰jms文档时,没有提到如何使用通用驼峰jms组件向任何符合jms 2.0的代理生成和使用消息。 组件文档中的唯一示例是使用Spring DSL使用专用的ActiveMQ组件配置ActiveMQ连接工厂。如何配置骆驼JMS的连接以连接到我的Artemis实例? 考

  • 如果在发送接收到的消息时发生异常,则会丢失已接收到的消息。