问题
I am updating Spring from 4.x.x to Spring 5.0.3. The project uses ActiveMQ version 5.15.3. When I try to deploy the application with the newest version of Spring I get this error:
Caused by: java.lang.NoSuchMethodError: org.springframework.web.servlet.handler.AbstractHandlerMapping.obtainApplicationContext()Lorg/springframework/context/ApplicationContext;
at org.springframework.web.servlet.handler.AbstractHandlerMapping.detectMappedInterceptors(AbstractHandlerMapping.java:269)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.initApplicationContext(AbstractHandlerMapping.java:243)
at org.springframework.web.servlet.handler.SimpleUrlHandlerMapping.initApplicationContext(SimpleUrlHandlerMapping.java:102)
at org.springframework.context.support.ApplicationObjectSupport.initApplicationContext(ApplicationObjectSupport.java:120)
at org.springframework.web.context.support.WebApplicationObjectSupport.initApplicationContext(WebApplicationObjectSupport.java:77)
at org.springframework.context.support.ApplicationObjectSupport.setApplicationContext(ApplicationObjectSupport.java:74)
at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:121)
at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:97)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
... 53 more
I noticed that ActiveMQ has Spring version "4.3.9" as a dependency. This version does not have the method "obtainApplicationContext" in "AbstractHandlerMapping" and hence the problem. Is there a way exclude the Spring libraries from the activemq-all bundle?
回答1:
I thought this was my problem too but I eventually got my Spring webapp deployed on TomEE to successfully connect and use ActiveMQ hosted and running internally to that Tomcat container.
I'm using Spring 5.0.3-RELEASE and activemq-client 5.15.3. I didn't need everything in the maven shaded uber jar activemq-all.
@Configuration
public class MyConfig {
@Bean
public SingleConnectionFactory connectionFactory() {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
((ActiveMQConnectionFactory) connectionFactory)
// See http://activemq.apache.org/objectmessage.html why we set trusted packages
.setTrustedPackages(new ArrayList<String>(Arrays.asList("com.mydomain", "java.util")));
return new SingleConnectionFactory(connectionFactory);
}
@Bean
@Scope("prototype")
public JmsTemplate jmsTemplate() {
return new JmsTemplate(connectionFactory());
}
@Bean
public Queue myQueue() throws JMSException {
Connection connection = connectionFactory().createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("message-updates");
return queue;
}
}
@Component
public class MyQueueImpl implements MyQueue {
@Inject
private JmsTemplate jmsTemplate;
@Inject
private Queue myQueue;
@PostConstruct
public void init() {
jmsTemplate.setReceiveTimeout(JmsTemplate.RECEIVE_TIMEOUT_NO_WAIT);
}
@Override
public void enqueue(Widget widget) {
jmsTemplate.send(myQueue, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
return session.createObjectMessage(widget);
}
});
}
@Override
public Optional<Widget> dequeue() {
Optional<Widget> widget = Optional.empty();
ObjectMessage message = (ObjectMessage) jmsTemplate.receive(myQueue);
try {
if (message != null) {
widget = Optional.ofNullable((Widget) message.getObject());
message.acknowledge();
}
} catch (JMSException e) {
throw new UncategorizedJmsException(e);
}
return widget;
}
}
回答2:
Thanks Matthew K above. I found that too. ActiveMQ-all have packed a version of spring (currently that 4.x version) inside. There are some none-backwards compatible changes between that and spring v.5. I came across a new method in one of the other spring classes myself. It can cause this kind of issue (no such method exception in my case). I had this issue with activeMQ 5.15.4 and spring 5.0.7. In the end I solved it with using the finer grained jars instead. I had to use all these: activemq-broker,activemq-client,activemq-pool,activemq-kahadb-store,activemq-spring
来源:https://stackoverflow.com/questions/48652986/activemq-all-5-15-3-does-not-work-with-spring-5