【问题标题】:Add manually mappedName in Message Driven Bean at runtime在运行时在消息驱动 Bean 中添加手动映射名称
【发布时间】:2013-04-09 10:14:21
【问题描述】:

我需要制作简单的消息驱动 Bean,它会监听动态添加的队列位置。我尝试了几种方法来实现这一点,但都没有奏效。我有使用 esb 和 java 消息队列的应用程序,并且我正在尝试在运行时从配置文件中读取队列位置,从而告诉我的消息驱动 bean 要侦听的队列是什么。我也不确定这是否可行。

我也试过实现message listener,但是因为要使用ejb模块,而且ejb模块不支持main方法,需要自己的容器(比如messagedriven bean),不知道用什么代替实现相同目标的主要方法。我无法使用会话 bean,因为我需要实现客户端和服务之间的异步通信。

我也尝试使用客户端应用程序(虽然它不是选项之一),但是 maven 项目不支持在 netbeans 中为此类应用程序调试和运行功能。

有没有人知道这个问题的任何解决方案,或者至少有一些想法?

【问题讨论】:

    标签: java message-queue ejb-3.1 message-driven-bean glassfish-esb


    【解决方案1】:

    这可能不是最好的解决方案,但可以使用 Stateful Session Bean 异步接收和处理 JMS 消息,如下所示:

    package com.example.statefuljms;
    
    import javax.annotation.Resource;
    import javax.ejb.Local;
    import javax.ejb.Stateful;
    import javax.jms.ConnectionFactory;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.Queue;
    import javax.jms.QueueConnection;
    import javax.jms.QueueReceiver;
    import javax.jms.QueueSession;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    
    @Stateful
    @Local(MessageReceiverLocal.class)
    public class MessageReceiver implements MessageReceiverLocal, MessageListener {
        @Resource(mappedName = "ConnectionFactory")
        private ConnectionFactory connectionFactory;
    
        private QueueConnection connection;
    
        @Override
        public void start(String queueName) throws JMSException, NamingException {
            Context initialContext = new InitialContext();
    
            connection = (QueueConnection) connectionFactory.createConnection();
            QueueSession session = (QueueSession) connection.createSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            Queue queue = (Queue) initialContext.lookup(queueName);
            QueueReceiver receiver = session.createReceiver(queue);
            receiver.setMessageListener(this);
            connection.start();
        }
    
        @Remove
        @Override
        public void stop() throws JMSException {
            connection.stop();
            connection.close();
        }
    
        @Override
        public void onMessage(Message message) {
            // handle message here
        }
    
    }
    

    使用单例进行测试:

    package com.example.statefuljms;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import javax.ejb.EJB;
    import javax.ejb.Singleton;
    import javax.ejb.Startup;
    import javax.jms.JMSException;
    import javax.naming.NamingException;
    
    @Startup
    @Singleton
    public class Test {
        @EJB
        private MessageReceiverLocal messageReceiver;
    
        @PostConstruct
        public void run() {
            messageReceiver.start("/queue/myQueue");
        }
    
        @PreDestroy
        public void cleanup() {
            messageReceiver.stop();
        }
    }
    

    【讨论】:

    • 很遗憾在 jboss 中不起作用:原因:javax.jms.IllegalStateException:此方法不适用于应用程序服务器内部。请参阅 J2EE 规范,例如org.hornetq.ra.HornetQRAMessageConsumer.setMessageListener(HornetQRAMessageConsumer.java:125) 中 org.hornetq.ra.HornetQRASession.checkStrict(HornetQRASession.java:1457) 中的 J2EE1.4 第 6.6 节
    猜你喜欢
    • 2020-08-14
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 2013-05-16
    • 2016-03-31
    • 2011-10-05
    • 1970-01-01
    • 2015-06-20
    相关资源
    最近更新 更多