英文:
Exception Caused by: java.lang.ClassNotFoundException: jakarta.jms.ConnectionFactory
问题
I want to use a Spring Boot Apache Camel application to get a message on IBM MQ. I am currently setting up the JMS connection, but I receive an error about a class not found. I thought it had something to do with dependencies so I tried a lot of different things, but the error stays the same.
import com.ibm.mq.MQEnvironment;
import com.ibm.msg.client.wmq.common.CommonConstants;
//import org.apache.camel.component.jms.JmsComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import org.springframework.jms.annotation.EnableJms;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.net.ssl.*;
import java.security.KeyStore;
@EnableJms
@Configuration
public class JmsConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(JmsComponent.class);
private String host = "xxx";
private int port = 4510;
private String queueManager = "xxx";
private String channel = "xxx";
//private String username = "";
//private String password = "";
private String sslCipherSuite = "TLS_RSA_WITH_AES_256_CBC_SHA256";
@Value("${keyStore}")
private String keyStore;
@Value("${keyStorePassword}")
private String keyStorePassword;
@Value("${trustStore}")
private String trustStore;
@Value("${trustStorepassword}")
private String trustStorePassword;
@Bean
public JmsComponent mq() {
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConnectionFactory(mqQueueConnectionFactory());
return jmsComponent;
}
@Bean
public MQQueueConnectionFactory mqQueueConnectionFactory() {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(host);
try {
//Load trust store
//System.setProperty("javax.net.ssl.trustStore", trustStore);
//System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
//Load keystore
//System.setProperty("javax.net.ssl.keyStore", keyStore);
//System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
//keystore fetch
String keystoreKey = "${keyStorePassword}";
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("${keyStore}"),
keystoreKey.toCharArray());
// Create key manager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, keystoreKey.toCharArray());
KeyManager[] km = keyManagerFactory.getKeyManagers();
// Create trust manager
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager[] tm = trustManagerFactory.getTrustManagers();
// Initialize SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(km, tm, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setChannel(channel);
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setObjectProperty(WMQConstants.WMQ_SSL_SOCKET_FACTORY, sslSocketFactory);
mqQueueConnectionFactory.setSSLCipherSuite(sslCipherSuite);
mqQueueConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setTransportType(CommonConstants.WMQ_CM_BINDINGS);
MQEnvironment.sslSocketFactory = sslSocketFactory;
} catch (Exception e) {
e.printStackTrace();
}
return mqQueueConnectionFactory;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>nl.test</groupId>
<artifactId>Testapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Testapp</name>
<description>Testapp</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>4.0.0-M3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jms-starter</artifactId>
<version>4.0.0-M3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is the stacktrace:
java.lang.NoClassDefFoundError: jakarta/jms/ConnectionFactory
at java.base/java.lang.Class.getDeclaredFields0(Native Method) ~[na:na]
at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3353) ~[na:na]
<details>
<summary>英文:</summary>
I want to use a Spring Boot Apache Camel application to get a message on IBM MQ. I am currently setting up the JMS connection, but I receive an error about a class not found. I thought it had something to do with dependencies so I tried a lot of different things, but the error stays the same.
```java
import com.ibm.mq.MQEnvironment;
import com.ibm.msg.client.wmq.common.CommonConstants;
//import org.apache.camel.component.jms.JmsComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import org.springframework.jms.annotation.EnableJms;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.net.ssl.*;
import java.security.KeyStore;
@EnableJms
@Configuration
public class JmsConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(JmsComponent.class);
private String host = "xxx";
private int port = 4510;
private String queueManager = "xxx";
private String channel = "xxx";
//private String username = "";
//private String password = "";
private String sslCipherSuite = "TLS_RSA_WITH_AES_256_CBC_SHA256";
@Value("${keyStore}")
private String keyStore;
@Value("${keyStorePassword}")
private String keyStorePassword;
@Value("${trustStore}")
private String trustStore;
@Value("${trustStorepassword}")
private String trustStorePassword;
@Bean
public JmsComponent mq() {
JmsComponent jmsComponent = new JmsComponent();
jmsComponent.setConnectionFactory(mqQueueConnectionFactory());
return jmsComponent;
}
@Bean
public MQQueueConnectionFactory mqQueueConnectionFactory() {
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
mqQueueConnectionFactory.setHostName(host);
try {
//Load trust store
//System.setProperty("javax.net.ssl.trustStore", trustStore);
//System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword);
//Load keystore
//System.setProperty("javax.net.ssl.keyStore", keyStore);
//System.setProperty("javax.net.ssl.keyStorePassword", keyStorePassword);
//keystore fetch
String keystoreKey = "${keyStorePassword}";
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("${keyStore}"),
keystoreKey.toCharArray());
// Create key manager
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, keystoreKey.toCharArray());
KeyManager[] km = keyManagerFactory.getKeyManagers();
// Create trust manager
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(keyStore);
TrustManager[] tm = trustManagerFactory.getTrustManagers();
// Initialize SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1");
sslContext.init(km, tm, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
mqQueueConnectionFactory.setPort(port);
mqQueueConnectionFactory.setChannel(channel);
mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setObjectProperty(WMQConstants.WMQ_SSL_SOCKET_FACTORY, sslSocketFactory);
mqQueueConnectionFactory.setSSLCipherSuite(sslCipherSuite);
mqQueueConnectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);
mqQueueConnectionFactory.setTransportType(CommonConstants.WMQ_CM_BINDINGS);
MQEnvironment.sslSocketFactory = sslSocketFactory;
} catch (Exception e) {
e.printStackTrace();
}
return mqQueueConnectionFactory;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>nl.test</groupId>
<artifactId>Testapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Testapp</name>
<description>Testapp</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
<version>4.0.0-M3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-jms-starter</artifactId>
<version>4.0.0-M3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.1.0.5</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>jakarta.jms</groupId>
<artifactId>jakarta.jms-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
This is the stacktrace:
java.lang.NoClassDefFoundError: jakarta/jms/ConnectionFactory
at java.base/java.lang.Class.getDeclaredFields0(Native Method) ~[na:na]
at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3353) ~[na:na]
at java.base/java.lang.Class.getDeclaredField(Class.java:2661) ~[na:na]
at org.springframework.boot.context.properties.bind.DefaultBindConstructorProvider$Constructors.isInnerClass(DefaultBindConstructorProvider.java:145) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.bind.DefaultBindConstructorProvider$Constructors.getCandidateConstructors(DefaultBindConstructorProvider.java:135) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.bind.DefaultBindConstructorProvider$Constructors.getConstructors(DefaultBindConstructorProvider.java:103) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.bind.DefaultBindConstructorProvider.getBindConstructor(DefaultBindConstructorProvider.java:55) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.ConfigurationPropertiesBean.deduceBindMethod(ConfigurationPropertiesBean.java:328) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrar.createBeanDefinition(ConfigurationPropertiesBeanRegistrar.java:93) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrar.registerBeanDefinition(ConfigurationPropertiesBeanRegistrar.java:89) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrar.register(ConfigurationPropertiesBeanRegistrar.java:61) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.context.properties.ConfigurationPropertiesBeanRegistrar.register(ConfigurationPropertiesBeanRegistrar.java:55) ~[spring-boot-3.0.8.jar:3.0.8]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.boot.context.properties.EnableConfigurationPropertiesRegistrar.registerBeanDefinitions(EnableConfigurationPropertiesRegistrar.java:49) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.context.annotation.ImportBeanDefinitionRegistrar.registerBeanDefinitions(ImportBeanDefinitionRegistrar.java:86) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:373) ~[spring-context-6.0.10.jar:6.0.10]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:729) ~[na:na]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:372) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:148) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:427) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:287) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:771) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:589) ~[spring-context-6.0.10.jar:6.0.10]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1304) ~[spring-boot-3.0.8.jar:3.0.8]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1293) ~[spring-boot-3.0.8.jar:3.0.8]
at nl.rabobank.mqputter.MqPutterApplication.main(MqPutterApplication.java:10) ~[classes/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.0.8.jar:3.0.8]
Caused by: java.lang.ClassNotFoundException: jakarta.jms.ConnectionFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
... 35 common frames omitted
答案1
得分: 4
至少你需要在你的应用程序类路径中包含Jakarta Messaging API的jar包。
你可能还需要升级你的IBM MQ客户端到9.3版本,因为它支持Jakarta Messaging(即jakarta.jms.*
中的类)。
英文:
At the very least you need to include the Jakarta Messaging API jar in your application's classpath.
You may also need to upgrade your IBM MQ client to 9.3 as it supports Jakarta Messaging (i.e. classes in jakarta.jms.*
).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论