Tolerate breaking API changes in ActiveMQ 5.11.0

In ActiveMQ 5.11 the signature of
PooledConnectionFactory.setConnectionFactory has changed. It now takes
an Object rather than a ConnectionFactory. This change is not binary
backwards compatible so it causes a NoSuchMethodError as we compile
against 5.10.

This commit updates ActiveMQConnectionFactoryConfiguration to call
the setConnectionFactory method reflectively, looking for both the
ConnectionFactory and Object variants.

Closes gh-2640
This commit is contained in:
Andy Wilkinson 2015-03-16 17:41:38 +00:00
parent 78a00b1658
commit 1f40c8a9ba
2 changed files with 42 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.jms.activemq;
import java.lang.reflect.Method;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
@ -23,6 +25,7 @@ import org.apache.activemq.pool.PooledConnectionFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
/**
* Configuration for ActiveMQ {@link ConnectionFactory}.
@ -30,6 +33,7 @@ import org.springframework.context.annotation.Configuration;
* @author Greg Turnquist
* @author Stephane Nicoll
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.1.0
*/
@Configuration
@ -42,10 +46,31 @@ class ActiveMQConnectionFactoryConfiguration {
properties).createConnectionFactory(ActiveMQConnectionFactory.class);
if (properties.isPooled()) {
PooledConnectionFactory pool = new PooledConnectionFactory();
pool.setConnectionFactory(connectionFactory);
Method connectionFactorySetter = findConnectionFactorySetter();
if (connectionFactorySetter != null) {
ReflectionUtils.invokeMethod(connectionFactorySetter, pool,
connectionFactory);
}
else {
throw new IllegalStateException(
"No supported setConnectionFactory method was found");
}
return pool;
}
return connectionFactory;
}
private Method findConnectionFactorySetter() {
Method setter = findConnectionFactorySetter(ConnectionFactory.class);
if (setter == null) {
setter = findConnectionFactorySetter(Object.class);
}
return setter;
}
private Method findConnectionFactorySetter(Class<?> param) {
return ReflectionUtils.findMethod(PooledConnectionFactory.class,
"setConnectionFactory", param);
}
}

View File

@ -19,8 +19,10 @@ package org.springframework.boot.autoconfigure.jms.activemq;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.pool.PooledConnectionFactory;
import org.junit.Test;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -57,15 +59,25 @@ public class ActiveMQAutoConfigurationTests {
assertTrue(mockingDetails(this.context.getBean(ConnectionFactory.class)).isMock());
}
private void load(Class<?> config) {
this.context = doLoad(config);
@Test
public void pooledConnectionFactoryConfiguration() {
load(EmptyConfiguration.class, "spring.activemq.pooled:true");
ConnectionFactory connectionFactory = this.context
.getBean(ConnectionFactory.class);
assertThat(connectionFactory, instanceOf(PooledConnectionFactory.class));
}
private AnnotationConfigApplicationContext doLoad(Class<?> config) {
private void load(Class<?> config, String... environment) {
this.context = doLoad(config, environment);
}
private AnnotationConfigApplicationContext doLoad(Class<?> config,
String... environment) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(config);
applicationContext.register(ActiveMQAutoConfiguration.class,
JmsAutoConfiguration.class);
EnvironmentTestUtils.addEnvironment(applicationContext, environment);
applicationContext.refresh();
return applicationContext;
}