2015-06-08 126 views
0

我想创建一个简单的Webapp来演示在Servlet容器(tomcat)中使用WMQ 7.5。我的webbap基于独立的WMQ示例应用程序。 我的独立应用程序效果不错。ClassNotFoundException:com.ibm.mq.jms.MQConnectionFactory(Websphere MQ 7.5 + spring jms + maven tomcat 7插件)

该测试用例也不错。

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = AppConfig.class) 
public class MQMessageTest { 

    /** 
    * Message count fot test 
    */ 
    private static final int MESSAGE_COUNT = 25; 

    /** 
    * Setting Environment for getting properties 
    */ 
    @Autowired 
    private Environment environment; 

    /** 
    * MQMessageSender for sending messages 
    */ 
    @Autowired 
    private MQMessageSender mqMessageSender; 

    /** 
    * JmsTemplate of Spring JMS 
    */ 
    @Autowired 
    private JmsTemplate jmsTemplate; 

    @Test 
    public void testEqualsOfSentAndReceivedMessages() { 

     /*Sending messages to Queue*/ 
     for (int i = 0; i < MESSAGE_COUNT; i++) { 
      mqMessageSender.send("Message with" + System.nanoTime()); 
     } 

     /*Container for received messages*/ 
     Set<TextMessage> messages = new HashSet<TextMessage>(); 

     /*Receiving messages from report Queue*/ 
     for (int i = 0; i < MESSAGE_COUNT; i++) { 
      TextMessage message = (TextMessage) jmsTemplate.receive(environment.getRequiredProperty("wmq.queue.test.input.2")); 
      messages.add(message); 
     } 

     assertEquals(messages.size(), MESSAGE_COUNT); 
    } 
} 

但是,当我开始的tomcat我有以下问题:

org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions 
INFO: Registering annotated classes: [class by.iba.config.AppConfig] 
июн 08, 2015 9:29:11 AM org.apache.catalina.core.ApplicationContext log 
SEVERE: StandardWrapper.Throwable 
**java.lang.NoClassDefFoundError: com/ibm/mq/jms/MQConnectionFactory** 
    at java.lang.Class.getDeclaredMethods0(Native Method) 
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615) 
    at java.lang.Class.getDeclaredMethods(Class.java:1860) 
    at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:140) 

... 30 more 

июн 08, 2015 9:29:11 AM org.apache.catalina.core.StandardContext loadOnStartup 
**SEVERE: Servlet /mqservice-webapp threw load() exception 
java.lang.ClassNotFoundException: com.ibm.mq.jms.MQConnectionFactory** 
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702) 

...... 

请告诉我出了什么问题。我该如何解决它?它需要修复:在tomcat或websphere MQ或spring jms中?我正在尝试与码头合作,但它是失败的。

我POM

<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>by.iba</groupId> 
    <artifactId>mqservice-webapp</artifactId> 
    <packaging>war</packaging> 
    <version>1.0-SNAPSHOT</version> 
    <name>Web MQ Module</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <websphereMq.version>7.5.0.2</websphereMq.version> 
     <wmq.jars>${basedir}/lib</wmq.jars> 
     <spring.version>4.0.6.RELEASE</spring.version> 
    </properties> 

    <dependencies> 

     <!--Websphere MQ dependencies--> 

     <dependency> 
      <groupId>com.ibm</groupId> 
      <artifactId>com.ibm.mqjms</artifactId> 
      <version>${websphereMq.version}</version> 
      <scope>system</scope> 
      <systemPath>${wmq.jars}/com.ibm.mqjms.jar</systemPath> 
     </dependency> 

     <dependency> 
      <groupId>com.ibm</groupId> 
      <artifactId>com.ibm.mq.headers</artifactId> 
      <version>${websphereMq.version}</version> 
      <scope>system</scope> 
      <systemPath>${wmq.jars}/com.ibm.mq.headers.jar</systemPath> 
     </dependency> 

     <dependency> 
      <groupId>com.ibm</groupId> 
      <artifactId>com.ibm.mq.jmqi</artifactId> 
      <version>${websphereMq.version}</version> 
      <scope>system</scope> 
      <systemPath>${wmq.jars}/com.ibm.mq.jmqi.jar</systemPath> 
     </dependency> 

     <dependency> 
      <groupId>com.ibm</groupId> 
      <artifactId>com.ibm.dhbcore</artifactId> 
      <version>${websphereMq.version}</version> 
      <scope>system</scope> 
      <systemPath>${wmq.jars}/dhbcore.jar</systemPath> 
     </dependency> 

     <!--Spring--> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-jms</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.apache.geronimo.specs</groupId> 
      <artifactId>geronimo-jms_1.1_spec</artifactId> 
      <version>1.1.1</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-webmvc</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

     <!--Javax Servlet API--> 

     <dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>javax.servlet-api</artifactId> 
      <version>3.1.0</version> 
      <scope>provided</scope> 
     </dependency> 

     <!--Junit--> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.6</version> 
      <scope>test</scope> 
     </dependency> 

    </dependencies> 

    <build> 
     <plugins> 

      <!-- Jetty Plugin --> 

      <!--<plugin>--> 
       <!--<groupId>org.mortbay.jetty</groupId>--> 
       <!--<artifactId>maven-jetty-plugin</artifactId>--> 
       <!--<version>6.1.10</version>--> 
      <!--</plugin>--> 

      <!-- Set JDK Compiler Level --> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>3.3</version> 
       <configuration> 
        <source>1.7</source> 
        <target>1.7</target> 
        <encoding>${project.build.sourceEncoding}</encoding> 
       </configuration> 
      </plugin> 

      <!-- Tomcat Plugin --> 

      <plugin> 
       <groupId>org.apache.tomcat.maven</groupId> 
       <artifactId>tomcat7-maven-plugin</artifactId> 
       <version>2.2</version> 
       <configuration> 
        <server>local_tomcat</server> 
       </configuration> 
      </plugin> 

      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <version>2.4</version> 
       <configuration> 
        <warName>mqservice-webapp</warName> 
        <failOnMissingWebXml>false</failOnMissingWebXml> 
       </configuration> 
      </plugin> 
     </plugins> 
    </build> 

</project> 

WebConfig

@Configuration 
@ComponentScan({"..."}) 
@PropertySource(value = {"classpath:by.iba/wmq.properties"}) 
public class AppConfig { 

    /** 
    * Logger is using for tracing status of the application configuration 
    */ 
    public static final Logger LOGGER = Logger.getLogger(AppConfig.class.getName()); 

    /** 
    * Environment Bean for working with properties 
    */ 
    @Autowired 
    private Environment environment; 

    /** 
    * Method provides setting up the MQConnectionFactory Bean in Binding mode 
    * 
    * @return MQConnectionFactory is set up in binding mode 
    * @throws JMSException if setting up MQConnectionFactory failed 
    */ 
    @Bean 
    public MQConnectionFactory mqBindingConnectionFactory() { 
     MQConnectionFactory connectionFactory = new MQConnectionFactory(); 
     try { 
      connectionFactory.setHostName(environment.getRequiredProperty("wmq.qmgr.host")); 
      connectionFactory.setPort(environment.getProperty("wmq.qmgr.port", Integer.class)); 
      connectionFactory.setQueueManager(environment.getRequiredProperty("wmq.qmgr.name")); 
      connectionFactory.setTransportType(environment.getProperty("wmq.qmgr.transport.type.binding", Integer.class)); 
      connectionFactory.setCCSID(environment.getProperty("wmq.qmgr.ccsid", Integer.class)); 
     } catch (JMSException e) { 
      LOGGER.severe("Cannot set up binding connection factory" + e.getMessage()); 
     } 
     return connectionFactory; 
    } 

    /** 
    * Method provides setting up the MQConnectionFactory Bean in Client mode 
    * 
    * @return MQConnectionFactory is set up in client mode 
    * @throws JMSException if setting up MQConnectionFactory failed 
    */ 
    @Bean 
    public MQConnectionFactory mqClientConnectionFactory() { 
     MQConnectionFactory connectionFactory = new MQConnectionFactory(); 
     try { 
      connectionFactory.setHostName(environment.getRequiredProperty("wmq.qmgr.host")); 
      connectionFactory.setPort(environment.getProperty("wmq.qmgr.port", Integer.class)); 
      connectionFactory.setQueueManager(environment.getRequiredProperty("wmq.qmgr.name")); 
      connectionFactory.setTransportType(environment.getProperty("wmq.qmgr.transport.type.client", Integer.class)); 
      connectionFactory.setCCSID(environment.getProperty("wmq.qmgr.ccsid", Integer.class)); 
      connectionFactory.setChannel(environment.getRequiredProperty("wmq.qmgr.channel")); 
     } catch (JMSException je) { 
      LOGGER.severe("Cannot set up client connection factory" + je.getMessage()); 
     } 
     return connectionFactory; 
    } 

    /** 
    * Method provides setting up Single Connection Factory Bean for using in Binding mode 
    * 
    * @return SingleConnectionFactory 
    */ 
    @Bean 
    public SingleConnectionFactory jmsQueueConnectionFactory() { 
     SingleConnectionFactory singleConnectionFactory = new SingleConnectionFactory(); 
     singleConnectionFactory.setTargetConnectionFactory(mqBindingConnectionFactory()); 
     singleConnectionFactory.setReconnectOnException(true); 
     return singleConnectionFactory; 
    } 

    /** 
    * Method provides setting up UserCredentialsConnectionFactoryAdapter Bean for using in Client mode 
    * 
    * @return UserCredentialsConnectionFactoryAdapter 
    */ 
    @Bean 
    public UserCredentialsConnectionFactoryAdapter jmsQueueConnectionFactorySecured() { 
     UserCredentialsConnectionFactoryAdapter connectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter(); 
     connectionFactoryAdapter.setTargetConnectionFactory(mqClientConnectionFactory()); 
     connectionFactoryAdapter.setUsername(environment.getRequiredProperty("wmq.qmgr.username")); 
     connectionFactoryAdapter.setPassword(environment.getRequiredProperty("wmq.qmgr.password")); 
     return connectionFactoryAdapter; 
    } 

    /** 
    * Method provides setting up CachingConnectionFactory Bean to organize connection pool 
    * 
    * @return CachingConnectionFactory 
    */ 
    @Bean 
    public CachingConnectionFactory cachingConnectionFactory() { 
     CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(); 
     cachingConnectionFactory.setTargetConnectionFactory(jmsQueueConnectionFactorySecured()); 
     cachingConnectionFactory.setCacheConsumers(true); 
     cachingConnectionFactory.setCacheProducers(true); 
     cachingConnectionFactory.setSessionCacheSize(5); 
     return cachingConnectionFactory; 
    } 

    /** 
    * Method provides setting up DynamicDestinationResolver Bean 
    * 
    * @return DynamicDestinationResolver 
    */ 
    @Bean 
    public DynamicDestinationResolver destinationResolver() { 
     return new DynamicDestinationResolver(); 
    } 

    /** 
    * Method provides setting up JmsTemplate Bean 
    * 
    * @return DynamicDestinationResolver 
    */ 
    @Bean 
    public JmsTemplate jmsQueueTemplate() { 
     JmsTemplate jmsTemplate = new JmsTemplate(); 
     jmsTemplate.setConnectionFactory(jmsQueueConnectionFactorySecured()); // optionally switching client mode 
//  jmsTemplate.setConnectionFactory(jmsQueueConnectionFactory()); // optionally switching binding mode 
     jmsTemplate.setDestinationResolver(destinationResolver()); 
     jmsTemplate.setReceiveTimeout(10000); 
     return jmsTemplate; 
    } 

    /** 
    * Method provides setting up MQMessageListener Bean for getting messages 
    * from Websphere MQ and his personal settings 
    * 
    * @return MQMessageListener 
    */ 
    @Bean 
    public MQMessageListener mqMessageListener() { 
     return new MQMessageListener(); 
    } 

    /** 
    * Method provides MQMessageSender Bean for sending messages 
    * to Websphere MQ and his personal settings 
    * 
    * @return @MQMessageSender 
    */ 
    @Bean 
    public MQMessageSender mqMessageSender() { 
     MQMessageSender mqMessageSender = new MQMessageSender(); 
     mqMessageSender.setDestinationQueue(environment.getRequiredProperty("wmq.queue.test.input.1")); 
     mqMessageSender.setForwardQueue(environment.getRequiredProperty("wmq.queue.test.input.2")); 
     return mqMessageSender; 
    } 

    /** 
    * Method provides DefaultMessageListenerContainer Bean for sending messages 
    * 
    * @return DefaultMessageListenerContainer 
    */ 
    @Bean 
    public DefaultMessageListenerContainer jmsListenerContainer() { 
     DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer(); 
     try { 
      dmlc.setConnectionFactory(mqClientConnectionFactory()); // optionally switching client mode 
//   dmlc.setConnectionFactory(mqBindingConnectionFactory()); // optionally switching binding mode 
      dmlc.setConcurrentConsumers(environment.getProperty("wmq.listener.concurrent.consumers", Integer.class)); 
      dmlc.setMessageListener(mqMessageListener()); 
      dmlc.setDestination(new MQDestination(environment.getRequiredProperty("wmq.queue.test.input.1"))); 
     } catch (JMSException je) { 
      LOGGER.severe(je.getMessage()); 
     } 
     return dmlc; 
    } 

} 

WEB初始化程序

public class WebInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); 
     ctx.register(AppConfig.class); 
     ctx.setServletContext(servletContext); 

     ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx)); 
     servlet.setLoadOnStartup(1); 
     servlet.addMapping("/"); 
    } 
} 

非常感谢。对不起,我的英文版

回答

2

最终的战争是否包含MQ jar文件?我认为它是构建IBM MQ jar文件丢失的问题,因此也是ClassNotFoundException。

我建议,去与maven的文件系统存储库,而不是直接链接到源与systempath。请参阅Maven: add a dependency to a jar by relative path。将MQ Jar添加到此存储库,并将这些作为依赖关系添加到您的POM中。

另一种选择是在catalina.properties中使用共享类加载器。在这里,您可以直接从/ opt/mqm/java/lib中加载MQ Jar。

+0

我通过使用gradle而不是maven来解决这个问题。该项目现在非常小。我决定Gradle有更好的机会。附:非常感谢您的回答。你的忠告很好。不幸的是,我无法投票回答你的答案。我没有要点去做。 –