问题
I am trying to create simple Webapp to demonstrate the using WMQ 7.5 in Servlet Container (tomcat). My webbap is based on standalone WMQ sample app. My standalone app works good.
The testcase is also good.
@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);
}
}
But when I am starting tomcat I have the following issue:
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)
......
Please tell me what's the problem. How can I resolve it? Whe it need to be fixed: in tomcat or websphere MQ or spring jms? I was trying to work with jetty but it was fail.
My 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 Initializer
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("/");
}
}
Thanks a lot. Sorry for my English
回答1:
Does the final war include the MQ jar files? I think its a problem with the build where the IBM MQ jar files are missing and hence ClassNotFoundException.
I suggest, go with a filesystem repository for maven instead of directly linking to the source with systempath. Refer Maven: add a dependency to a jar by relative path. Add MQ Jars to this repository and add these as dependencies in your POM.
Another option is to use the shared classloader in catalina.properties. Here you can load the MQ jars directly from /opt/mqm/java/lib.
来源:https://stackoverflow.com/questions/30710138/classnotfoundexception-com-ibm-mq-jms-mqconnectionfactory-websphere-mq-7-5-s