首页 > 解决方案 > ClassCastException:org.apache.activemq.ra.ActiveMQConnectionFactory 不能转换为 javax.jms.ConnectionFactory

问题描述

我在启动基于 Spring Boot 应用程序的 JMS 客户端时遇到了一些问题。正如您在堆栈跟踪中看到的:

 Error creating bean with name 'connectionFactory' defined in class path resource [com/configuration/JMSConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'connectionFactory' threw exception; nested exception is java.lang.ClassCastException: org.apache.activemq.ra.ActiveMQConnectionFactory cannot be cast to javax.jms.ConnectionFactory
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:754)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
        at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
        at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
        at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:86)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
        at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:192)
        at io.undertow.servlet.core.DeploymentManagerImpl$1.call(DeploymentManagerImpl.java:174)
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:42)
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
        at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1501)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1501)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1501)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1501)
        at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1501)
        at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:239)
        ... 8 more
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myFactory' defined in class path resource [com/configuration/JMSConfiguration.class]: Unsatisfied dependency expressed through method 'myFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [com/configuration/JMSConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'connectionFactory' threw exception; nested exception is java.lang.ClassCastException: org.apache.activemq.ra.ActiveMQConnectionFactory cannot be cast to javax.jms.ConnectionFactory
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.jms.annotation.JmsListenerAnnotationBeanPostProcessor.processJmsListener(JmsListenerAnnotationBeanPostProcessor.java:272)
        at org.springframework.jms.annotation.JmsListenerAnnotationBeanPostProcessor.postProcessAfterInitialization(JmsListenerAnnotationBeanPostProcessor.java:224)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1588)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
        ... 35 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connectionFactory' defined in class path resource [com/configuration/JMSConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'connectionFactory' threw exception; nested exception is java.lang.ClassCastException: org.apache.activemq.ra.ActiveMQConnectionFactory cannot be cast to javax.jms.ConnectionFactory
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1128)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1022)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:512)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:207)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1131)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1059)
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
        ... 49 more
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.jms.ConnectionFactory]: Factory method 'connectionFactory' threw exception; nested exception is java.lang.ClassCastException: org.apache.activemq.ra.ActiveMQConnectionFactory cannot be cast to javax.jms.ConnectionFactory
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
        ... 62 more
Caused by: java.lang.ClassCastException: org.apache.activemq.ra.ActiveMQConnectionFactory cannot be cast to javax.jms.ConnectionFactory
        at com.configuration.JMSConfiguration.connectionFactory(JMSConfiguration.java:67)
        at com.configuration.JMSConfiguration$$EnhancerBySpringCGLIB$$dbf0619f.CGLIB$connectionFactory$0(<generated>)
        at com.configuration.JMSConfiguration$$EnhancerBySpringCGLIB$$dbf0619f$$FastClassBySpringCGLIB$$fdd15aa6.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
        at com.configuration.JMSConfiguration$$EnhancerBySpringCGLIB$$dbf0619f.connectionFactory(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
        ... 63 more

当 Spring 尝试创建 Connection 工厂时,会抛出 ClassCastException。我不明白为什么。也许我忘记了什么。我在属性文件中输入了我在 jboss 中使用的连接工厂的名称:

jndi-name-connection-factory=java:/ConnectionFactory

正如您在standalone.xml 文件中看到的:

<subsystem xmlns="urn:jboss:domain:resource-adapters:5.0">
            <resource-adapters>
                <resource-adapter id="org.apache.activemq.ra">
                    <module slot="main" id="org.apache.activemq"/>
                    <transaction-support>XATransaction</transaction-support>
                    <config-property name="ServerUrl">
                        failover:(tcp://host:port,tcp://host2:port)?randomize=false&amp;timeout=10000&amp;jms.sendTimeout=2000&amp;maxReconnectDelay=10000
                    </config-property>
                    <config-property name="UseInboundSession">
                        false
                    </config-property>
                    <connection-definitions>
                        <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ConnectionFactory" enabled="true" use-java-context="true" pool-name="ActiveMQConnectionFactoryPool" use-ccm="true">
                            <xa-pool>
                                <min-pool-size>2</min-pool-size>
                                <max-pool-size>50</max-pool-size>
                            </xa-pool>
                            <validation>
                                <background-validation>false</background-validation>
                                <background-validation-millis>30000</background-validation-millis>
                                <use-fast-fail>false</use-fast-fail>
                            </validation>
                            <recovery no-recovery="true">
                                <recover-credential>
                                    <user-name>user</user-name>
                                    <password>psw</password>
                                </recover-credential>
                            </recovery>
                        </connection-definition>
                    </connection-definitions>
                    <admin-objects>

而且,它在我的配置类中使用,如您所见:

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.*;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.support.converter.MarshallingMessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jmx.support.MBeanServerConnectionFactoryBean;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.naming.InitialContext;
import javax.naming.NamingException;


@EnableJms
@Configuration
@EnableAutoConfiguration
@PropertySources({
        @PropertySource("classpath:conf/application.properties")
})
public class JMSConfiguration {

    @Value("${activemq.broker.connector}")
    private String connector;

    @Value("${jndi-name-connection-factory}")
    private String factory;

    @Bean
    public ConnectionFactory connectionFactory() throws NamingException{

        ConnectionFactory connectionFactory = InitialContext.doLookup(factory);
        return connectionFactory;
    }

    @Bean
    public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setMessageConverter(messageConverter());
        // This provides all boot's default to this factory, including the message converter
        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        return factory;
    }


    @Bean
    public Queue jndiDataSource() throws IllegalArgumentException,
            NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();           // create JNDI data source
        bean.setJndiName(factory);  // jndiDataSource is name of JNDI data source
        bean.setProxyInterface(Queue.class);
        bean.setLookupOnStartup(false);
        bean.afterPropertiesSet();
        return (Queue) bean.getObject();
    }


    //@Bean
    MessageConverter messageConverter() {
        MarshallingMessageConverter converter = new MarshallingMessageConverter();
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setClassesToBeBound(Notification.class);
        converter.setMarshaller(marshaller);
        //converter.unmarshaller = marshaller()
        // set this converter on the implicit Spring JMS template

        return converter;
    }
}

我也尝试使用 ActiveMQConnectionFactory 而不是 ConnectionFactory,但应用程序无法进行此转换。

另外,这是我的 pom.xml:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.2.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.4</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.8.0</version>
        </dependency>
        <!--<dependency>-->
        <!--<groupId>mysql</groupId>-->
        <!--<artifactId>mysql-connector-java</artifactId>-->
        <!--<version>5.1.35</version>-->

        <!--</dependency>-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.sonatype.plugins</groupId>
                <artifactId>nexus-staging-maven-plugin</artifactId>
                <version>1.5.1</version>
                <executions>
                    <execution>
                        <id>default-deploy</id>
                        <phase>deploy</phase>
                        <goals>
                            <goal>deploy</goal>
                        </goals>
                    </execution>
                </executions>

                <configuration>
                    <serverId>nexus</serverId>
                    <nexusUrl>https://nexus.bmeme.cloud</nexusUrl>
                    <skipStaging>true</skipStaging>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <webResources>
                        <resource>
                            <!-- this is relative to the pom.xml directory -->
                            <directory>${project.basedir}/src/main/resources/meta
                            </directory>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
        </plugins>

        <!--   <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <executable>true</executable>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>jaxb2-maven-plugin</artifactId>
                        <version>2.2</version>
                        <executions>
                            <execution>
                                <id>adapter-schema</id>
                                <goals>
                                    <goal>xjc</goal>
                                </goals>
                                <configuration>
                                    <sources>
                                        <source>src/main/resources/xsd</source>
                                    </sources>
                                    <xjbSources>
                                        <xjbSource>src/main/resources/xjb</xjbSource>
                                    </xjbSources>

                                    <packageName>com.core.bean.generated</packageName>
                                    <extension>true</extension>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
           -->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <excludes>
                    <exclude>xsd/**</exclude>
                    <exclude>3rd-party-lib/**</exclude>
                    <!-- <exclude>bip-batch-adapter/**</exclude> -->
                </excludes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>
</project>

标签: javaspringjbossactivemq

解决方案


推荐阅读