Index: build.properties =================================================================== --- build.properties (revision 1721032) +++ build.properties (working copy) @@ -85,6 +85,11 @@ commons-collections.loc = ${maven2.repo}/commons-collections/commons-collections/${commons-collections.version} commons-collections.md5 = f54a8510f834a1a57166970bfc982e94 +commons-dbcp2.version = 2.1.1 +commons-dbcp2.jar = commons-dbcp2-${commons-dbcp2.version}.jar +commons-dbcp2.loc = ${maven2.repo}/org/apache/commons/commons-dbcp2/${commons-dbcp2.version} +commons-dbcp2.md5 = 298897b1e785b933b0522351871cf7ae + commons-httpclient.version = 3.1 commons-httpclient.jar = commons-httpclient-${commons-httpclient.version}.jar commons-httpclient.loc = ${maven2.repo}/commons-httpclient/commons-httpclient/${commons-httpclient.version} @@ -110,7 +115,6 @@ commons-lang3.loc = ${maven2.repo}/org/apache/commons/commons-lang3/${commons-lang3.version} commons-lang3.md5 = 8667a442ee77e509fbe8176b94726eb2 - commons-logging.version = 1.2 commons-logging.jar = commons-logging-${commons-logging.version}.jar commons-logging.loc = ${maven2.repo}/commons-logging/commons-logging/${commons-logging.version} @@ -139,38 +143,11 @@ dnsjava.loc = ${maven2.repo}/dnsjava/dnsjava/${dnsjava.version} dnsjava.md5 = 11363bd58696feae207a992da2ce7a90 -excalibur-instrument.version = 1.0 -excalibur-instrument.jar = excalibur-instrument-${excalibur-instrument.version}.jar -excalibur-instrument.loc = ${maven2.repo}/excalibur-instrument/excalibur-instrument/${excalibur-instrument.version} -excalibur-instrument.md5 = 81BF95737C97A46836EA5F21F7C82719 - excalibur-logger.version = 1.1 excalibur-logger.jar = excalibur-logger-${excalibur-logger.version}.jar excalibur-logger.loc = ${maven2.repo}/excalibur-logger/excalibur-logger/${excalibur-logger.version} excalibur-logger.md5 = E8246C546B7B0CAFD65947E9B80BB884 -excalibur-datasource.version = 2.1 -excalibur-datasource.jar = excalibur-datasource-${excalibur-datasource.version}.jar -excalibur-datasource.loc = ${maven2.repo}/excalibur-datasource/excalibur-datasource/${excalibur-datasource.version} -excalibur-datasource.md5 = 7a57ccdfeda3a4f157016f5a9270a4f9 - -# pool has been split into 3 parts -excalibur-pool.version = 2.1 -excalibur-pool-api.version = ${excalibur-pool.version} -excalibur-pool-api.jar = excalibur-pool-api-${excalibur-pool-api.version}.jar -excalibur-pool-api.loc = ${maven2.repo}/excalibur-pool/excalibur-pool-api/${excalibur-pool-api.version} -excalibur-pool-api.md5 = f9a224e1ee0896764aadbf7ddd253acc - -excalibur-pool-impl.version = ${excalibur-pool.version} -excalibur-pool-impl.jar = excalibur-pool-impl-${excalibur-pool-impl.version}.jar -excalibur-pool-impl.loc = ${maven2.repo}/excalibur-pool/excalibur-pool-impl/${excalibur-pool-impl.version} -excalibur-pool-impl.md5 = 8be9c177894998090b4662326d7f22de - -excalibur-pool-instrumented.version = ${excalibur-pool.version} -excalibur-pool-instrumented.jar = excalibur-pool-instrumented-${excalibur-pool-instrumented.version}.jar -excalibur-pool-instrumented.loc = ${maven2.repo}/excalibur-pool/excalibur-pool-instrumented/${excalibur-pool-instrumented.version} -excalibur-pool-instrumented.md5 = 1b5425fe0fe63dc67da6fe995db6be31 - # Freemarker freemarker.version = 2.3.23 freemarker.loc = ${maven2.repo}/org/freemarker/freemarker/${freemarker.version} Index: build.xml =================================================================== --- build.xml (revision 1719635) +++ build.xml (working copy) @@ -365,6 +365,7 @@ + @@ -375,12 +376,7 @@ - - - - - @@ -442,6 +438,7 @@ + @@ -452,12 +449,7 @@ - - - - - @@ -488,7 +480,7 @@ - + @@ -2843,6 +2835,7 @@ + @@ -2853,12 +2846,7 @@ - - - - - @@ -2925,7 +2913,6 @@ - Index: eclipse.classpath =================================================================== --- eclipse.classpath (revision 1721032) +++ eclipse.classpath (working copy) @@ -48,6 +48,7 @@ + @@ -58,12 +59,7 @@ - - - - - Index: lib/aareadme.txt =================================================================== --- lib/aareadme.txt (revision 1720926) +++ lib/aareadme.txt (working copy) @@ -91,22 +91,10 @@ http://www.dnsjava.org/download/ - DNSCacheManager -excalibur-datasource-1.1.1 (org.apache.avalon.excalibur.datasource) --------------------------- -- DataSourceElement (JDBC) - -excalibur-instrument-1.0 (org.apache.excalibur.instrument) ------------------------- -- used by excalibur-datasource - excalibur-logger-1.1 (org.apache.avalon.excalibur.logger) -------------------- - LoggingManager -excalibur-pool-1.2 (org.apache.avalon.excalibur.pool) ------------------- -- used by excalibur-datasource - freemarker-2.3.23.jar ---------------------- - used by Report/Dashboard feature @@ -227,6 +215,10 @@ http://tika.apache.org/ - Regular Expression Extractor +commons-dbcp2-2.1.1 (org.apache.commons.dbcp2) +-------------------------- +- DataSourceElement (JDBC) + velocity-1.7 -------------- http://velocity.apache.org/download.cgi Index: licenses/bin/README.txt =================================================================== --- licenses/bin/README.txt (revision 1721032) +++ licenses/bin/README.txt (working copy) @@ -7,6 +7,7 @@ bshclient.jar (part of JMeter) commons-codec-1.10.jar commons-collections-3.2.2.jar +commons-dbcp2-2.1.1.jar commons-httpclient-3.1.jar commons-io-2.4.jar commons-jexl-1.1.jar @@ -16,12 +17,7 @@ commons-math3-3.5.jar commons-net-3.4.jar commons-pool2-2.4.2.jar -excalibur-datasource-2.1.jar -excalibur-instrument-1.0.jar excalibur-logger-1.1.jar -excalibur-pool-api-2.1.jar -excalibur-pool-impl-2.1.jar -excalibur-pool-instrumented-2.1.jar geronimo-jms_1.1_spec-1.1.1.jar httpclient-4.5.1.jar httpcore-4.4.4.jar Index: res/maven/ApacheJMeter_parent.pom =================================================================== --- res/maven/ApacheJMeter_parent.pom (revision 1721032) +++ res/maven/ApacheJMeter_parent.pom (working copy) @@ -60,6 +60,7 @@ 1.49 1.10 3.2.2 + 2.1.1 3.1 2.4 1.1 @@ -70,13 +71,7 @@ 3.4 2.4.2 2.1.7 - 2.1 - 1.0 1.1 - 2.1 - ${excalibur-pool.version} - ${excalibur-pool.version} - ${excalibur-pool.version} 2.3.23 2.1 4.5.1 @@ -155,6 +150,11 @@ ${commons-collections.version} + org.apache.commons + commons-dbcp2 + ${commons-dbcp2.version} + + commons-httpclient commons-httpclient ${commons-httpclient.version} @@ -205,46 +205,11 @@ ${dnsjava.version} - excalibur-datasource - excalibur-datasource - ${excalibur-datasource.version} - - - excalibur-fortress - excalibur-fortress-container-api - - - excalibur-fortress - excalibur-fortress-meta - - - - - excalibur-instrument - excalibur-instrument - ${excalibur-instrument.version} - - excalibur-logger excalibur-logger ${excalibur-logger.version} - excalibur-pool - excalibur-pool-api - ${excalibur-pool-api.version} - - - excalibur-pool - excalibur-pool-impl - ${excalibur-pool-impl.version} - - - excalibur-pool - excalibur-pool-instrumented - ${excalibur-pool-instrumented.version} - - org.htmlparser htmllexer ${htmlparser.version} Index: src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/config/DataSourceElement.java =================================================================== --- src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/config/DataSourceElement.java (revision 1721822) +++ src/protocol/jdbc/org/apache/jmeter/protocol/jdbc/config/DataSourceElement.java (working copy) @@ -24,12 +24,7 @@ import java.util.Map; import java.util.Set; -import org.apache.avalon.excalibur.datasource.DataSourceComponent; -import org.apache.avalon.excalibur.datasource.ResourceLimitingJdbcDataSource; -import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.avalon.framework.configuration.DefaultConfiguration; -import org.apache.avalon.framework.logger.LogKitLogger; +import org.apache.commons.dbcp2.BasicDataSource; import org.apache.jmeter.config.ConfigElement; import org.apache.jmeter.testbeans.TestBean; import org.apache.jmeter.testbeans.TestBeanHelper; @@ -42,26 +37,35 @@ import org.apache.log.Logger; public class DataSourceElement extends AbstractTestElement - implements ConfigElement, TestStateListener, TestBean - { + implements ConfigElement, TestStateListener, TestBean { private static final Logger log = LoggingManager.getLoggerForClass(); - private static final long serialVersionUID = 233L; + private static final long serialVersionUID = 234L; - private transient String dataSource, driver, dbUrl, username, password, checkQuery, poolMax, connectionAge, timeout, - trimInterval,transactionIsolation; + private transient String dataSource; + private transient String driver; + private transient String dbUrl; + private transient String username; + private transient String password; + private transient String checkQuery; + private transient String poolMax; + private transient String connectionAge; + private transient String timeout; + private transient String trimInterval; + private transient String transactionIsolation; - private transient boolean keepAlive, autocommit; + private transient boolean keepAlive; + private transient boolean autocommit; /* * The datasource is set up by testStarted and cleared by testEnded. * These are called from different threads, so access must be synchronized. * The same instance is called in each case. */ - private transient ResourceLimitingJdbcDataSource excaliburSource; + private transient BasicDataSource dbcpDataSource; // Keep a record of the pre-thread pools so that they can be disposed of at the end of a test - private transient Set perThreadPoolSet; + private transient Set perThreadPoolSet; public DataSourceElement() { } @@ -69,15 +73,23 @@ @Override public void testEnded() { synchronized (this) { - if (excaliburSource != null) { - excaliburSource.dispose(); + if (dbcpDataSource != null) { + try { + dbcpDataSource.close(); + } catch (SQLException ex) { + log.error("Error closing pool:"+getName(), ex); + } } - excaliburSource = null; + dbcpDataSource = null; } if (perThreadPoolSet != null) {// in case - for(ResourceLimitingJdbcDataSource dsc : perThreadPoolSet){ - log.debug("Disposing pool: "+dsc.getInstrumentableName()+" @"+System.identityHashCode(dsc)); - dsc.dispose(); + for(BasicDataSource dsc : perThreadPoolSet){ + log.debug("Closing pool: "+dsc.getJmxName()+" @"+System.identityHashCode(dsc)); + try { + dsc.close(); + } catch (SQLException ex) { + log.error("Error closing pool:"+getName(), ex); + } } perThreadPoolSet=null; } @@ -100,14 +112,14 @@ log.error("JDBC data source already defined for: "+poolName); } else { String maxPool = getPoolMax(); - perThreadPoolSet = Collections.synchronizedSet(new HashSet()); + perThreadPoolSet = Collections.synchronizedSet(new HashSet()); if (maxPool.equals("0")){ // i.e. if we want per thread pooling variables.putObject(poolName, new DataSourceComponentImpl()); // pool will be created later } else { - ResourceLimitingJdbcDataSource src=initPool(maxPool); + BasicDataSource src=initPool(maxPool); synchronized(this){ - excaliburSource = src; - variables.putObject(poolName, new DataSourceComponentImpl(excaliburSource)); + dbcpDataSource = src; + variables.putObject(poolName, new DataSourceComponentImpl(dbcpDataSource)); } } } @@ -122,7 +134,7 @@ public Object clone() { DataSourceElement el = (DataSourceElement) super.clone(); synchronized (this) { - el.excaliburSource = excaliburSource; + el.dbcpDataSource = dbcpDataSource; el.perThreadPoolSet = perThreadPoolSet; } return el; @@ -140,8 +152,8 @@ if (poolObject == null) { throw new SQLException("No pool found named: '" + poolName + "', ensure Variable Name matches Variable Name of JDBC Connection Configuration"); } else { - if(poolObject instanceof DataSourceComponent) { - DataSourceComponent pool = (DataSourceComponent) poolObject; + if(poolObject instanceof DataSourceComponentImpl) { + DataSourceComponentImpl pool = (DataSourceComponentImpl) poolObject; return pool.getConnection(); } else { String errorMsg = "Found object stored under variable:'"+poolName @@ -156,10 +168,8 @@ * Set up the DataSource - maxPool is a parameter, so the same code can * also be used for setting up the per-thread pools. */ - private ResourceLimitingJdbcDataSource initPool(String maxPool) { - ResourceLimitingJdbcDataSource source = null; - source = new ResourceLimitingJdbcDataSource(); - DefaultConfiguration config = new DefaultConfiguration("rl-jdbc"); // $NON-NLS-1$ + private BasicDataSource initPool(String maxPool) { + BasicDataSource dataSource = new BasicDataSource(); if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder(40); @@ -173,17 +183,14 @@ sb.append(isAutocommit()); log.debug(sb.toString()); } - DefaultConfiguration poolController = new DefaultConfiguration("pool-controller"); // $NON-NLS-1$ - poolController.setAttribute("max", maxPool); // $NON-NLS-1$ - poolController.setAttribute("max-strict", "true"); // $NON-NLS-1$ $NON-NLS-2$ - poolController.setAttribute("blocking", "true"); // $NON-NLS-1$ $NON-NLS-2$ - poolController.setAttribute("timeout", getTimeout()); // $NON-NLS-1$ - poolController.setAttribute("trim-interval", getTrimInterval()); // $NON-NLS-1$ - config.addChild(poolController); + int poolSize = Integer.parseInt(maxPool); + dataSource.setMinIdle(0); + dataSource.setInitialSize(poolSize); + dataSource.setMaxIdle(poolSize); + dataSource.setMaxTotal(poolSize); + dataSource.setMaxWaitMillis(Long.parseLong(getTimeout())); - DefaultConfiguration autoCommit = new DefaultConfiguration("auto-commit"); // $NON-NLS-1$ - autoCommit.setValue(String.valueOf(isAutocommit())); - config.addChild(autoCommit); + dataSource.setDefaultAutoCommit(Boolean.valueOf(isAutocommit())); if (log.isDebugEnabled()) { StringBuilder sb = new StringBuilder(40); @@ -195,11 +202,22 @@ sb.append(getCheckQuery()); log.debug(sb.toString()); } - DefaultConfiguration cfgKeepAlive = new DefaultConfiguration("keep-alive"); // $NON-NLS-1$ - cfgKeepAlive.setAttribute("disable", String.valueOf(!isKeepAlive())); // $NON-NLS-1$ - cfgKeepAlive.setAttribute("age", getConnectionAge()); // $NON-NLS-1$ - cfgKeepAlive.setValue(getCheckQuery()); - poolController.addChild(cfgKeepAlive); + dataSource.setTestOnBorrow(false); + dataSource.setTestOnReturn(false); + dataSource.setTestOnCreate(false); + dataSource.setTestWhileIdle(false); + + if(isKeepAlive()) { + dataSource.setTestWhileIdle(true); + dataSource.setValidationQuery(getCheckQuery()); + dataSource.setMaxConnLifetimeMillis(Long.parseLong(getConnectionAge())); + dataSource.setTimeBetweenEvictionRunsMillis(Integer.parseInt(getTrimInterval())); + } + + int transactionIsolation = DataSourceElementBeanInfo.getTransactionIsolationMode(getTransactionIsolation()); + if (transactionIsolation >= 0) { + dataSource.setDefaultTransactionIsolation(transactionIsolation); + } String _username = getUsername(); if (log.isDebugEnabled()) { @@ -212,38 +230,27 @@ sb.append(_username); log.debug(sb.toString()); } - DefaultConfiguration cfgDriver = new DefaultConfiguration("driver"); // $NON-NLS-1$ - cfgDriver.setValue(getDriver()); - config.addChild(cfgDriver); - DefaultConfiguration cfgDbUrl = new DefaultConfiguration("dburl"); // $NON-NLS-1$ - cfgDbUrl.setValue(getDbUrl()); - config.addChild(cfgDbUrl); + dataSource.setDriverClassName(getDriver()); + dataSource.setUrl(getDbUrl()); if (_username.length() > 0){ - DefaultConfiguration cfgUsername = new DefaultConfiguration("user"); // $NON-NLS-1$ - cfgUsername.setValue(_username); - config.addChild(cfgUsername); - DefaultConfiguration cfgPassword = new DefaultConfiguration("password"); // $NON-NLS-1$ - cfgPassword.setValue(getPassword()); - config.addChild(cfgPassword); + dataSource.setUsername(_username); + dataSource.setPassword(getPassword()); } // log is required to ensure errors are available - source.enableLogging(new LogKitLogger(log)); - try { - source.configure(config); - source.setInstrumentableName(getDataSource()); - } catch (ConfigurationException e) { - log.error("Could not configure datasource for pool: "+getDataSource(),e); + //source.enableLogging(new LogKitLogger(log)); + if(log.isDebugEnabled()) { + log.debug("PoolConfiguration:"+this.dataSource); } - return source; + return dataSource; } // used to hold per-thread singleton connection pools - private static final ThreadLocal> perThreadPoolMap = - new ThreadLocal>(){ + private static final ThreadLocal> perThreadPoolMap = + new ThreadLocal>(){ @Override - protected Map initialValue() { + protected Map initialValue() { return new HashMap<>(); } }; @@ -253,31 +260,34 @@ * and per-thread pools. * */ - private class DataSourceComponentImpl implements DataSourceComponent{ + private class DataSourceComponentImpl { - private final ResourceLimitingJdbcDataSource sharedDSC; + private final BasicDataSource sharedDSC; DataSourceComponentImpl(){ sharedDSC=null; } - DataSourceComponentImpl(ResourceLimitingJdbcDataSource p_dsc){ + DataSourceComponentImpl(BasicDataSource p_dsc){ sharedDSC=p_dsc; } - @Override + /** + * @return Connection + * @throws SQLException + */ public Connection getConnection() throws SQLException { Connection conn = null; - ResourceLimitingJdbcDataSource dsc = null; + BasicDataSource dsc = null; if (sharedDSC != null){ // i.e. shared pool dsc = sharedDSC; } else { - Map poolMap = perThreadPoolMap.get(); - dsc = poolMap.get(getDataSource()); + Map poolMap = perThreadPoolMap.get(); + dsc = poolMap.get(getDataSourceName()); if (dsc == null){ dsc = initPool("1"); - poolMap.put(getDataSource(),dsc); - log.debug("Storing pool: "+dsc.getInstrumentableName()+" @"+System.identityHashCode(dsc)); + poolMap.put(getDataSourceName(),dsc); + log.debug("Storing pool: "+getName()+" @"+System.identityHashCode(dsc)); perThreadPoolSet.add(dsc); } } @@ -298,11 +308,6 @@ } return conn; } - - @Override - public void configure(Configuration arg0) throws ConfigurationException { - } - } @Override @@ -358,6 +363,10 @@ public void setDataSource(String dataSource) { this.dataSource = dataSource; } + + private String getDataSourceName() { + return getDataSource(); + } /** * @return Returns the dbUrl. Index: xdocs/usermanual/component_reference.xml =================================================================== --- xdocs/usermanual/component_reference.xml (revision 1722342) +++ xdocs/usermanual/component_reference.xml (working copy) @@ -4143,7 +4143,7 @@ Pool throws an error if the timeout period is exceeded in the process of trying to retrieve a connection - This is used to specify how long idle connections will be maintained in the pool before being closed. For a complete explanation on how this works, see ResourceLimitingPool.trim() (Defaults to "60000", 1 minute) + This is used to specify how long idle connections will be maintained in the pool before being closed. (Defaults to "60000", 1 minute) Turn auto commit on or off for the connections. The keep-alive is used enable a mechanism to monitor the health of connections. If a connection has not been used for Max Connection Age (ms) then before returning the connection from a call to getConnection(), the connection is first used to ping the database to make sure that it is still alive. Setting the age allows the 5 second age to be overridden. Validation Query will be used to test it.