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

时间:2015-03-17 06:08:43

标签: java spring jms spring-jms

我有一个JMS Listener容器的奇怪问题。如果我停止监听器容器,一半的消息仍然传递给应用程序并由侦听器处理。这是我的部署描述符:

  <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>

这是我的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>

尝试在这里启动监听器

@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";
    }

}

在这里停止听众。

@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";

    }

}

根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

   <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>

在博客中读到这可能是错误“是您将容器加载到Web上下文(DispatcherServlet的上下文)和根上下文(ContextLoaderListener的上下文)。这意味着您有2个容器而您只是停止servlet上下文中的那个“

问题类似于Spring JMS Listener Container stop only half of listeners

但答案中的修复并不清楚。

我该如何解决这个问题。 ?

1 个答案:

答案 0 :(得分:1)

在您的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>

删除以下部分。

<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内容和Web内容提供单独的上下文。但是在你的情况下,在根上下文中似乎没有任何东西,如果你的应用程序以这种方式工作,你可以跳过它。

将来,如果您需要根范围 - 比如说您在应用中添加了ORM支持 - 您可以始终使用ContextLoaderListener上下文参数保留contextConfigLocation条目,其值仅为您的根上下文配置文件名。

作为旁注,即使您决定在应用中添加ORM支持,您也可以在网络环境中做到这一点,应用程序应该可以正常工作,只是不建议使用。

<强>更新 试试这个。

    <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>