简体   繁体   English

Spring JMS侦听器容器未完全停止

[英]Spring JMS Listener Container not stopping fully

I have weird problem with a JMS Listener container. 我对JMS侦听器容器有奇怪的问题。 In case I stop the listener container, half of messages are still delivered to the app and processed by listener. 万一我停止了监听器容器,一半的消息仍会传递到应用程序并由监听器处理。 Here is my deployment descriptor: 这是我的部署描述符:

  <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/jms-config.xml,WEB-INF/root-context.xml</param-value>      
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

Here is my Spring configuration: 这是我的Spring配置:

<context:component-scan base-package="com.con.*" />


    <bean   class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />


    <!-- Web methods environment mappings -->

    <bean id="webMethodProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="file:/opt/app/jboss/current/modules/com/con/commons/logconfiguration/main/webmethods.properties" />
    </bean> 


    <bean id="intialContext" class="javax.naming.InitialContext">
    <constructor-arg>

            <map>
                <entry key="java.naming.factory.initial" value="${java.naming.factory.initial}" />
                <entry key="java.naming.provider.url" value="${java.naming.provider.url}" />
                <entry key="com.webmethods.jms.naming.clientgroup" value="${com.webmethods.jms.naming.clientgroup}" />
            </map>

        </constructor-arg>
    </bean>
    <!-- JNDI Template for accessing Web Method resources -->
    <bean id="webMethodsJndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
            <map>
                <entry key="java.naming.factory.initial" value="${java.naming.factory.initial}" />
                <entry key="java.naming.provider.url" value="${java.naming.provider.url}" />
                <entry key="com.webmethods.jms.naming.clientgroup" value="${com.webmethods.jms.naming.clientgroup}" />
            </map>
        </property>
    </bean>
    <bean id="destinationResolver"
        class="org.springframework.jms.support.destination.JndiDestinationResolver">
        <property name="jndiTemplate" ref="webMethodsJndiTemplate" />
        <property name="cache" value="true" />
        <property name="fallbackToDynamicDestination" value="false" />
    </bean>

    <!-- Custom ConnectionFactory to customize ClientId -->
    <bean id="remoteJmsConnectionFactory"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="connectionFactoryHelper"/>
        <property name="targetMethod" value="createJmsConnectionFactory"/>
    </bean>

    <!-- JMS MDB Container which recieves messages from Vantage S -->

    <jms:listener-container container-type="default"
        connection-factory="remoteJmsConnectionFactory" destination-type="durableTopic"
        destination-resolver="destinationResolver" acknowledge="auto">
        <jms:listener destination="beconEventingJMSTopic" ref="beconListener" id="jmslistener"
            selector="${scrmessageselector}" subscription="${screventingsubscriber}"
            method="onMessage" />
    </jms:listener-container>

    <bean id="beconListener" class="com.con.jms.OMIListener"/>

</beans>

Trying to start listener here 尝试在此处启动监听器

@Controller
public class StartJmsController {

    @Resource(name="jmslistener")
    private DefaultMessageListenerContainer beconListener;

    @RequestMapping("/startscrjms")
    public String hello(
            @RequestParam(value = "name", required = false, defaultValue = "World") String name,
            Model model) {

        beconListener.start();
        model.addAttribute("message", "JMS Listener started.");
        return "jmsmessage";
    }

}

Stop Listener here. 在此处停止侦听器。

@Controller

public class StopJmsController {

    @Resource(name="jmslistener")
    private DefaultMessageListenerContainer beconListener;

    @RequestMapping("/stopscrjms" ) 
    public String printWelcome(ModelMap model,  HttpSession session) {

        beconListener.stop(new Runnable() {
            public void run() {
                System.out.println("JMS Listener stopped.");
            }
        });

        model.addAttribute("message", "JMS Listener stopped.");
        return "jmsmessage";

    }

}

root-context.xml 根的context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- Empty -->

</beans>

pom.xml 的pom.xml

   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>WebMethodTopicSubscriber</groupId>
        <artifactId>OMISCRPayLoad</artifactId>
        <version>1.0</version>
        <packaging>war</packaging>
        <dependencies>
            <dependency>
                <groupId>com.wm.g11n</groupId>
                <artifactId>wm-g11nutils</artifactId>
                <version>8.2.2.4</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.webmethods.jms</groupId>
                <artifactId>wm-brokerclient</artifactId>
                <version>8.2.3</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.webmethods.jms</groupId>
                <artifactId>wm-jmsnaming</artifactId>
                <version>8.2.2</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.webmethods.jms</groupId>
                <artifactId>wm-jmsclient</artifactId>
                <version>8.2.2.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>antlr</groupId>
                <artifactId>antlr</artifactId>
                <version>2.7.7</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>aopalliance</groupId>
                <artifactId>aopalliance</artifactId>
                <version>1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>3.2.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-dbcp</groupId>
                <artifactId>commons-dbcp</artifactId>
                <version>1.4</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.1.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>commons-pool</groupId>
                <artifactId>commons-pool</artifactId>
                <version>1.6</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifactId>
                <version>1.6.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.logicblaze.fuse.liferay.dependencies</groupId>
                <artifactId>jms</artifactId>
                <version>fuse-4.1.2</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.quartz-scheduler</groupId>
                <artifactId>quartz</artifactId>
                <version>2.2.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-expression</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jms</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-orm</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.0.3.RELEASE</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.con.commons</groupId>
                <artifactId>Configuration</artifactId>
                <version>1.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
              <groupId>org.apache.logging.log4j</groupId>
              <artifactId>log4j-api</artifactId>
              <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.1</version>
        </dependency>   
            <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
             <scope>provided</scope>
        </dependency>
        </dependencies>

    <build>
         <sourceDirectory>src/main/java</sourceDirectory>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <filtering>true</filtering>
            <includes>
              <include>**/*.xml</include>          
            </includes>
          </resource>     
        </resources>

            <plugins>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <warSourceDirectory>WebContent</warSourceDirectory>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>


          </plugins>
        </build>
    </project>

Read in the blog that probably this is the error " is that you are loading the container into both the web context (DispatcherServlet's context) and the root context (ContextLoaderListener's context). Which means you have 2 containers and you are only stopping the one in the servlet context" 在博客中读到“这可能是错误”,因为您正在将容器加载到Web上下文(DispatcherServlet的上下文)和根上下文(ContextLoaderListener的上下文)中。这意味着您有2个容器,并且仅在其中停止了一个servlet上下文”

Issue is similar Spring JMS Listener Container stop only half of listeners 问题是类似的Spring JMS侦听器容器仅停止一半的侦听器

But fix is not clear in the answer. 但是解决方案尚不清楚。

How can I fix this. 我怎样才能解决这个问题。 ?

In your web.xml change the Dispatcher Servlet definition to below. 在您的web.xml中,将Dispatcher Servlet定义更改为以下内容。

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
                <param-value>WEB-INF/jms-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

And remove the following part. 并删除以下部分。

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/jms-config.xml,WEB-INF/root-context.xml</param-value>      
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Updated as per user comments 根据用户评论更新

The recommended pattern is to have separate context for non web stuff and the web stuff. 推荐的模式是为非Web内容和Web内容分别设置上下文。 But in your case there doesn't seem to be anything in the root context, you can skip it if your app works that way. 但是在您的情况下,根上下文似乎没有任何内容,如果您的应用程序以这种方式工作,则可以跳过它。

In future if you require root scope - say you add ORM support in your app - you could always keep the ContextLoaderListener entry in there with the contextConfigLocation context param with the value as only your root context config file name. 将来,如果您需要根范围(例如,您在应用程序中添加了ORM支持),则始终可以将ContextLoaderListener条目与contextConfigLocation上下文参数一起保留在其中,该值仅作为您的根上下文配置文件名。

As a side note, even if you decide to add the ORM support in your app you could very well do that in the web context and the app should work fine, just that it is not recommended. 附带说明一下,即使您决定在应用程序中添加ORM支持,也可以在Web上下文中很好地做到这一点,并且该应用程序应该可以正常运行,只是不建议这样做。

Update try this. 更新试试这个。

    <servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
                <param-value>WEB-INF/jms-config.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>


<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/root-context.xml</param-value>      
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM