无法在tomcat上使用ActiveMQ消息

无法在tomcat上使用ActiveMQ消息,tomcat,jakarta-ee,jms,activemq,jndi,Tomcat,Jakarta Ee,Jms,Activemq,Jndi,我正在尝试在ApacheTomcat中配置ApacheActiveMQ。我有两个war文件,MessageProducer.war和MessageConsumer.war。我在这两个项目的/WebContent/WEB-INF/lib文件夹中添加了所有ActiveMQ依赖项jar。我添加了在两个WAR的context.xml文件中配置的以下资源。context.xml文件放在/WebContent/META-INF/文件夹中 Context.xml <Context> <Res

我正在尝试在ApacheTomcat中配置ApacheActiveMQ。我有两个war文件,MessageProducer.war和MessageConsumer.war。我在这两个项目的/WebContent/WEB-INF/lib文件夹中添加了所有ActiveMQ依赖项jar。我添加了在两个WAR的context.xml文件中配置的以下资源。context.xml文件放在/WebContent/META-INF/文件夹中

Context.xml

<Context>
<Resource
        name="myConFactory"
        auth="Container"
        type="org.apache.activemq.ActiveMQConnectionFactory"
        description="JMS Connection Factory"
        factory="org.apache.activemq.jndi.JNDIReferenceFactory"
        brokerURL="vm://localhost"
        brokerName="LocalActiveMQBroker"
        useEmbeddedBroker="true"/>

 <Resource name="jms/myTopic"
          auth="Container"
          type="org.apache.activemq.command.ActiveMQTopic"
          factory="org.apache.activemq.jndi.JNDIReferenceFactory"
          physicalName="com.myproject.TOPIC"/>
 </Context>
我已经在Tomcat v7上部署了MessageProducer.war

MessageConsumer.java文件位于MessageConsumer.war中,将使用MessageProducer发布的消息。以下是相同的代码:

try {
Properties props = new Properties();
props.put(Context.INITIAL_CONTEXT_FACTORY,
             "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
props.put(Context.PROVIDER_URL,"vm://localhost");
Context context = new InitialContext(props);
TopicConnectionFactory factory = (TopicConnectionFactory) 
context.lookup("java:comp/env/myConFactory");
TopicConnection connection = factory.createTopicConnection();
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
Topic topic = (Topic) context.lookup("java:comp/env/jms/myTopic");
publisher = session.createPublisher(topic);
TextMessage tm = session.createTextMessage();
tm.setText("Sending Message with ActiveMQ");
publisher.publish(tm);
}
catch(Exceptione e) {
e.printStackTrace();
}
public class MessageConsumer extends HttpServlet  {
public TopicSession session = null;
public TopicConnection connection = null;
Topic topic = null;
TopicSubscriber subscriber = null;

    public void init() {
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY,
            "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
    props.put(Context.PROVIDER_URL, "vm://localhost");
    Context context = null;
    try {
        context = new InitialContext(props);
        TopicConnectionFactory factory = null;
        factory = (TopicConnectionFactory) context.
        lookup("java:comp/env/myConFactory");
        connection = factory.createTopicConnection();
        connection.setClientID("DURABLE_SUBSCRIBER_ID");
        session = connection.createTopicSession(false,
        Session.AUTO_ACKNOWLEDGE);
        topic = (Topic) context.lookup("java:comp/env/jms/myTopic");
        subscriber = session.createDurableSubscriber(topic, 
        "DURABLE_SUBSCRIBER");
        connection.start();
        TextMessage tm = (TextMessage) subscriber.receive(3000);
        String strMsgRecieved = tm.getText();
    } catch (NamingException | JMSException e) {
        e.printStackTrace();
    }
   }
 }
我已将MessageConsumer类配置为在web.xml中启动时运行,如下所示

<servlet>
    <servlet-name>startupServelt</servlet-name>
    <servlet-class>com.myproject.MessageConsumer</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

startupServelt
com.myproject.MessageConsumer
0

我已经在TomcatV8上部署了MessageConsumer.war。Tomcat v7和v8都运行在同一台物理机器和同一个JVM上。当我启动MessageProducer.war runnning时,它将消息发布到我可以通过JConsole看到的主题。但当我启动MessageConsumer war时,它将显示100%启动ApacheTomcat,持续无限时间。它不会继续下去。它不会在Tomcat控制台上显示任何异常或任何内容,也不会使用已发布的消息。请让我知道我做错了什么或为什么它不工作。

启动时加载没问题

启动时,您的
startupServelt
将只侦听一条消息,您需要在订阅服务器上循环。接收(3000)在另一个线程中,或使用
MessageListener

您有tomcat启动或activemq的任何其他日志

您可以说:对于这两个Tomcat,我已经将JRE8配置为默认使用。所以两者都使用相同的JVM!! 因此,两者都使用相同的JVM版本,但运行的JVM不同。 我认为这就是问题所在,MessageConsumer.war在Tomcat v8上运行,在v8上使用来自AMQ的消息,在Tomcat v7上使用MessageProducer.war并在v7上向AMQ发送消息。由于这个原因,一切正常,您可以看到生产者生成消息,但消费者没有收到任何消息,因为它位于生产者之外的另一个JVM中,并且没有生产者向其代理发送消息

您需要在同一个Tomcat上部署两个应用程序才能使其正常工作

Tomcat v7和v8都运行在同一台物理机器上,并且相同 JVM

我不确定两个Tomcat实例如何在同一个JVM上运行。它们可以使用相同的JDK,是的,它们也可以在相同的物理机器上运行,但它们不会在相同的JVM上。他们都会独立地启动自己的JVM


在您的例子中,您使用的是ActiveMQ嵌入式代理,根据文档,它允许“客户机在VM内相互连接”。在你的情况下,我认为,这不是同一个虚拟机。正在查找消息的消息使用者正在查看的ActiveMQ实例与消息生产者发送消息的对象不同

我同意您的评论,即startupServlet在启动期间只消耗一条消息。我需要循环来继续消费。但在我的情况下,它甚至不消耗第一条信息。它只是继续在eclipse底部显示消息,“100%启动Tomcat服务器”。控制台上没有异常。没有理由出现异常,因为您在启动时加载了0个startupServelt实例!!将0更改为1或通过http请求调用startupServelt来启动它。您如何确定这两个Apache实例在同一JVM上运行?@AdityaK您在哪里看到我确定这两个Apache实例在同一JVM上运行?@HassenBennour我在寻址Babanna Duggani。对不起,我应该说得更清楚些。我错误地在你的回答中加了这个作为评论。我应该把这句话作为对问题的评论。不。对于这两个Tomcat,我已将JRE8配置为默认使用。所以两者都使用相同的JVM。@Babananduggani AdityaK完全正确,您已经将Tomcat配置为使用JRE8版本,但这并不意味着相同的JVM@BabannaDuggani如果您在两个不同的环境中使用相同的JRE,这并不意味着您在使用相同的JVM!每个服务器实例将产生自己的JVM,它们将彼此独立工作。它们将是操作系统级别的两个独立进程。你的情况也是如此。
<servlet>
    <servlet-name>startupServelt</servlet-name>
    <servlet-class>com.myproject.MessageConsumer</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>