DATAREDIS-261 - Upgrade to commons-pool2.

'JRedisPool' and 'DefaultLettucePool' have been migrated to 'commons-pool2'.

'PoolConfig' has been deprecated, and will be removed in '1.4', as all required operations are available via 'GenericObjectPoolConfig'.

Along the way a minor bug within 'LettuceConnection' has been resolved, which prevented 'RedisAsyncConnections' from being properly closed/returned to pool.

Original Pull Request: #50
This commit is contained in:
Christoph Strobl
2014-03-19 15:01:51 +01:00
committed by Thomas Darimont
parent d116d3825a
commit 408b52a449
10 changed files with 166 additions and 180 deletions

View File

@@ -29,6 +29,12 @@ apply plugin: 'javadocHotfix'
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:-serial"]
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:-serial", "-Xlint:deprecation"]
configurations.all {
resolutionStrategy {
force 'org.apache.commons:commons-pool2:2.2'
}
}
// Common dependencies
dependencies {
// Logging
@@ -60,7 +66,7 @@ dependencies {
compile("com.fasterxml.jackson.core:jackson-databind:$fasterXmlJacksonDatabindVersion", optional)
// Pool
compile("commons-pool:commons-pool:1.5.6", optional)
compile("org.apache.commons:commons-pool2:2.2", optional)
// Testing
testCompile "junit:junit:$junitVersion"

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -15,64 +15,22 @@
*/
package org.springframework.data.redis.connection;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
/**
* Subclass of {@link Config} that includes setters for instantiation in Spring
* Subclass of {@link GenericObjectPoolConfig} that includes setters for instantiation in Spring
*
* @author Jennifer Hickey
* @author Christoph Strobl
* @deprecated use {@link GenericObjectPoolConfig} instead. Will be removed in {@literal 1.4}.
*/
public class PoolConfig extends Config {
public class PoolConfig extends GenericObjectPoolConfig {
public PoolConfig() {
super();
}
public void setMaxIdle(int maxIdle) {
this.maxIdle = maxIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public void setMaxWait(long maxWait) {
this.maxWait = maxWait;
}
public void setWhenExhaustedAction(byte whenExhaustedAction) {
this.whenExhaustedAction = whenExhaustedAction;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
this.numTestsPerEvictionRun = numTestsPerEvictionRun;
}
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) {
this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;
setMaxTotal(maxActive);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 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.
@@ -15,9 +15,11 @@
*/
package org.springframework.data.redis.connection.jredis;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.jredis.JRedis;
import org.jredis.connector.Connection;
import org.jredis.connector.Connection.Socket.Property;
@@ -32,10 +34,11 @@ import org.springframework.util.StringUtils;
* JRedis implementation of {@link Pool}
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class JredisPool implements Pool<JRedis> {
private final GenericObjectPool internalPool;
private final GenericObjectPool<JRedis> internalPool;
/**
* Uses the {@link Config} and {@link ConnectionSpec} defaults for configuring the connection pool
@@ -44,7 +47,7 @@ public class JredisPool implements Pool<JRedis> {
* @param port The Redis port
*/
public JredisPool(String hostName, int port) {
this(hostName, port, 0, null, 0, new Config());
this(hostName, port, 0, null, 0, new GenericObjectPoolConfig());
}
/**
@@ -54,7 +57,7 @@ public class JredisPool implements Pool<JRedis> {
* @param port The Redis port
* @param poolConfig The pool {@link Config}
*/
public JredisPool(String hostName, int port, Config poolConfig) {
public JredisPool(String hostName, int port, GenericObjectPoolConfig poolConfig) {
this(hostName, port, 0, null, 0, poolConfig);
}
@@ -64,15 +67,15 @@ public class JredisPool implements Pool<JRedis> {
* @param connectionSpec The {@link ConnectionSpec} for connecting to Redis
*/
public JredisPool(ConnectionSpec connectionSpec) {
this.internalPool = new GenericObjectPool(new JredisFactory(connectionSpec), new Config());
this.internalPool = new GenericObjectPool<JRedis>(new JredisFactory(connectionSpec), new GenericObjectPoolConfig());
}
/**
* @param connectionSpec The {@link ConnectionSpec} for connecting to Redis
* @param poolConfig The pool {@link Config}
*/
public JredisPool(ConnectionSpec connectionSpec, Config poolConfig) {
this.internalPool = new GenericObjectPool(new JredisFactory(connectionSpec), poolConfig);
public JredisPool(ConnectionSpec connectionSpec, GenericObjectPoolConfig poolConfig) {
this.internalPool = new GenericObjectPool<JRedis>(new JredisFactory(connectionSpec), poolConfig);
}
/**
@@ -87,7 +90,7 @@ public class JredisPool implements Pool<JRedis> {
* @param timeout The socket timeout or 0 to use the default socket timeout
*/
public JredisPool(String hostName, int port, int dbIndex, String password, int timeout) {
this(hostName, port, dbIndex, password, timeout, new Config());
this(hostName, port, dbIndex, password, timeout, new GenericObjectPoolConfig());
}
/**
@@ -98,7 +101,8 @@ public class JredisPool implements Pool<JRedis> {
* @param timeout The socket timeout or 0 to use the default socket timeout
* @param poolConfig The pool {@link Config}
*/
public JredisPool(String hostName, int port, int dbIndex, String password, int timeout, Config poolConfig) {
public JredisPool(String hostName, int port, int dbIndex, String password, int timeout,
GenericObjectPoolConfig poolConfig) {
ConnectionSpec connectionSpec = DefaultConnectionSpec.newSpec(hostName, port, dbIndex, null);
connectionSpec.setConnectionFlag(Connection.Flag.RELIABLE, false);
if (StringUtils.hasLength(password)) {
@@ -107,12 +111,12 @@ public class JredisPool implements Pool<JRedis> {
if (timeout > 0) {
connectionSpec.setSocketProperty(Property.SO_TIMEOUT, timeout);
}
this.internalPool = new GenericObjectPool(new JredisFactory(connectionSpec), poolConfig);
this.internalPool = new GenericObjectPool<JRedis>(new JredisFactory(connectionSpec), poolConfig);
}
public JRedis getResource() {
try {
return (JRedis) internalPool.borrowObject();
return internalPool.borrowObject();
} catch (Exception e) {
throw new PoolException("Could not get a resource from the pool", e);
}
@@ -142,7 +146,7 @@ public class JredisPool implements Pool<JRedis> {
}
}
private static class JredisFactory extends BasePoolableObjectFactory {
private static class JredisFactory extends BasePooledObjectFactory<JRedis> {
private final ConnectionSpec connectionSpec;
@@ -151,31 +155,33 @@ public class JredisPool implements Pool<JRedis> {
this.connectionSpec = connectionSpec;
}
public Object makeObject() throws Exception {
@Override
public void destroyObject(final PooledObject<JRedis> obj) throws Exception {
try {
obj.getObject().quit();
} catch (Exception e) {
// Errors may happen if returning a broken resource
}
}
@Override
public boolean validateObject(final PooledObject<JRedis> obj) {
try {
obj.getObject().ping();
return true;
} catch (Exception e) {
return false;
}
}
@Override
public JRedis create() throws Exception {
return new JRedisClient(connectionSpec);
}
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof JRedis) {
try {
((JRedis) obj).quit();
} catch (Exception e) {
// Errors may happen if returning a broken resource
}
}
}
public boolean validateObject(final Object obj) {
if (obj instanceof JRedis) {
try {
((JRedis) obj).ping();
return true;
} catch (Exception e) {
return false;
}
} else {
return false;
}
@Override
public PooledObject<JRedis> wrap(JRedis obj) {
return new DefaultPooledObject<JRedis>(obj);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -17,9 +17,11 @@ package org.springframework.data.redis.connection.lettuce;
import java.util.concurrent.TimeUnit;
import org.apache.commons.pool.BasePoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.util.Assert;
@@ -28,15 +30,18 @@ import com.lambdaworks.redis.RedisAsyncConnection;
import com.lambdaworks.redis.RedisClient;
/**
* Default implementation of {@link LettucePool}
* Default implementation of {@link LettucePool}.
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class DefaultLettucePool implements LettucePool, InitializingBean {
private GenericObjectPool internalPool;
@SuppressWarnings("rawtypes")//
private GenericObjectPool<RedisAsyncConnection> internalPool;
private RedisClient client;
private int dbIndex = 0;
private Config poolConfig = new Config();
private GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
private String hostName = "localhost";
private int port = 6379;
private String password;
@@ -63,25 +68,26 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
*
* @param hostName The Redis host
* @param port The Redis port
* @param poolConfig The pool {@link Config}
* @param poolConfig The pool {@link GenericObjectPoolConfig}
*/
public DefaultLettucePool(String hostName, int port, Config poolConfig) {
public DefaultLettucePool(String hostName, int port, GenericObjectPoolConfig poolConfig) {
this.hostName = hostName;
this.port = port;
this.poolConfig = poolConfig;
}
@SuppressWarnings({ "rawtypes" })
public void afterPropertiesSet() {
this.client = password != null ? new AuthenticatingRedisClient(hostName, port, password) : new RedisClient(
hostName, port);
client.setDefaultTimeout(timeout, TimeUnit.MILLISECONDS);
this.internalPool = new GenericObjectPool(new LettuceFactory(client, dbIndex), poolConfig);
this.internalPool = new GenericObjectPool<RedisAsyncConnection>(new LettuceFactory(client, dbIndex), poolConfig);
}
@SuppressWarnings("unchecked")
public RedisAsyncConnection<byte[], byte[]> getResource() {
try {
return (RedisAsyncConnection<byte[], byte[]>) internalPool.borrowObject();
return internalPool.borrowObject();
} catch (Exception e) {
throw new PoolException("Could not get a resource from the pool", e);
}
@@ -119,14 +125,14 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
/**
* @return The pool configuration
*/
public Config getPoolConfig() {
public GenericObjectPoolConfig getPoolConfig() {
return poolConfig;
}
/**
* @param poolConfig The pool configuration to use
*/
public void setPoolConfig(Config poolConfig) {
public void setPoolConfig(GenericObjectPoolConfig poolConfig) {
this.poolConfig = poolConfig;
}
@@ -221,7 +227,8 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
this.timeout = timeout;
}
private static class LettuceFactory extends BasePoolableObjectFactory {
@SuppressWarnings("rawtypes")
private static class LettuceFactory extends BasePooledObjectFactory<RedisAsyncConnection> {
private final RedisClient client;
@@ -233,41 +240,37 @@ public class DefaultLettucePool implements LettucePool, InitializingBean {
this.dbIndex = dbIndex;
}
public Object makeObject() throws Exception {
return client.connectAsync(LettuceConnection.CODEC);
}
@SuppressWarnings("rawtypes")
@Override
public void activateObject(Object obj) throws Exception {
if (obj instanceof RedisAsyncConnection) {
((RedisAsyncConnection) obj).select(dbIndex);
public void activateObject(PooledObject<RedisAsyncConnection> pooledObject) throws Exception {
pooledObject.getObject().select(dbIndex);
}
public void destroyObject(final PooledObject<RedisAsyncConnection> obj) throws Exception {
try {
obj.getObject().close();
} catch (Exception e) {
// Errors may happen if returning a broken resource
}
}
@SuppressWarnings("rawtypes")
public void destroyObject(final Object obj) throws Exception {
if (obj instanceof RedisAsyncConnection) {
try {
((RedisAsyncConnection) obj).close();
} catch (Exception e) {
// Errors may happen if returning a broken resource
}
}
}
@SuppressWarnings("rawtypes")
public boolean validateObject(final Object obj) {
if (obj instanceof RedisAsyncConnection) {
try {
((RedisAsyncConnection) obj).ping();
return true;
} catch (Exception e) {
return false;
}
} else {
public boolean validateObject(final PooledObject<RedisAsyncConnection> obj) {
try {
obj.getObject().ping();
return true;
} catch (Exception e) {
return false;
}
}
@Override
public RedisAsyncConnection create() throws Exception {
return client.connectAsync(LettuceConnection.CODEC);
}
@Override
public PooledObject<RedisAsyncConnection> wrap(RedisAsyncConnection obj) {
return new DefaultPooledObject<RedisAsyncConnection>(obj);
}
}
}

View File

@@ -314,23 +314,32 @@ public class LettuceConnection implements RedisConnection {
}
}
private void returnDedicatedAsyncConnection() {
if (pool != null) {
if (!broken) {
pool.returnResource(this.asyncDedicatedConn);
} else {
pool.returnBrokenResource(this.asyncDedicatedConn);
}
this.asyncDedicatedConn = null;
} else {
try {
asyncDedicatedConn.close();
} catch (RuntimeException ex) {
throw convertLettuceAccessException(ex);
}
}
}
public void close() throws DataAccessException {
isClosed = true;
if (asyncDedicatedConn != null) {
if (pool != null) {
if (!broken) {
pool.returnResource(asyncDedicatedConn);
} else {
pool.returnBrokenResource(asyncDedicatedConn);
}
} else {
try {
asyncDedicatedConn.close();
} catch (RuntimeException ex) {
throw convertLettuceAccessException(ex);
}
}
returnDedicatedAsyncConnection();
}
if (subscription != null) {

View File

@@ -23,7 +23,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.hamcrest.core.IsInstanceOf;
import org.jredis.JRedis;
import org.jredis.protocol.BulkResponse;
@@ -112,9 +112,9 @@ public class JRedisConnectionIntegrationTests extends AbstractConnectionIntegrat
@Test
public void testConnectionNotReturnedOnException() {
Config config = new Config();
config.maxActive = 1;
config.maxWait = 1;
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(1);
config.setMaxWaitMillis(1);
JredisConnectionFactory factory2 = new JredisConnectionFactory(new JredisPool(SettingsUtils.getHost(),
SettingsUtils.getPort(), config));
RedisConnection conn2 = factory2.getConnection();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -15,7 +15,9 @@
*/
package org.springframework.data.redis.connection.jredis;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import static org.junit.Assert.*;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.jredis.JRedis;
import org.jredis.RedisException;
import org.jredis.connector.ConnectionSpec;
@@ -27,13 +29,12 @@ import org.junit.Test;
import org.springframework.data.redis.SettingsUtils;
import org.springframework.data.redis.connection.PoolException;
import static org.junit.Assert.*;
/**
* Integration test of {@link JredisPool}
* Integration test of {@link JredisPool}.
*
* @author Jennifer Hickey
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class JredisPoolTests {
@@ -63,9 +64,9 @@ public class JredisPoolTests {
@Test
public void testGetResourcePoolExhausted() {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new JredisPool(connectionSpec, poolConfig);
JRedis client = pool.getResource();
assertNotNull(client);
@@ -79,8 +80,8 @@ public class JredisPoolTests {
@Test
public void testGetResourceValidate() {
Config poolConfig = new Config();
poolConfig.testOnBorrow = true;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setTestOnBorrow(true);
this.pool = new JredisPool(connectionSpec, poolConfig);
JRedis client = pool.getResource();
assertNotNull(client);
@@ -96,9 +97,10 @@ public class JredisPoolTests {
@Test
public void testReturnResource() throws RedisException {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new JredisPool(connectionSpec);
JRedis client = pool.getResource();
assertNotNull(client);
@@ -108,9 +110,10 @@ public class JredisPoolTests {
@Test
public void testReturnBrokenResource() throws RedisException {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new JredisPool(connectionSpec, poolConfig);
JRedis client = pool.getResource();
assertNotNull(client);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013 the original author or authors.
* Copyright 2013-2014 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.
@@ -15,9 +15,9 @@
*/
package org.springframework.data.redis.connection.lettuce;
import com.lambdaworks.redis.RedisAsyncConnection;
import com.lambdaworks.redis.RedisException;
import org.apache.commons.pool.impl.GenericObjectPool.Config;
import static org.junit.Assert.*;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Test;
@@ -25,13 +25,15 @@ import org.springframework.data.redis.SettingsUtils;
import org.springframework.data.redis.connection.PoolConfig;
import org.springframework.data.redis.connection.PoolException;
import static org.junit.Assert.*;
import com.lambdaworks.redis.RedisAsyncConnection;
import com.lambdaworks.redis.RedisException;
/**
* Unit test of {@link DefaultLettucePool}
*
* @author Jennifer Hickey
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class DefaultLettucePoolTests {
@@ -61,9 +63,9 @@ public class DefaultLettucePoolTests {
@Test
public void testGetResourcePoolExhausted() {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new DefaultLettucePool(SettingsUtils.getHost(), SettingsUtils.getPort(), poolConfig);
pool.afterPropertiesSet();
RedisAsyncConnection<byte[], byte[]> client = pool.getResource();
@@ -96,9 +98,9 @@ public class DefaultLettucePoolTests {
@Test
public void testReturnResource() {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new DefaultLettucePool(SettingsUtils.getHost(), SettingsUtils.getPort(), poolConfig);
pool.afterPropertiesSet();
RedisAsyncConnection<byte[], byte[]> client = pool.getResource();
@@ -110,9 +112,9 @@ public class DefaultLettucePoolTests {
@Test
public void testReturnBrokenResource() {
Config poolConfig = new Config();
poolConfig.maxActive = 1;
poolConfig.maxWait = 1;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(1);
poolConfig.setMaxWaitMillis(1);
this.pool = new DefaultLettucePool(SettingsUtils.getHost(), SettingsUtils.getPort(), poolConfig);
pool.afterPropertiesSet();
RedisAsyncConnection<byte[], byte[]> client = pool.getResource();

View File

@@ -95,7 +95,7 @@ public class RedisMapTests extends AbstractRedisMapTests<Object, Object> {
ObjectFactory<byte[]> rawFactory = new RawObjectFactory();
JedisConnectionFactory jedisConnFactory = new JedisConnectionFactory();
jedisConnFactory.getPoolConfig().setMaxTotal(defaultPoolConfig.maxActive);
jedisConnFactory.getPoolConfig().setMaxTotal(defaultPoolConfig.getMaxTotal());
jedisConnFactory.setUsePool(true);
jedisConnFactory.setPort(SettingsUtils.getPort());
jedisConnFactory.setHostName(SettingsUtils.getHost());

View File

@@ -21,8 +21,7 @@ Import-Template:
javax.xml.transform.*;resolution:="optional";version="0",
org.jredis.*;resolution:="optional";version="[1.0.0, 2.0.0)",
redis.clients.*;resolution:="optional";version="[2.1.0, 2.4.1)",
org.apache.commons.pool.*;resolution:="optional";version="[1.0.0, 3.0.0)",
org.apache.commons.pool2.*;resolution:="optional";version="[1.0, 2.0)",
org.apache.commons.pool2.*;resolution:="optional";version="[1.0, 2.2)",
org.codehaus.jackson.*;resolution:="optional";version="[1.6, 2.0.0)",
com.fasterxml.jackson.*;resolution:="optional";version="[2.0.0, 3.0.0)",
org.apache.commons.beanutils.*;resolution:="optional";version=1.8.5,