diff --git a/openjpa-integration/daytrader/pom.xml b/openjpa-integration/daytrader/pom.xml
index c2116a577..99a2e72f5 100644
--- a/openjpa-integration/daytrader/pom.xml
+++ b/openjpa-integration/daytrader/pom.xml
@@ -203,7 +203,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -219,7 +223,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}
diff --git a/openjpa-integration/jmx/pom.xml b/openjpa-integration/jmx/pom.xml
index f0c975028..4cfd6d660 100644
--- a/openjpa-integration/jmx/pom.xml
+++ b/openjpa-integration/jmx/pom.xml
@@ -125,16 +125,20 @@
${surefire.jvm.args}
- openjpa.Log
- ${openjpa.Log}
+ openjpa.Log
+ ${openjpa.Log}
- openjpa.DynamicEnhancementAgent
- false
+ openjpa.DynamicEnhancementAgent
+ false
- openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ openjpa.ConnectionDriverName
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -150,7 +154,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
diff --git a/openjpa-integration/slf4j/pom.xml b/openjpa-integration/slf4j/pom.xml
index be7c08917..65765ad57 100644
--- a/openjpa-integration/slf4j/pom.xml
+++ b/openjpa-integration/slf4j/pom.xml
@@ -159,7 +159,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -175,7 +179,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
diff --git a/openjpa-integration/validation/pom.xml b/openjpa-integration/validation/pom.xml
index d2d35d9e1..62a8b1584 100644
--- a/openjpa-integration/validation/pom.xml
+++ b/openjpa-integration/validation/pom.xml
@@ -245,7 +245,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -261,7 +265,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java
index 07f5e1ce7..174ddedaf 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/ant/ReverseMappingToolTask.java
@@ -277,7 +277,7 @@ public class ReverseMappingToolTask
// create and configure customizer
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
flags.customizer = (ReverseCustomizer) Configurations.
- newInstance(customizerClass, conf, null,
+ newInstance(customizerClass, conf, (String)null,
AccessController.doPrivileged(
J2DoPrivHelper.getClassLoaderAction(
ReverseCustomizer.class)));
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
index 8e0f0aba1..8a43e5b04 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/conf/JDBCConfigurationImpl.java
@@ -242,7 +242,9 @@ public class JDBCConfigurationImpl
driverDataSourcePlugin = addPlugin("jdbc.DriverDataSource", false);
aliases = new String[]{
+ "auto", "org.apache.openjpa.jdbc.schema.AutoDriverDataSource",
"simple", "org.apache.openjpa.jdbc.schema.SimpleDriverDataSource",
+ "dbcp", "org.apache.openjpa.jdbc.schema.DBCPDriverDataSource",
};
driverDataSourcePlugin.setAliases(aliases);
driverDataSourcePlugin.setDefault(aliases[0]);
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java
new file mode 100644
index 000000000..8eb8f6ab9
--- /dev/null
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/AutoDriverDataSource.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.apache.openjpa.lib.util.ConcreteClassGenerator;
+
+/**
+ * Automatic Commons DBCP pooling or Simple non-pooling driver data source.
+ * If the commons-dbcp packages are on the class path, then they will be used,
+ * else it will fall back to non-DBCP mode.
+ */
+public abstract class AutoDriverDataSource
+ extends DBCPDriverDataSource {
+
+ private static final Class extends AutoDriverDataSource> implClass;
+
+ static {
+ try {
+ implClass = ConcreteClassGenerator.makeConcrete(AutoDriverDataSource.class);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ public static AutoDriverDataSource newInstance() {
+ return ConcreteClassGenerator.newInstance(implClass);
+ }
+
+ @Override
+ public Connection getConnection(Properties props) throws SQLException {
+ // if we're using managed transactions, or user specified a DBCP driver
+ // or DBCP is not on the classpath, then use SimpleDriver
+ if (conf == null || conf.isTransactionModeManaged() || conf.isConnectionFactoryModeManaged() ||
+ !isDBCPLoaded()) {
+ return getSimpleConnection(props);
+ } else {
+ // use DBCPDriverDataSource
+ return getDBCPConnection(props);
+ }
+ }
+}
diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java
new file mode 100644
index 000000000..0554df3ef
--- /dev/null
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/DBCPDriverDataSource.java
@@ -0,0 +1,296 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.jdbc.schema;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
+import org.apache.openjpa.lib.conf.Configurable;
+import org.apache.openjpa.lib.conf.Configuration;
+import org.apache.openjpa.lib.conf.Configurations;
+import org.apache.openjpa.lib.util.ConcreteClassGenerator;
+
+/**
+ * Commons DBCP basic pooling driver data source.
+ * The commons-dbcp packages must be on the class path for this plugin to work,
+ * as it WILL NOT fall back to non-DBCP mode if they are missing. For automatic
+ * usage of Commons DBCP when available, use AutoDriverDataSource instead.
+ */
+public abstract class DBCPDriverDataSource
+extends SimpleDriverDataSource implements Configurable {
+
+ private static String DBCPPACKAGENAME = "org.apache.commons.dbcp";
+ private static String DBCPBASICDATASOURCENAME = "org.apache.commons.dbcp.BasicDataSource";
+ protected JDBCConfiguration conf;
+ private Class> _dbcpClass;
+ private Boolean _dbcpAvail;
+ private RuntimeException _dbcpEx;
+ private DataSource _ds;
+
+ private static final Class extends DBCPDriverDataSource> implClass;
+
+ static {
+ try {
+ implClass = ConcreteClassGenerator.makeConcrete(DBCPDriverDataSource.class);
+ } catch (Exception e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
+ public static DBCPDriverDataSource newInstance() {
+ return ConcreteClassGenerator.newInstance(implClass);
+ }
+
+ @Override
+ public Connection getConnection(Properties props) throws SQLException {
+ return getDBCPConnection(props);
+ }
+
+ protected Connection getDBCPConnection(Properties props) throws SQLException {
+ Connection con = getDBCPDataSource(props).getConnection();
+ if (con == null) {
+ throw new SQLException(_eloc.get("dbcp-ds-null",
+ DBCPBASICDATASOURCENAME, getConnectionDriverName(), getConnectionURL()).getMessage());
+ }
+ return con;
+ }
+
+ protected DataSource getDBCPDataSource(Properties props) {
+ if (isDBCPLoaded()) {
+ if (_ds == null) {
+ Properties dbcpProps = updateDBCPProperties(props);
+ _ds = (DataSource) Configurations.newInstance(DBCPBASICDATASOURCENAME, conf,
+ dbcpProps, getClassLoader());
+ return _ds;
+ } else {
+ return _ds;
+ }
+ } else {
+ // user chose DBCP, so fail if it isn't on the classpath
+ throw _dbcpEx;
+ }
+ }
+
+ /**
+ * This method should not throw an exception, as it is called by
+ * AutoDriverDataSource to determine if user already specified
+ * to use Commons DBCP.
+ * @return true if ConnectionDriverName contains org.apache.commons.dbcp,
+ * otherwise false
+ */
+ protected boolean isDBCPDataSource() {
+ return (getConnectionDriverName() != null &&
+ getConnectionDriverName().toLowerCase().indexOf(DBCPPACKAGENAME) >= 0);
+ }
+
+ /**
+ * This method should not throw an exception, as it is called by
+ * AutoDriverDataSource to determine if it should use DBCP or not
+ * based on if org.apache.commons.dbcp.BasicDataSource can be loaded.
+ * @return true if Commons DBCP was found on the classpath, otherwise false
+ */
+ protected boolean isDBCPLoaded() {
+ if (Boolean.TRUE.equals(_dbcpAvail) && (_dbcpClass != null)) {
+ return true;
+ } else if (Boolean.FALSE.equals(_dbcpAvail)) {
+ return false;
+ } else {
+ // first time checking, so try to load it
+ try {
+ _dbcpClass = Class.forName(DBCPBASICDATASOURCENAME, true, getClassLoader());
+ _dbcpAvail = Boolean.TRUE;
+ return true;
+ } catch (Exception e) {
+ _dbcpAvail = Boolean.FALSE;
+ // save exception details for later instead of throwing here
+ _dbcpEx = new RuntimeException(_eloc.get("driver-null", DBCPBASICDATASOURCENAME).getMessage(), e);
+ }
+ return _dbcpAvail.booleanValue();
+ }
+ }
+
+ /**
+ * Normalize properties for Commons DBCP. This should be done for every call from DataSourceFactory,
+ * as we do not have a pre-configured Driver to reuse.
+ * @param props
+ * @return updated properties
+ */
+ private Properties updateDBCPProperties(Properties props) {
+ Properties dbcpProps = mergeConnectionProperties(props);
+
+ // only perform the following check for the first connection attempt (_driverClassName == null),
+ // as multiple connections could be requested (like from SchemaTool) and isDBCPDriver() will be true
+ if (isDBCPDataSource()) {
+ String propDriver = hasProperty(dbcpProps, "DriverClassName");
+ if (propDriver == null || propDriver.trim().isEmpty()) {
+ // if user specified DBCP for the connectionDriverName, then make sure they supplied a DriverClassName
+ throw new RuntimeException(_eloc.get("connection-property-invalid", "DriverClassName",
+ propDriver).getMessage());
+ }
+ propDriver = hasProperty(dbcpProps, "Url");
+ if (propDriver == null || propDriver.trim().isEmpty()) {
+ // if user specified DBCP for the connectionDriverName, then make sure they supplied a Url
+ throw new RuntimeException(_eloc.get("connection-property-invalid", "Url",
+ propDriver).getMessage());
+ }
+ } else {
+ // set Commons DBCP expected DriverClassName to the original connection driver name
+ dbcpProps.setProperty(hasKey(dbcpProps, "DriverClassName", "DriverClassName"), getConnectionDriverName());
+ // set Commons DBCP expected URL property
+ dbcpProps.setProperty(hasKey(dbcpProps, "Url", "Url"), getConnectionURL());
+ }
+
+ // Commons DBCP requires non-Null username/password values in the connection properties
+ if (hasKey(dbcpProps, "Username") == null) {
+ if (getConnectionUserName() != null)
+ dbcpProps.setProperty("Username", getConnectionUserName());
+ else
+ dbcpProps.setProperty("Username", "");
+ }
+ // Commons DBCP requires non-Null username/password values in the connection properties
+ if (hasKey(dbcpProps, "Password") == null) {
+ if (getConnectionPassword() != null)
+ dbcpProps.setProperty("Password", getConnectionPassword());
+ else
+ dbcpProps.setProperty("Password", "");
+ }
+
+ // set some default properties for DBCP
+ if (hasKey(dbcpProps, "MaxIdle") == null) {
+ dbcpProps.setProperty("MaxIdle", "1");
+ }
+ if (hasKey(dbcpProps, "MinIdle") == null) {
+ dbcpProps.setProperty("MinIdle", "0");
+ }
+ if (hasKey(dbcpProps, "MaxActive") == null) {
+ dbcpProps.setProperty("MaxActive", "10");
+ }
+
+ return dbcpProps;
+ }
+
+ /**
+ * Merge the passed in properties with a copy of the existing _connectionProperties
+ * @param props
+ * @return Merged properties
+ */
+ private Properties mergeConnectionProperties(final Properties props) {
+ Properties mergedProps = new Properties();
+ mergedProps.putAll(getConnectionProperties());
+
+ // need to map "user" to "username" for Commons DBCP
+ String uid = removeProperty(mergedProps, "user");
+ if (uid != null) {
+ mergedProps.setProperty("Username", uid);
+ }
+
+ // now, merge in any passed in properties
+ if (props != null && !props.isEmpty()) {
+ for (Iteratoropenjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -73,7 +77,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
@@ -1019,7 +1023,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -1043,7 +1051,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
diff --git a/openjpa-persistence-locking/pom.xml b/openjpa-persistence-locking/pom.xml
index f28e40499..19d4a9cbc 100644
--- a/openjpa-persistence-locking/pom.xml
+++ b/openjpa-persistence-locking/pom.xml
@@ -75,7 +75,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -83,7 +87,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure
@@ -799,7 +803,11 @@
openjpa.ConnectionDriverName
- org.apache.commons.dbcp.BasicDataSource
+ ${connection.driver.name}
+
+
+ openjpa.ConnectionURL
+ ${connection.url}derby.stream.error.file
@@ -815,7 +823,7 @@
openjpa.ConnectionProperties
- DriverClassName=${connection.driver.name},Url=${connection.url},Username=${connection.username},Password=${connection.password},${dbcp.args}
+ Username=${connection.username},Password=${connection.password},${dbcp.args}tests.openjpa.allowfailure