You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2015/07/31 17:10:48 UTC

tomee git commit: TOMEE-1617 no more default for db pooling

Repository: tomee
Updated Branches:
  refs/heads/master b3ac6942f -> 8d2d7183a


TOMEE-1617 no more default for db pooling


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/8d2d7183
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/8d2d7183
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/8d2d7183

Branch: refs/heads/master
Commit: 8d2d7183aed2c811fdbc39babf2900ce66070305
Parents: b3ac694
Author: Romain Manni-Bucau <rm...@starbucks.com>
Authored: Fri Jul 31 17:10:35 2015 +0200
Committer: Romain Manni-Bucau <rm...@starbucks.com>
Committed: Fri Jul 31 17:10:35 2015 +0200

----------------------------------------------------------------------
 .../openejb/assembler/classic/Assembler.java    | 184 ++++++----
 .../jdbc/pool/PoolDataSourceCreator.java        |   6 +-
 .../META-INF/org.apache.openejb/service-jar.xml | 348 +------------------
 .../jdbc/driver/AlternateDriverJarTest.java     |   4 +-
 .../openejb/bonecp/BoneCPDataSourceCreator.java | 113 ++----
 .../BoneCPPooledDataSourceFromPoolTest.java     |   4 +-
 .../bonecp/BoneCPPooledDataSourceTest.java      |  22 +-
 .../tomee/jdbc/TomEEDataSourceCreator.java      | 232 ++++---------
 .../jdbc/TomcatDataSourceFromPoolTest.java      |   4 +-
 .../jdbc/TomcatPoolCipherPasswordTest.java      |  10 +-
 .../org/apache/tomee/jdbc/TomcatPoolTest.java   |   8 +-
 .../tomee/jdbc/TomcatXADataSourceTest.java      |   3 +-
 12 files changed, 259 insertions(+), 679 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
index 278d7c5..6d736df 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
@@ -136,6 +136,7 @@ import org.apache.openejb.util.classloader.ClassLoaderAwareHandler;
 import org.apache.openejb.util.classloader.URLClassLoaderFirst;
 import org.apache.openejb.util.proxy.ProxyFactory;
 import org.apache.openejb.util.proxy.ProxyManager;
+import org.apache.openejb.util.reflection.Reflections;
 import org.apache.webbeans.component.ResourceBean;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.container.BeanManagerImpl;
@@ -161,6 +162,43 @@ import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Option;
 import org.apache.xbean.recipe.UnsetPropertiesRecipe;
 
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import javax.ejb.EJB;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.DefinitionException;
+import javax.enterprise.inject.spi.DeploymentException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.resource.cci.Connection;
+import javax.resource.cci.ConnectionFactory;
+import javax.resource.spi.BootstrapContext;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ManagedConnectionFactory;
+import javax.resource.spi.ResourceAdapter;
+import javax.resource.spi.ResourceAdapterInternalException;
+import javax.resource.spi.XATerminator;
+import javax.resource.spi.work.WorkManager;
+import javax.servlet.ServletContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
 import java.io.ByteArrayInputStream;
 import java.io.Externalizable;
 import java.io.File;
@@ -200,43 +238,6 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.ReentrantLock;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-import javax.annotation.Resource;
-import javax.ejb.EJB;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.DefinitionException;
-import javax.enterprise.inject.spi.DeploymentException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.naming.Binding;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NameAlreadyBoundException;
-import javax.naming.NamingEnumeration;
-import javax.naming.NamingException;
-import javax.resource.cci.Connection;
-import javax.resource.cci.ConnectionFactory;
-import javax.resource.spi.BootstrapContext;
-import javax.resource.spi.ConnectionManager;
-import javax.resource.spi.ManagedConnectionFactory;
-import javax.resource.spi.ResourceAdapter;
-import javax.resource.spi.ResourceAdapterInternalException;
-import javax.resource.spi.XATerminator;
-import javax.resource.spi.work.WorkManager;
-import javax.servlet.ServletContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-import javax.transaction.TransactionSynchronizationRegistry;
-import javax.validation.ValidationException;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
 
 import static org.apache.openejb.util.Classes.ancestors;
 
@@ -2697,50 +2698,79 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
         }
         serviceInfo.properties.remove("SkipImplicitAttributes");
 
+        // if custom instance allow to skip properties fallback to avoid to set unexpectedly it - connectionProps of DBs
+        final String skipPropertiesFallback = (String) serviceInfo.properties.remove("SkipPropertiesFallback");
         final AtomicReference<Properties> injectedProperties = new AtomicReference<>();
-        serviceRecipe.setProperty("properties", new UnsetPropertiesRecipe() {
-            @Override
-            protected Object internalCreate(final Type expectedType, final boolean lazyRefAllowed) throws ConstructionException {
-                final Map<String, Object> original = serviceRecipe.getUnsetProperties();
-                final Properties properties = new SuperProperties() {
-                    @Override
-                    public Object remove(final Object key) { // avoid to log them then
-                        original.remove(key);
-                        return super.remove(key);
+        if (!"true".equalsIgnoreCase(skipPropertiesFallback)) {
+            serviceRecipe.setProperty("properties", new UnsetPropertiesRecipe() {
+                @Override
+                protected Object internalCreate(final Type expectedType, final boolean lazyRefAllowed) throws ConstructionException {
+                    final Map<String, Object> original = serviceRecipe.getUnsetProperties();
+                    final Properties properties = new SuperProperties() {
+                        @Override
+                        public Object remove(final Object key) { // avoid to log them then
+                            original.remove(key);
+                            return super.remove(key);
+                        }
+                    }.caseInsensitive(true); // keep our nice case insensitive feature
+                    for (final Map.Entry<String, Object> entry : original.entrySet()) {
+                        properties.put(entry.getKey(), entry.getValue());
                     }
-                }.caseInsensitive(true); // keep our nice case insensitive feature
-                for (final Map.Entry<String, Object> entry : original.entrySet()) {
-                    properties.put(entry.getKey(), entry.getValue());
+                    injectedProperties.set(properties);
+                    return properties;
+                }
+            });
+        } else { // this is not the best fallback we have but since it is super limited it is acceptable
+            final Map<String, Object> unsetProperties = serviceRecipe.getUnsetProperties();
+            injectedProperties.set(new Properties() {
+                @Override
+                public String getProperty(final String key) {
+                    final Object obj = unsetProperties.get(key);
+                    return String.class.isInstance(obj) ? String.valueOf(obj) : null;
                 }
-                injectedProperties.set(properties);
-                return properties;
-            }
-        });
 
-        final Properties props = PropertyPlaceHolderHelper.simpleHolds(serviceInfo.properties);
-        if (serviceInfo.properties.containsKey("Definition")) {
-            final Object encoding = serviceInfo.properties.remove("DefitionEncoding");
-            try { // we catch classcast etc..., if it fails it is not important
-                final InputStream is = new ByteArrayInputStream(serviceInfo.properties.getProperty("Definition")
+                @Override
+                public Set<String> stringPropertyNames() {
+                    return unsetProperties.keySet();
+                }
+
+                @Override
+                public Set<Object> keySet() {
+                    return Set.class.cast(unsetProperties.keySet());
+                }
+
+                @Override
+                public synchronized boolean containsKey(final Object key) {
+                    return getProperty(String.valueOf(key)) != null;
+                }
+            });
+        }
+
+        if (serviceInfo.types.contains("DataSource") || serviceInfo.types.contains(DataSource.class.getName())) {
+            final Properties props = PropertyPlaceHolderHelper.simpleHolds(serviceInfo.properties);
+            if (serviceInfo.properties.containsKey("Definition")) {
+                final Object encoding = serviceInfo.properties.remove("DefitionEncoding");
+                try { // we catch classcast etc..., if it fails it is not important
+                    final InputStream is = new ByteArrayInputStream(serviceInfo.properties.getProperty("Definition")
                         .getBytes(encoding != null ? encoding.toString() : "ISO-8859-1"));
-                final Properties p = new SuperProperties();
-                IO.readProperties(is, p);
-                for (final Entry<Object, Object> entry : p.entrySet()) {
-                    final String key = entry.getKey().toString();
-                    if (!props.containsKey(key)
-                        // never override from Definition, just use it to complete the properties set
-                        &&
-                        !(key.equalsIgnoreCase("url") &&
-                            props.containsKey("JdbcUrl"))) { // with @DataSource we can get both, see org.apache.openejb.config.ConvertDataSourceDefinitions.rawDefinition()
-                        props.put(key, entry.getValue());
+                    final Properties p = new SuperProperties();
+                    IO.readProperties(is, p);
+                    for (final Entry<Object, Object> entry : p.entrySet()) {
+                        final String key = entry.getKey().toString();
+                        if (!props.containsKey(key)
+                            // never override from Definition, just use it to complete the properties set
+                            &&
+                            !(key.equalsIgnoreCase("url") &&
+                                props.containsKey("JdbcUrl"))) { // with @DataSource we can get both, see org.apache.openejb.config.ConvertDataSourceDefinitions.rawDefinition()
+                            props.put(key, entry.getValue());
+                        }
                     }
+                } catch (final Exception e) {
+                    // ignored
                 }
-            } catch (final Exception e) {
-                // ignored
             }
-        }
-
-        serviceRecipe.setProperty("Definition", PropertiesHelper.propertiesToString(props));
+            serviceRecipe.setProperty("Definition", PropertiesHelper.propertiesToString(props));
+        } // else: any other kind of resource relying on it? shouldnt be
 
         replaceResourceAdapterProperty(serviceRecipe);
 
@@ -3175,9 +3205,13 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
             return;
         }
 
+        final boolean ignoreJdbcDefault = "Annotation".equalsIgnoreCase(info.properties.getProperty("Origin"));
         Logger logger = null;
         for (final String property : unsetProperties.keySet()) {
             //TODO: DMB: Make more robust later
+            if (ignoreJdbcDefault && ("JdbcUrl".equals(property) || "UserName".equals(property) || "Password".equals(property) || "PasswordCipher".equals(property))) {
+                continue;
+            }
             if (property.equalsIgnoreCase("Definition")) {
                 continue;
             }
@@ -3271,7 +3305,9 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A
 
         final ObjectRecipe serviceRecipe = prepareRecipe(info);
         final Object value = info.properties.remove("SkipImplicitAttributes"); // we don't want this one to go in recipe
-        serviceRecipe.setAllProperties(PropertyPlaceHolderHelper.simpleHolds(info.properties));
+        final Properties allProperties = PropertyPlaceHolderHelper.simpleHolds(info.properties);
+        allProperties.remove("SkipPropertiesFallback");
+        serviceRecipe.setAllProperties(allProperties);
         if (value != null) {
             info.properties.put("SkipImplicitAttributes", value);
         }

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
index 1e1dba4..31360a7 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/jdbc/pool/PoolDataSourceCreator.java
@@ -96,12 +96,16 @@ public abstract class PoolDataSourceCreator implements DataSourceCreator {
         recipeOptions(serviceRecipe);
         serviceRecipe.setAllProperties(properties);
         final T value = (T) serviceRecipe.create();
-        if (value instanceof DataSource) { // avoid to keep config objects
+        if (trackRecipeFor(value)) { // avoid to keep config objects
             recipes.put(value, serviceRecipe);
         }
         return value;
     }
 
+    protected boolean trackRecipeFor(final Object value) {
+        return value instanceof DataSource;
+    }
+
     protected <T> T build(final Class<T> clazz, final Object instance, final Properties properties) {
         final ObjectRecipe recipe = PassthroughFactory.recipe(instance);
         recipeOptions(recipe);

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
index 8b324cd..c15684a 100644
--- a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
+++ b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
@@ -591,10 +591,6 @@
           factory-name="create"
           constructor="ServiceId, JtaManaged, JdbcDriver, Definition, MaxWaitTime, TimeBetweenEvictionRuns, MinEvictableIdleTime"
           class-name="org.apache.openejb.resource.jdbc.DataSourceFactory">
-    ServiceId
-
-    Definition
-
     # Determines wether or not this data source should be JTA managed
     # or user managed.  If set to 'true' it will automatically be enrolled
     # in any ongoing transactions.  Calling begin/commit/rollback or setAutoCommit
@@ -610,184 +606,21 @@
 
     # Driver class name
 
-    JdbcDriver org.hsqldb.jdbcDriver
+    JdbcDriver = org.hsqldb.jdbcDriver
 
     # Url for creating connections
 
-    JdbcUrl jdbc:hsqldb:mem:hsqldb
+    JdbcUrl = jdbc:hsqldb:mem:hsqldb
 
     # Default user name
 
-    UserName sa
+    UserName = sa
 
     # Default password
 
-    Password
-
-    PasswordCipher  PlainText
-
-
-    # The connection properties that will be sent to the JDBC
-    # driver when establishing new connections
-    #
-    # Format of the string must be [propertyName=property;]*
-    #
-    # NOTE - The "user" and "password" properties will be passed
-    # explicitly, so they do not need to be included here.
-
-    ConnectionProperties
-
-    # The default auto-commit state of new connections
-
-    DefaultAutoCommit true
-
-    # The default read-only state of new connections
-    # If not set then the setReadOnly method will not be called.
-    # (Some drivers don't support read only mode, ex: Informix)
-
-    DefaultReadOnly
-
-
-    # The default TransactionIsolation state of new connections
-    # If not set then the `setTransactionIsolation` method will not
-    # be called. The allowed values for this property are:
-    #
-    # - `NONE`
-    # - `READ_COMMITTED`
-    # - `READ_UNCOMMITTED`
-    # - `REPEATABLE_READ`
-    # - `SERIALIZABLE`
-    #
-    # Note: Most JDBC drivers do not support all isolation levels
-
-    # DefaultTransactionIsolation
-
-
-    # The initial number of connections that are created when the
-    # pool is started
-
-    InitialSize	0
-
-    # The maximum number of active connections that can be
-    # allocated from this pool at the same time, or a negative
-    # number for no limit.
-
-    MaxActive	20
-
-    # The maximum number of connections that can remain idle in
-    # the pool, without extra ones being released, or a negative
-    # number for no limit.
-
-    MaxIdle	20
-
-    # The minimum number of connections that can remain idle in
-    # the pool, without extra ones being created, or zero to
-    # create none.
-
-    MinIdle	0
-
-    # The maximum number of milliseconds that the pool will wait
-    # (when there are no available connections) for a connection
-    # to be returned before throwing an exception, or -1 to wait
-    # indefinitely.
+    Password =
 
-    MaxWaitTime	-1 millisecond
-
-    # The SQL query that will be used to validate connections from
-    # this pool before returning them to the caller. If specified,
-    # this query MUST be an SQL SELECT statement that returns at
-    # least one row.
-
-    ValidationQuery
-
-    # If true connections will be validated before being returned
-    # from the pool. If the validation fails, the connection is
-    # destroyed, and a new conection will be retrieved from the
-    # pool (and validated).
-    #
-    # NOTE - for a true value to have any effect, the
-    # ValidationQuery parameter must be set.
-
-    TestOnBorrow	true
-
-    # If true connections will be validated before being returned
-    # to the pool.  If the validation fails, the connection is
-    # destroyed instead of being returned to the pool.
-    #
-    # NOTE - for a true value to have any effect, the
-    # ValidationQuery parameter must be set.
-
-    TestOnReturn	false
-
-    # If true connections will be validated by the idle connection
-    # evictor (if any). If the validation fails, the connection is
-    # destroyed and removed from the pool
-    #
-    # NOTE - for a true value to have any effect, the
-    # timeBetweenEvictionRunsMillis property must be a positive
-    # number and the ValidationQuery parameter must be set.
-
-    TestWhileIdle	false
-
-    # The number of milliseconds to sleep between runs of the idle
-    # connection evictor thread. When set to a negative number, no
-    # idle connection evictor thread will be run.
-
-    TimeBetweenEvictionRuns	-1 millisecond
-
-    # The number of connectionss to examine during each run of the
-    # idle connection evictor thread (if any).
-
-    NumTestsPerEvictionRun	3
-
-    # The minimum amount of time a connection may sit idle in the
-    # pool before it is eligable for eviction by the idle
-    # connection evictor (if any).
-
-    MinEvictableIdleTime	30 minutes
-
-    # If true, a statement pool is created for each Connection and
-    # PreparedStatements created by one of the following methods are
-    # pooled:
-    #
-    #     public PreparedStatement prepareStatement(String sql);
-    #     public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)
-
-    PoolPreparedStatements false
-
-    # The maximum number of open statements that can be allocated
-    # from the statement pool at the same time, or zero for no
-    # limit.
-    #
-    # NOTE - Some drivers have limits on the number of open
-    # statements, so make sure there are some resources left
-    # for the other (non-prepared) statements.
-
-    MaxOpenPreparedStatements 0
-
-    # If true the raw physical connection to the database can be
-    # accessed using the following construct:
-    #
-    #     Connection conn = ds.getConnection();
-    #     Connection rawConn = ((DelegatingConnection) conn).getInnermostDelegate();
-    #     ...
-    #     conn.close()
-    #
-    # Default is false, because misbehaving programs can do harmfull
-    # things to the raw connection shuch as closing the raw
-    # connection or continuing to use the raw connection after it
-    # has been assigned to another logical connection.  Be careful
-    # and only use when you need direct access to driver specific
-    # extensions.
-    #
-    # NOTE: Do NOT close the underlying connection, only the
-    # original logical connection wrapper.
-
-    AccessToUnderlyingConnectionAllowed	false
-
-    # use only all set values in this config
-    # will need a lot of properties but allow to not set some values
-    IgnoreDefaultValues = false
+    PasswordCipher = PlainText
   </ServiceProvider>
 
   <ServiceProvider
@@ -797,186 +630,25 @@
           factory-name="create"
           constructor="ServiceId, JtaManaged, JdbcDriver, Definition, MaxWaitTime, TimeBetweenEvictionRuns, MinEvictableIdleTime"
           class-name="org.apache.openejb.resource.jdbc.DataSourceFactory">
-    ServiceId
-
-    Definition
-
     JtaManaged = false
 
     # Driver class name
 
-    JdbcDriver org.hsqldb.jdbcDriver
+    JdbcDriver = org.hsqldb.jdbcDriver
 
     # Url for creating connections
 
-    JdbcUrl jdbc:hsqldb:mem:hsqldb
+    JdbcUrl = jdbc:hsqldb:mem:hsqldb
 
     # Default user name
 
-    UserName sa
+    UserName = sa
 
     # Default password
 
-    Password
-
-    PasswordCipher  PlainText
-
-    # The connection properties that will be sent to the JDBC
-    # driver when establishing new connections
-    #
-    # Format of the string must be [propertyName=property;]*
-    #
-    # NOTE - The "user" and "password" properties will be passed
-    # explicitly, so they do not need to be included here.
-
-    ConnectionProperties
-
-    # The default auto-commit state of new connections
-
-    DefaultAutoCommit true
-
-    # The default read-only state of new connections
-    # If not set then the setReadOnly method will not be called.
-    # (Some drivers don't support read only mode, ex: Informix)
-
-    DefaultReadOnly
-
-
-    # The default TransactionIsolation state of new connections
-    # If not set then the setTransactionIsolation method will not
-    # be called. The allowed values for this property are:
-    #     NONE
-    #     READ_COMMITTED
-    #     READ_UNCOMMITTED
-    #     REPEATABLE_READ
-    #     SERIALIZABLE
-    #
-    # Note: Most JDBC drivers do not support all isolation levels
-
-    # DefaultTransactionIsolation
-
-
-    # The initial number of connections that are created when the
-    # pool is started
-
-    InitialSize	0
-
-    # The maximum number of active connections that can be
-    # allocated from this pool at the same time, or a negative
-    # number for no limit.
-
-    MaxActive	10
-
-    # The maximum number of connections that can remain idle in
-    # the pool, without extra ones being released, or a negative
-    # number for no limit.
-
-    MaxIdle	10
-
-    # The minimum number of connections that can remain idle in
-    # the pool, without extra ones being created, or zero to
-    # create none.
-
-    MinIdle	0
-
-    # The maximum number of milliseconds that the pool will wait
-    # (when there are no available connections) for a connection
-    # to be returned before throwing an exception, or -1 to wait
-    # indefinitely.
-
-    MaxWaitTime	-1 millisecond
-
-    # The SQL query that will be used to validate connections from
-    # this pool before returning them to the caller. If specified,
-    # this query MUST be an SQL SELECT statement that returns at
-    # least one row.
-
-    ValidationQuery
-
-    # If true connections will be validated before being returned
-    # from the pool. If the validation fails, the connection is
-    # destroyed, and a new conection will be retrieved from the
-    # pool (and validated).
-    #
-    # NOTE - for a true value to have any effect, the
-    # ValidationQuery parameter must be set.
-
-    TestOnBorrow	true
-
-    # If true connections will be validated before being returned
-    # to the pool.  If the validation fails, the connection is
-    # destroyed instead of being returned to the pool.
-    #
-    # NOTE - for a true value to have any effect, the
-    # ValidationQuery parameter must be set.
-
-    TestOnReturn	false
-
-    # If true connections will be validated by the idle connection
-    # evictor (if any). If the validation fails, the connection is
-    # destroyed and removed from the pool
-    #
-    # NOTE - for a true value to have any effect, the
-    # timeBetweenEvictionRunsMillis property must be a positive
-    # number and the ValidationQuery parameter must be set.
-
-    TestWhileIdle	false
-
-    # The number of milliseconds to sleep between runs of the idle
-    # connection evictor thread. When set to a negative number, no
-    # idle connection evictor thread will be run.
-
-    TimeBetweenEvictionRuns	-1 millisecond
-
-    # The number of connectionss to examine during each run of the
-    # idle connection evictor thread (if any).
-
-    NumTestsPerEvictionRun	3
-
-    # The minimum amount of time a connection may sit idle in the
-    # pool before it is eligable for eviction by the idle
-    # connection evictor (if any).
-
-    MinEvictableIdleTime	30 minutes
-
-    # If true, a statement pool is created for each Connection and
-    # PreparedStatements created by one of the following methods are
-    # pooled:
-    #    public PreparedStatement prepareStatement(String sql);
-    #    public PreparedStatement prepareStatement(String sql,
-    #            int resultSetType,
-    #            int resultSetConcurrency)
-
-    PoolPreparedStatements false
-
-    # The maximum number of open statements that can be allocated
-    # from the statement pool at the same time, or zero for no
-    # limit.
-    #
-    # NOTE - Some drivers have limits on the number of open
-    # statements, so make sure there are some resources left
-    # for the other (non-prepared) statements.
-
-    MaxOpenPreparedStatements 0
-
-    # If true the raw physical connection to the database can be
-    # accessed using the following construct:
-    #     Connection conn = ds.getConnection();
-    #     Connection rawConn = ((DelegatingConnection) conn).getInnermostDelegate();
-    #     ...
-    #     conn.close()
-    #
-    # Default is false, because misbehaving programs can do harmfull
-    # things to the raw connection shuch as closing the raw
-    # connection or continuing to use the raw connection after it
-    # has been assigned to another logical connection.  Be carefull
-    # and only use when you need direct access to driver specific
-    # extentions.
-    #
-    # NOTE: Do NOT close the underlying connection, only the
-    # original logical connection wrapper.
+    Password =
 
-    AccessToUnderlyingConnectionAllowed	false
+    PasswordCipher = PlainText
   </ServiceProvider>
 
   <!--

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/driver/AlternateDriverJarTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/driver/AlternateDriverJarTest.java b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/driver/AlternateDriverJarTest.java
index 0b99d99..ae7015e 100644
--- a/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/driver/AlternateDriverJarTest.java
+++ b/container/openejb-core/src/test/java/org/apache/openejb/resource/jdbc/driver/AlternateDriverJarTest.java
@@ -35,6 +35,8 @@ import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.util.Properties;
 
+import static org.apache.openejb.loader.JarLocation.jarLocation;
+
 @RunWith(ApplicationComposer.class)
 public class AlternateDriverJarTest {
 
@@ -44,7 +46,7 @@ public class AlternateDriverJarTest {
     @Configuration
     public Properties config() {
 
-        final File drivers = new File(".", "drivers").getAbsoluteFile();
+        final File drivers = new File(jarLocation(AlternateDriverJarTest.class).getParentFile(), "drivers").getAbsoluteFile();
 
         final Properties p = new Properties();
         p.put("openejb.jdbc.datasource-creator", "dbcp-alternative");

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java b/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
index 748d619..2deed33 100644
--- a/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
+++ b/server/openejb-bonecp/src/main/java/org/apache/openejb/bonecp/BoneCPDataSourceCreator.java
@@ -16,31 +16,25 @@
  */
 package org.apache.openejb.bonecp;
 
-import com.jolbox.bonecp.BoneCP;
 import com.jolbox.bonecp.BoneCPConfig;
 import com.jolbox.bonecp.BoneCPDataSource;
 import org.apache.openejb.OpenEJB;
-import org.apache.openejb.OpenEJBRuntimeException;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.resource.jdbc.BasicDataSourceUtil;
 import org.apache.openejb.resource.jdbc.managed.xa.ManagedXADataSource;
 import org.apache.openejb.resource.jdbc.plugin.DataSourcePlugin;
 import org.apache.openejb.resource.jdbc.pool.PoolDataSourceCreator;
 import org.apache.openejb.resource.jdbc.pool.XADataSourceResource;
-import org.apache.openejb.util.Duration;
 import org.apache.openejb.util.Strings;
+import org.apache.xbean.recipe.ObjectRecipe;
 
 import javax.sql.CommonDataSource;
 import javax.sql.DataSource;
 import javax.sql.XADataSource;
 import javax.transaction.TransactionSynchronizationRegistry;
-import java.lang.reflect.Field;
 import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
 import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
 
 public class BoneCPDataSourceCreator extends PoolDataSourceCreator {
     @Override
@@ -50,20 +44,46 @@ public class BoneCPDataSourceCreator extends PoolDataSourceCreator {
 
     @Override
     public DataSource pool(final String name, final DataSource ds, final Properties properties) {
+        final BoneCPDataSource dataSourceProvidedPool = createPool(properties);
+        dataSourceProvidedPool.setDatasourceBean(ds);
+        if (dataSourceProvidedPool.getPoolName() == null) {
+            dataSourceProvidedPool.setPoolName(name);
+        }
+        return dataSourceProvidedPool;
+    }
+
+    @Override
+    public CommonDataSource pool(final String name, final String driver, final Properties properties) {
+        final BoneCPDataSource pool = createPool(properties);
+        if (pool.getDriverClass() == null) {
+            pool.setDriverClass(driver);
+        }
+        if (pool.getPoolName() == null) {
+            pool.setPoolName(name);
+        }
+        final String xa = String.class.cast(properties.remove("XaDataSource"));
+        if (xa != null) {
+            final XADataSource xaDs = XADataSourceResource.proxy(Thread.currentThread().getContextClassLoader(), xa);
+            pool.setDatasourceBean(new ManagedXADataSource(xaDs, OpenEJB.getTransactionManager(), SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class)));
+        }
+        return pool;
+    }
+
+    private BoneCPDataSource createPool(final Properties properties) {
         final BoneCPConfig config;
-        final BoneCP pool;
         try {
             config = new BoneCPConfig(prefixedProps(properties));
-            pool = new BoneCP(config);
         } catch (Exception e) {
             throw new IllegalArgumentException(e);
         }
-        return build(BoneCPDataSourceProvidedPool.class, new BoneCPDataSourceProvidedPool(pool), new Properties());
+        final BoneCPDataSource dataSourceProvidedPool = new BoneCPDataSource(config);
+        recipes.put(dataSourceProvidedPool, new ObjectRecipe(BoneCPDataSource.class.getName())); // no error
+        return dataSourceProvidedPool;
     }
 
     private Properties prefixedProps(final Properties properties) {
         if (properties.containsKey("url")) {
-            properties.setProperty("", properties.getProperty("url"));
+            properties.setProperty("url", properties.getProperty("url"));
         }
 
         // updating relative url if mandatory (hsqldb for instance)
@@ -82,83 +102,22 @@ public class BoneCPDataSourceCreator extends PoolDataSourceCreator {
             }
         }
 
-        // TODO: convert some more properties:
-        // InitialSize, TestOnReturn, ConnectionProperties, MaxOpenPreparedStatements
-        // AccessToUnderlyingConnectionAllowed, PoolPreparedStatements, MinIdle, TestWhileIdle
-        // NumTestsPerEvictionRun, MaxIdle, MaxWait, MinEvictableIdleTimeMillis, TestOnBorrow, ValidationQuery
-
         final String cipher = properties.getProperty("PasswordCipher");
         if (cipher == null || "PlainText".equals(cipher)) { // no need to warn
             properties.remove("PasswordCipher");
         }
-        if (properties.containsKey("TimeBetweenEvictionRuns")) {
-            properties.setProperty("idleConnectionTestPeriodInSeconds", Long.toString(new Duration((String) properties.remove("TimeBetweenEvictionRuns")).getTime(TimeUnit.SECONDS)));
-        }
-        if (properties.containsKey("UserName")) {
-            properties.put("username", properties.remove("UserName"));
-        }
-        if (properties.containsKey("MaxActive")) {
-            properties.put("maxConnectionsPerPartition", properties.remove("MaxActive"));
-        }
 
         // bonecp expects bonecp prefix in properties
         final Properties prefixedProps = new Properties();
         for (Map.Entry<Object, Object> entry : properties.entrySet()) {
             final String suffix = Strings.lcfirst((String) entry.getKey());
-            prefixedProps.put("bonecp." + suffix, entry.getValue());
-        }
-
-        return prefixedProps;
-    }
-
-    @Override
-    public CommonDataSource pool(final String name, final String driver, final Properties properties) {
-        // bonecp already have a kind of ObjectRecipe so simply giving it the values
-        final Properties props = new Properties();
-        props.put("properties", prefixedProps(properties));
-
-        final BoneCPDataSource ds = build(BoneCPDataSource.class, props);
-        if (ds.getDriverClass() == null || ds.getDriverClass().isEmpty()) {
-            ds.setDriverClass(driver);
-        }
-        if (ds.getPoolName() == null || ds.getPoolName().isEmpty()) {
-            ds.setPoolName(name);
-        }
-
-        final String xa = String.class.cast(properties.remove("XaDataSource"));
-        if (xa != null) {
-            cleanProperty(ds, "xadatasource");
-
-            final XADataSource xaDs = XADataSourceResource.proxy(Thread.currentThread().getContextClassLoader(), xa);
-            ds.setDatasourceBean(new ManagedXADataSource(xaDs, OpenEJB.getTransactionManager(), SystemInstance.get().getComponent(TransactionSynchronizationRegistry.class)));
-        }
-
-        return ds;
-    }
-
-    private static final class BoneCPDataSourceProvidedPool extends BoneCPDataSource {
-        private static final Field POOL_FIELD;
-
-        static {
-            try {
-                POOL_FIELD = BoneCPDataSource.class.getDeclaredField("pool");
-                POOL_FIELD.setAccessible(true);
-            } catch (NoSuchFieldException e) {
-                throw new OpenEJBRuntimeException(e);
+            if (!suffix.startsWith("bonecp.")) {
+                prefixedProps.put("bonecp." + suffix, entry.getValue());
+            } else {
+                prefixedProps.put(suffix, entry.getValue());
             }
         }
 
-        public BoneCPDataSourceProvidedPool(final BoneCP pool) {
-            try {
-                POOL_FIELD.set(this, pool);
-            } catch (IllegalAccessException e) {
-                throw new OpenEJBRuntimeException(e);
-            }
-        }
-
-        // @Override // java 7
-        public Logger getParentLogger() throws SQLFeatureNotSupportedException {
-            throw new SQLFeatureNotSupportedException();
-        }
+        return prefixedProps;
     }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
index 8ae4dc6..7e83491 100644
--- a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
+++ b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceFromPoolTest.java
@@ -19,8 +19,8 @@ package org.apache.openejb.bonecp;
 import org.apache.openejb.jee.EjbJar;
 import org.apache.openejb.jee.SingletonBean;
 import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.junit.Configuration;
-import org.apache.openejb.junit.Module;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
----------------------------------------------------------------------
diff --git a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
index 5e275db..1ea22d2 100644
--- a/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
+++ b/server/openejb-bonecp/src/test/java/org/apache/openejb/bonecp/BoneCPPooledDataSourceTest.java
@@ -19,22 +19,12 @@ package org.apache.openejb.bonecp;
 import org.apache.openejb.jee.EjbJar;
 import org.apache.openejb.jee.SingletonBean;
 import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.junit.Configuration;
-import org.apache.openejb.junit.Module;
-import org.apache.openejb.resource.jdbc.managed.local.ManagedConnection;
-import org.junit.After;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.lang.reflect.Field;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Map;
-import java.util.Properties;
 import javax.annotation.Resource;
 import javax.ejb.EJB;
 import javax.ejb.EJBContext;
@@ -43,9 +33,13 @@ import javax.ejb.Singleton;
 import javax.ejb.TransactionAttribute;
 import javax.ejb.TransactionAttributeType;
 import javax.sql.DataSource;
-import javax.transaction.Transaction;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java b/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
index 6c6c363..cb813ee 100644
--- a/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
+++ b/tomee/tomee-jdbc/src/main/java/org/apache/tomee/jdbc/TomEEDataSourceCreator.java
@@ -18,19 +18,14 @@ package org.apache.tomee.jdbc;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
-import org.apache.openejb.cipher.PasswordCipher;
 import org.apache.openejb.cipher.PasswordCipherFactory;
+import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.monitoring.LocalMBeanServer;
 import org.apache.openejb.monitoring.ObjectNameBuilder;
-import org.apache.openejb.resource.jdbc.BasicDataSourceUtil;
 import org.apache.openejb.resource.jdbc.dbcp.DataSourceSerialization;
-import org.apache.openejb.resource.jdbc.plugin.DataSourcePlugin;
 import org.apache.openejb.resource.jdbc.pool.PoolDataSourceCreator;
-import org.apache.openejb.resource.jdbc.pool.XADataSourceResource;
+import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.util.Duration;
-import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.Strings;
 import org.apache.openejb.util.SuperProperties;
 import org.apache.openejb.util.reflection.Reflections;
 import org.apache.tomcat.jdbc.pool.ConnectionPool;
@@ -38,31 +33,22 @@ import org.apache.tomcat.jdbc.pool.PoolConfiguration;
 import org.apache.tomcat.jdbc.pool.PoolProperties;
 import org.apache.tomcat.jdbc.pool.PooledConnection;
 
+import javax.management.ObjectName;
+import javax.naming.NamingException;
+import javax.sql.CommonDataSource;
+import javax.sql.DataSource;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.sql.SQLException;
-import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.TimeUnit;
-import javax.management.ObjectName;
-import javax.sql.CommonDataSource;
-import javax.sql.DataSource;
-import javax.sql.XADataSource;
 
 public class TomEEDataSourceCreator extends PoolDataSourceCreator {
-    private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, TomEEDataSourceCreator.class);
-
     @Override
     public DataSource pool(final String name, final DataSource ds, final Properties properties) {
-        final Properties converted = new Properties();
-        final SuperProperties prop = new SuperProperties().caseInsensitive(true);
-        prop.putAll(properties);
-        updateProperties(prop, converted, null);
-
-        final PoolConfiguration config = build(PoolProperties.class, converted);
+        final PoolConfiguration config = build(TomEEPoolProperties.class, createProperties(name, properties));
         config.setDataSource(ds);
         final ConnectionPool pool;
         try {
@@ -70,139 +56,59 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
         } catch (final SQLException e) {
             throw new IllegalStateException(e);
         }
-        return build(TomEEDataSource.class, new TomEEDataSource(config, pool, name), converted);
+
+        final TomEEDataSource dataSource = new TomEEDataSource(config, pool, name);
+        recipes.put(dataSource, recipes.remove(config)); // transfer unset props for correct logging
+        return dataSource;
     }
 
     @Override
     public CommonDataSource pool(final String name, final String driver, final Properties properties) {
-        final Properties converted = new Properties();
-        converted.setProperty("name", name);
-
-        final SuperProperties prop = new SuperProperties().caseInsensitive(true);
-        prop.putAll(properties);
-
-        updateProperties(prop, converted, driver);
-        final PoolConfiguration config = build(PoolProperties.class, converted);
-        final TomEEDataSource ds = build(TomEEDataSource.class, new TomEEDataSource(config, name), converted);
-
-        final String xa = String.class.cast(properties.remove("XaDataSource"));
-        if (xa != null) {
-            cleanProperty(ds, "xadatasource");
-
-            final XADataSource xaDs = XADataSourceResource.proxy(Thread.currentThread().getContextClassLoader(), xa);
-            ds.setDataSource(xaDs);
-        }
-
+        final PoolConfiguration config = build(TomEEPoolProperties.class, createProperties(name, properties));
+        final TomEEDataSource ds = new TomEEDataSource(config, name);
+        recipes.put(ds, recipes.remove(config));
         return ds;
     }
 
-    private void updateProperties(final SuperProperties properties, final Properties converted, final String driver) {
-        // some compatibility with old dbcp style
-        if (driver != null && !properties.containsKey("driverClassName")) {
-            converted.setProperty("driverClassName", driver);
-        }
-        final String jdbcDriver = (String) properties.remove("JdbcDriver");
-        if (jdbcDriver != null && !properties.containsKey("driverClassName")) {
-            converted.setProperty("driverClassName", jdbcDriver);
-        }
-        final String url = (String) properties.remove("JdbcUrl");
-        if (url != null && !properties.containsKey("url")) {
-            converted.setProperty("url", url);
-        }
-        final String user = (String) properties.remove("user");
-        if (user != null && !properties.containsKey("username")) {
-            converted.setProperty("username", user);
-        }
-        final String maxWait = toMillis((String) properties.remove("maxWaitTime"));
-        if (maxWait != null && !properties.containsKey("maxWait")) {
-            converted.setProperty("maxWait", maxWait);
-        }
-        final String tb = toMillis((String) properties.remove("timeBetweenEvictionRuns"));
-        if (tb != null && !properties.containsKey("timeBetweenEvictionRunsMillis")) {
-            converted.setProperty("timeBetweenEvictionRunsMillis", tb);
-        }
-        final String minEvict = toMillis((String) properties.remove("minEvictableIdleTime"));
-        if (minEvict != null && !properties.containsKey("minEvictableIdleTimeMillis")) {
-            converted.setProperty("minEvictableIdleTimeMillis", minEvict);
-        }
-
-        final String passwordCipher = properties.getProperty("PasswordCipher");
-        if (passwordCipher != null && "PlainText".equals(passwordCipher)) { // no need to warn about it
-            properties.remove("PasswordCipher");
-        } else {
-            final String password = properties.getProperty("Password");
-            if (passwordCipher != null) {
-                final PasswordCipher cipher = PasswordCipherFactory.getPasswordCipher(passwordCipher);
-                final String plainPwd = cipher.decrypt(password.toCharArray());
-                converted.setProperty("password", plainPwd);
-
-                // all went fine so remove it to avoid errors later
-                properties.remove("PasswordCipher");
-                properties.remove("Password");
-            }
+    @Override
+    protected void doDestroy(final CommonDataSource dataSource) throws Throwable {
+        final org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
+        if (ds instanceof TomEEDataSource) {
+            ((TomEEDataSource) ds).internalJMXUnregister();
         }
+        ds.close(true);
+    }
 
-        for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
-            final String key = entry.getKey().toString();
-            final String value = entry.getValue().toString().trim();
-            if (!converted.containsKey(key)) {
-                if (!value.isEmpty()) {
-                    if ("MaxOpenPreparedStatements".equalsIgnoreCase(key) || "PoolPreparedStatements".equalsIgnoreCase(key)) {
-                        if ("0".equalsIgnoreCase(properties.getProperty("MaxOpenPreparedStatements", "0"))
-                                || "false".equalsIgnoreCase(properties.getProperty("PoolPreparedStatements", "false"))) {
-                            continue;
-                        }
-
-                        final String interceptors = properties.getProperty("jdbcInterceptors");
-                        if (interceptors == null) {
-                            converted.setProperty("jdbcInterceptors",
-                                    "StatementCache(max=" + properties.getProperty("MaxOpenPreparedStatements", "128") + ")");
-                            LOGGER.debug("Tomcat-jdbc StatementCache added to handle prepared statement cache/pool");
-                        } else if (!interceptors.contains("StatementCache")) {
-                            converted.setProperty("jdbcInterceptors", interceptors
-                                    + ";StatementCache(max=" + properties.getProperty("MaxOpenPreparedStatements", "128") + ")");
-                            LOGGER.debug("Tomcat-jdbc StatementCache added to handle prepared statement cache/pool");
-                        }
-                        continue;
-                    }
-
-                    converted.put(Strings.lcfirst(key), value);
-                } else if (key.toLowerCase().equals("username") || key.toLowerCase().equals("password")) { // avoid NPE
-                    converted.put(Strings.lcfirst(key), "");
-                }
-            }
-        }
+    @Override
+    protected boolean trackRecipeFor(final Object value) {
+        return super.trackRecipeFor(value) || TomEEPoolProperties.class.isInstance(value);
+    }
 
-        final String currentUrl = converted.getProperty("url");
-        if (currentUrl != null) {
-            try {
-                final DataSourcePlugin helper = BasicDataSourceUtil.getDataSourcePlugin(currentUrl);
-                if (helper != null) {
-                    final String newUrl = helper.updatedUrl(currentUrl);
-                    if (!currentUrl.equals(newUrl)) {
-                        properties.setProperty("url", newUrl);
-                    }
+    private SuperProperties createProperties(final String name, final Properties properties) {
+        final SuperProperties converted = new SuperProperties() {
+            @Override
+            public Object setProperty(final String name, final String value) {
+                if (value == null) {
+                    return super.getProperty(name);
                 }
-            } catch (final SQLException ignored) {
-                // no-op
+                return super.setProperty(name, value);
             }
-        }
-    }
+        }.caseInsensitive(true);
 
-    private String toMillis(final String d) {
-        if (d == null) {
-            return null;
+        converted.setProperty("name", name);
+        // very few properties have default = connection ones, so ensure to translate them with priority to specific ones
+        converted.setProperty("url", properties.getProperty("url", (String) properties.remove("JdbcUrl")));
+        converted.setProperty("driverClassName", properties.getProperty("driverClassName", (String) properties.remove("JdbcDriver")));
+        converted.setProperty("username", (String) properties.remove("username"));
+        converted.setProperty("password", (String) properties.remove("password"));
+        converted.putAll(properties);
+
+        final String passwordCipher = (String) converted.remove("PasswordCipher");
+        if (passwordCipher != null && !"PlainText".equals(passwordCipher)) {
+            converted.setProperty("password", PasswordCipherFactory.getPasswordCipher(passwordCipher).decrypt(converted.getProperty("Password").toCharArray()));
         }
-        return Long.toString(new Duration(d).getTime(TimeUnit.MILLISECONDS));
-    }
 
-    @Override
-    protected void doDestroy(final CommonDataSource dataSource) throws Throwable {
-        final org.apache.tomcat.jdbc.pool.DataSource ds = (org.apache.tomcat.jdbc.pool.DataSource) dataSource;
-        if (ds instanceof TomEEDataSource) {
-            ((TomEEDataSource) ds).internalJMXUnregister();
-        }
-        ds.close(true);
+        return converted;
     }
 
     public static class TomEEDataSource extends org.apache.tomcat.jdbc.pool.DataSource implements Serializable {
@@ -251,27 +157,6 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
         }
 
         private static PoolConfiguration readOnly(final PoolConfiguration pool) {
-            // if validationQuery is not filled disable testXXX
-            if (pool.getValidationQuery() == null || pool.getValidationQuery().isEmpty()) {
-                if (pool.isTestOnBorrow()) {
-                    LOGGER.info("Disabling testOnBorrow since no validation query is provided");
-                    pool.setTestOnBorrow(false);
-                }
-                if (pool.isTestOnConnect()) {
-                    LOGGER.info("Disabling testOnConnect since no validation query is provided");
-                    pool.setTestOnConnect(false);
-                }
-                if (pool.isTestOnReturn()) {
-                    LOGGER.info("Disabling testOnReturn since no validation query is provided");
-                    pool.setTestOnReturn(false);
-                }
-                if (pool.isTestWhileIdle()) {
-                    LOGGER.info("Disabling testWhileIdle since no validation query is provided");
-                    pool.setTestWhileIdle(false);
-                }
-            }
-
-            // prevent overriding of the configuration
             try {
                 return (PoolConfiguration) Proxy.newProxyInstance(TomEEDataSourceCreator.class.getClassLoader(), CONNECTION_POOL_CLASS, new ReadOnlyConnectionpool(pool));
             } catch (final Throwable e) {
@@ -361,4 +246,31 @@ public class TomEEDataSourceCreator extends PoolDataSourceCreator {
             return con;
         }
     }
+
+    // enhanced API/setters
+    public static class TomEEPoolProperties extends PoolProperties {
+        public void setMinEvictableIdleTime(final String minEvictableIdleTime) {
+            final Duration duration = new Duration(minEvictableIdleTime);
+            super.setMinEvictableIdleTimeMillis((int) duration.getUnit().toMillis(duration.getTime()));
+        }
+
+        public void setTimeBetweenEvictionRuns(final String timeBetweenEvictionRuns) {
+            final Duration duration = new Duration(timeBetweenEvictionRuns);
+            super.setMinEvictableIdleTimeMillis((int) duration.getUnit().toMillis(duration.getTime()));
+        }
+
+        public void setXaDataSource(final String jndi) {
+            // we should do setDataSourceJNDI(jndi); but ATM tomcat doesnt do the lookup so using this as correct impl
+            try {
+                setDataSource(SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext().lookup("openejb:Resource/" + jndi));
+            } catch (final NamingException e) {
+                throw new IllegalStateException(e);
+            }
+        }
+
+        @Override
+        public void setDataSourceJNDI(final String jndi) {
+            super.setDataSourceJNDI("openejb:Resource/" + jndi);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
index 6cc369b..705f3a0 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatDataSourceFromPoolTest.java
@@ -19,8 +19,8 @@ package org.apache.tomee.jdbc;
 import org.apache.openejb.jee.EjbJar;
 import org.apache.openejb.jee.SingletonBean;
 import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.junit.Configuration;
-import org.apache.openejb.junit.Module;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
index 45704a1..0696b77 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolCipherPasswordTest.java
@@ -18,8 +18,8 @@ package org.apache.tomee.jdbc;
 
 import org.apache.openejb.jee.EjbJar;
 import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.junit.Configuration;
-import org.apache.openejb.junit.Module;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
 import org.apache.openejb.resource.jdbc.cipher.PasswordCipher;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -63,7 +63,7 @@ public class TomcatPoolCipherPasswordTest {
     public static void createTable() throws SQLException, ClassNotFoundException {
         Class.forName("org.hsqldb.jdbcDriver");
 
-        final Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
+        final Connection connection = DriverManager.getConnection(URL, USER, "");
         final Statement statement = connection.createStatement();
         statement.execute("CREATE TABLE " + TABLE + "(ID INTEGER)");
         statement.close();
@@ -77,8 +77,8 @@ public class TomcatPoolCipherPasswordTest {
         p.put("openejb.jdbc.datasource-creator", TomEEDataSourceCreator.class.getName());
 
         p.put("ciphered", "new://Resource?type=DataSource");
-        p.put("ciphered.JdbcDriver", "org.hsqldb.jdbcDriver");
-        p.put("ciphered.JdbcUrl", URL);
+        p.put("ciphered.DriverClassName", "org.hsqldb.jdbcDriver");
+        p.put("ciphered.Url", URL);
         p.put("ciphered.UserName", USER);
         p.put("ciphered.Password", PASSWORD);
         p.put("ciphered.PasswordCipher", "Mock");

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
index 658333f..aeeda3f 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatPoolTest.java
@@ -19,8 +19,8 @@ package org.apache.tomee.jdbc;
 import org.apache.openejb.jee.EjbJar;
 import org.apache.openejb.jee.SingletonBean;
 import org.apache.openejb.junit.ApplicationComposer;
-import org.apache.openejb.junit.Configuration;
-import org.apache.openejb.junit.Module;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -71,8 +71,8 @@ public class TomcatPoolTest {
         p.put("openejb.jdbc.datasource-creator", TomEEDataSourceCreator.class.getName());
 
         p.put("managed", "new://Resource?type=DataSource");
-        p.put("managed.JdbcDriver", "org.hsqldb.jdbcDriver");
-        p.put("managed.JdbcUrl", URL);
+        p.put("managed.DriverClassName", "org.hsqldb.jdbcDriver");
+        p.put("managed.Url", URL);
         p.put("managed.UserName", USER);
         p.put("managed.Password", PASSWORD);
         p.put("managed.JtaManaged", "true");

http://git-wip-us.apache.org/repos/asf/tomee/blob/8d2d7183/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
----------------------------------------------------------------------
diff --git a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
index f44b0bb..ecffcb9 100644
--- a/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
+++ b/tomee/tomee-jdbc/src/test/java/org/apache/tomee/jdbc/TomcatXADataSourceTest.java
@@ -55,12 +55,13 @@ public class TomcatXADataSourceTest {
             .p("txMgr.txRecovery", "true")
             .p("txMgr.logFileDir", "target/test/xa/howl")
 
-                // real XA datasources
+            // real XA datasources
             .p("xa", "new://Resource?class-name=" + JDBCXADataSource.class.getName())
             .p("xa.url", "jdbc:hsqldb:mem:tomcat-xa")
             .p("xa.user", "sa")
             .p("xa.password", "")
             .p("xa.SkipImplicitAttributes", "true")
+            .p("xa.SkipPropertiesFallback", "true") // otherwise goes to connection properties
 
             .p("xadb", "new://Resource?type=DataSource")
             .p("xadb.xaDataSource", "xa")