Skip to content
Commits on Source (8)
...@@ -18,8 +18,11 @@ sudo: false ...@@ -18,8 +18,11 @@ sudo: false
jdk: jdk:
- openjdk7 - openjdk7
- openjdk8
- openjdk11
- openjdk12
- oraclejdk8 - oraclejdk8
- oraclejdk9 - oraclejdk11
script: script:
- mvn - mvn
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
| commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates | | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+======================================================================+ +======================================================================+
| | | |
| 1) Re-generate using: mvn commons:contributing-md | | 1) Re-generate using: mvn commons-build:contributing-md |
| | | |
| 2) Set the following properties in the component's pom: | | 2) Set the following properties in the component's pom: |
| - commons.jira.id (required, alphabetic, upper case) | | - commons.jira.id (required, alphabetic, upper case) |
......
Apache Commons Pool Apache Commons Pool
Copyright 2001-2018 The Apache Software Foundation Copyright 2001-2019 The Apache Software Foundation
This product includes software developed at This product includes software developed at
The Apache Software Foundation (http://www.apache.org/). The Apache Software Foundation (http://www.apache.org/).
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
| commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates | | commons-build-plugin/trunk/src/main/resources/commons-xdoc-templates |
+======================================================================+ +======================================================================+
| | | |
| 1) Re-generate using: mvn commons:readme-md | | 1) Re-generate using: mvn commons-build:readme-md |
| | | |
| 2) Set the following properties in the component's pom: | | 2) Set the following properties in the component's pom: |
| - commons.componentid (required, alphabetic, lower case) | | - commons.componentid (required, alphabetic, lower case) |
...@@ -46,7 +46,7 @@ Apache Commons Pool ...@@ -46,7 +46,7 @@ Apache Commons Pool
[![Build Status](https://travis-ci.org/apache/commons-pool.svg)](https://travis-ci.org/apache/commons-pool) [![Build Status](https://travis-ci.org/apache/commons-pool.svg)](https://travis-ci.org/apache/commons-pool)
[![Coverage Status](https://coveralls.io/repos/apache/commons-pool/badge.svg)](https://coveralls.io/r/apache/commons-pool) [![Coverage Status](https://coveralls.io/repos/apache/commons-pool/badge.svg)](https://coveralls.io/r/apache/commons-pool)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-pool2/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-pool2/) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-pool2/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.apache.commons/commons-pool2/)
[![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-pool2/2.6.0.svg)](https://javadoc.io/doc/org.apache.commons/commons-pool2/2.6.0) [![Javadocs](https://javadoc.io/badge/org.apache.commons/commons-pool2/2.6.2.svg)](https://javadoc.io/doc/org.apache.commons/commons-pool2/2.6.2)
The Apache Commons Object Pooling Library. The Apache Commons Object Pooling Library.
...@@ -54,7 +54,7 @@ Documentation ...@@ -54,7 +54,7 @@ Documentation
------------- -------------
More information can be found on the [Apache Commons Pool homepage](https://commons.apache.org/proper/commons-pool). More information can be found on the [Apache Commons Pool homepage](https://commons.apache.org/proper/commons-pool).
The [Javadoc](https://commons.apache.org/proper/commons-pool/javadocs/api-release) can be browsed. The [Javadoc](https://commons.apache.org/proper/commons-pool/apidocs) can be browsed.
Questions related to the usage of Apache Commons Pool should be posted to the [user mailing list][ml]. Questions related to the usage of Apache Commons Pool should be posted to the [user mailing list][ml].
Where can I get the latest release? Where can I get the latest release?
...@@ -67,7 +67,7 @@ Alternatively you can pull it from the central Maven repositories: ...@@ -67,7 +67,7 @@ Alternatively you can pull it from the central Maven repositories:
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
<version>2.6.0</version> <version>2.6.2</version>
</dependency> </dependency>
``` ```
......
Apache Commons Pool 2.6.2 RELEASE NOTES
The Apache Commons Pool team is pleased to announce the release of Apache Commons Pool 2.6.2.
Apache Commons Pool provides an object-pooling API and a number of object pool implementations.
Version 2 contains a completely re-written pooling implementation compared to the 1.x series.
In addition to performance and scalability improvements, version 2 includes robust instance
tracking and pool monitoring. Version 2 requires JDK level 1.6 or above.
No client code changes are required to migrate from versions 2.0-2.3 to version 2.4.3.
Users of version 1.x should consult the migration guide on the Commons Pool web site.
NOTE: The MBean interfaces (DefaultPooledObjectInfoMBean, GenericKeyedObjectPoolMXBean
and GenericKeyedObjectPoolMXBean) exist only to define the attributes and methods
that will be made available via JMX. They must not be implemented by clients as
they are subject to change between major, minor and patch version releases of
Commons Pool. Clients that implement any of these interfaces may not, therefore,
be able to upgrade to a new minor or patch release without requiring code
changes.
This is a maintenance release.
Changes in version 2.6.2 include:
Fixed Bugs:
o POOL-362: Always null out org.apache.commons.pool2.impl.BaseGenericObjectPool.evictionIterator to match org.apache.commons.pool2.impl.BaseGenericObjectPool.evictor.
o POOL-363: Evictor Thread prevents Spring Context shutdown in standalone app. Thanks to Josh Landin.
o POOL-348: The commons-pool-evictor-thread should run as a Deamon. Thanks to Josh Landin.
For complete information on Apache Commons Pool, including instructions on how to submit bug reports,
patches, or suggestions for improvement, see the Apache Apache Commons Pool website:
http://commons.apache.org/proper/commons-pool/
Download page: http://commons.apache.org/proper/commons-pool/download_pool.cgi
-----------------------------------------------------------------------------------------------
Apache Commons Pool 2.6.1 RELEASE NOTES
The Apache Commons Pool team is pleased to announce the release of Apache Commons Pool 2.6.1.
Apache Commons Pool provides an object-pooling API and a number of object pool implementations.
Version 2 contains a completely re-written pooling implementation compared to the 1.x series.
In addition to performance and scalability improvements, version 2 includes robust instance
tracking and pool monitoring. Version 2 requires JDK level 1.6 or above.
No client code changes are required to migrate from versions 2.0-2.3 to version 2.4.3.
Users of version 1.x should consult the migration guide on the Commons Pool web site.
NOTE: The MBean interfaces (DefaultPooledObjectInfoMBean, GenericKeyedObjectPoolMXBean
and GenericKeyedObjectPoolMXBean) exist only to define the attributes and methods
that will be made available via JMX. They must not be implemented by clients as
they are subject to change between major, minor and patch version releases of
Commons Pool. Clients that implement any of these interfaces may not, therefore,
be able to upgrade to a new minor or patch release without requiring code
changes.
This is a maintenance release.
Changes in version 2.6.1 include:
Fixed Bugs:
o POOL-340: Correct validateObject with concurrent borrowObject Thanks to Pavel Kolesov.
o POOL-356: Fix deadlock on massive concurrent requests
o POOL-347: Method borrowObject waits for maxWaitMillis over in pool full. Thanks to Shunsuke Nakamura.
o POOL-359: NullPointerException closing multiple GenericObjectPools. Thanks to Michael Wintermeyer, Gary Gregory.
o POOL-326: Threading issue, NullPointerException and IllegalStateException in GenericKeyedObjectPool. Thanks to Chris Allison, Phil Steitz.
o POOL-352: CallStackUtils mishandles security manager check (partial fix.) Thanks to Volker Kleinschmidt, Gary Gregory.
Changes:
o POOL-345: Update optional library cglib from 3.2.6 to 3.2.9.
o POOL-346: Move common configuration setter to BaseGenericObjectPool #9. Thanks to Michael Chen.
o POOL-349: Update optional library asm-util from 6.2 to 7.0.
o POOL-360: Update optional library cglib from 3.2.9 to 3.2.10.
For complete information on Apache Commons Pool, including instructions on how to submit bug reports,
patches, or suggestions for improvement, see the Apache Apache Commons Pool website:
http://commons.apache.org/proper/commons-pool/
Download page: http://commons.apache.org/proper/commons-pool/download_pool.cgi
-----------------------------------------------------------------------------------------------
Apache Commons Pool 2.6.0 RELEASE NOTES Apache Commons Pool 2.6.0 RELEASE NOTES
The Apache Commons Pool team is pleased to announce the release of Apache Commons Pool 2.6.0. The Apache Commons Pool team is pleased to announce the release of Apache Commons Pool 2.6.0.
...@@ -48,6 +135,8 @@ patches, or suggestions for improvement, see the Apache Apache Commons Pool webs ...@@ -48,6 +135,8 @@ patches, or suggestions for improvement, see the Apache Apache Commons Pool webs
http://commons.apache.org/proper/commons-pool/ http://commons.apache.org/proper/commons-pool/
Download page: https://commons.apache.org/proper/commons-pool/download_pool.cgi
----------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------
Apache Commons Pool 2.5.0 RELEASE NOTES Apache Commons Pool 2.5.0 RELEASE NOTES
......
commons-pool2 (2.6.2-1) unstable; urgency=medium
* New upstream release
* Standards-Version updated to 4.4.0
* Use salsa.debian.org Vcs-* URLs
-- Emmanuel Bourg <ebourg@apache.org> Fri, 19 Jul 2019 10:00:20 +0200
commons-pool2 (2.6.0-1) unstable; urgency=medium commons-pool2 (2.6.0-1) unstable; urgency=medium
* Team upload. * Team upload.
......
...@@ -2,26 +2,22 @@ Source: commons-pool2 ...@@ -2,26 +2,22 @@ Source: commons-pool2
Section: java Section: java
Priority: optional Priority: optional
Maintainer: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org> Maintainer: Debian Java Maintainers <pkg-java-maintainers@lists.alioth.debian.org>
Uploaders: Uploaders: Emmanuel Bourg <ebourg@apache.org>
Emmanuel Bourg <ebourg@apache.org>
Build-Depends: Build-Depends:
debhelper (>= 11), debhelper (>= 11),
default-jdk, default-jdk,
junit4, junit4,
libcglib-java (>= 3.0), libcglib-java (>= 3.0),
maven-debian-helper (>= 1.5) maven-debian-helper (>= 1.5)
Standards-Version: 4.2.1 Standards-Version: 4.4.0
Vcs-Git: https://anonscm.debian.org/git/pkg-java/commons-pool2.git Vcs-Git: https://salsa.debian.org/java-team/commons-pool2.git
Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/commons-pool2.git Vcs-Browser: https://salsa.debian.org/java-team/commons-pool2
Homepage: http://commons.apache.org/pool/ Homepage: http://commons.apache.org/pool/
Package: libcommons-pool2-java Package: libcommons-pool2-java
Architecture: all Architecture: all
Depends: Depends:${misc:Depends}, ${maven:Depends}
${maven:Depends}, Suggests: ${maven:OptionalDepends}
${misc:Depends}
Suggests:
${maven:OptionalDepends}
Description: Apache Commons Pool 2 - Pooling implementation for Java objects Description: Apache Commons Pool 2 - Pooling implementation for Java objects
The Apache Commons Pool library provides an object-pooling API and a number The Apache Commons Pool library provides an object-pooling API and a number
of object pool implementations. Version 2 of Apache Commons Pool contains of object pool implementations. Version 2 of Apache Commons Pool contains
......
com.github.siom79.japicmp japicmp-maven-plugin * * * *
org.apache.maven.plugins maven-antrun-plugin * * * * org.apache.maven.plugins maven-antrun-plugin * * * *
org.apache.maven.plugins maven-assembly-plugin * * * * org.apache.maven.plugins maven-assembly-plugin * * * *
org.apache.maven.plugins maven-changes-plugin * * * * org.apache.maven.plugins maven-changes-plugin * * * *
......
#!/usr/bin/make -f #!/usr/bin/make -f
export JAVA_HOME = /usr/lib/jvm/default-java
%: %:
dh $@ --buildsystem=maven dh $@
get-orig-source:
uscan --download-current-version --force-download --no-symlink
...@@ -19,14 +19,16 @@ ...@@ -19,14 +19,16 @@
xmlns="http://maven.apache.org/POM/4.0.0" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId> <artifactId>commons-parent</artifactId>
<version>47</version> <version>48</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
<version>2.6.0</version> <version>2.6.2</version>
<name>Apache Commons Pool</name> <name>Apache Commons Pool</name>
<inceptionYear>2001</inceptionYear> <inceptionYear>2001</inceptionYear>
...@@ -127,13 +129,14 @@ ...@@ -127,13 +129,14 @@
<dependency> <dependency>
<groupId>cglib</groupId> <groupId>cglib</groupId>
<artifactId>cglib</artifactId> <artifactId>cglib</artifactId>
<version>3.2.6</version> <version>3.2.10</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.ow2.asm</groupId> <groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId> <artifactId>asm-util</artifactId>
<version>6.2</version> <!-- Version 7.1 depends on Java 8 -->
<version>7.0</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
...@@ -155,8 +158,9 @@ ...@@ -155,8 +158,9 @@
<maven.compiler.target>1.7</maven.compiler.target> <maven.compiler.target>1.7</maven.compiler.target>
<commons.componentid>pool</commons.componentid> <commons.componentid>pool</commons.componentid>
<commons.module.name>org.apache.commons.pool2</commons.module.name> <commons.module.name>org.apache.commons.pool2</commons.module.name>
<commons.rc.version>RC1</commons.rc.version>
<!-- Java 7 --> <!-- Java 7 -->
<commons.release.version>2.6.0</commons.release.version> <commons.release.version>2.6.2</commons.release.version>
<commons.release.desc>(Java 7)</commons.release.desc> <commons.release.desc>(Java 7)</commons.release.desc>
<!-- Java 6 --> <!-- Java 6 -->
<commons.release.2.version>2.4.3</commons.release.2.version> <commons.release.2.version>2.4.3</commons.release.2.version>
...@@ -168,23 +172,33 @@ ...@@ -168,23 +172,33 @@
<commons.release.3.name>commons-pool-${commons.release.3.version}</commons.release.3.name> <commons.release.3.name>commons-pool-${commons.release.3.version}</commons.release.3.name>
<commons.jira.id>POOL</commons.jira.id> <commons.jira.id>POOL</commons.jira.id>
<commons.jira.pid>12310488</commons.jira.pid> <commons.jira.pid>12310488</commons.jira.pid>
<commons.site.path>pool</commons.site.path>
<commons.scmPubUrl>https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-${commons.componentid}</commons.scmPubUrl>
<commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory> <commons.scmPubCheckoutDirectory>site-content</commons.scmPubCheckoutDirectory>
<commons.osgi.import>net.sf.cglib.proxy;resolution:=optional,*</commons.osgi.import> <commons.osgi.import>net.sf.cglib.proxy;resolution:=optional,*</commons.osgi.import>
<commons.animal-sniffer.version>1.16</commons.animal-sniffer.version> <commons.animal-sniffer.version>1.16</commons.animal-sniffer.version>
<!-- Commons Release Plugin --> <!-- Commons Release Plugin -->
<commons.bc.version>2.5.0</commons.bc.version> <commons.bc.version>2.6.1</commons.bc.version>
<commons.release.isDistModule>true</commons.release.isDistModule> <commons.release.isDistModule>true</commons.release.isDistModule>
<commons.releaseManagerName>Gary Gregory</commons.releaseManagerName> <commons.releaseManagerName>Gary Gregory</commons.releaseManagerName>
<commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey> <commons.releaseManagerKey>86fdc7e2a11262cb</commons.releaseManagerKey>
<commons.japicmp.version>0.13.1</commons.japicmp.version>
<japicmp.skip>false</japicmp.skip>
</properties> </properties>
<build> <build>
<defaultGoal>clean verify apache-rat:check clirr:check javadoc:javadoc</defaultGoal> <defaultGoal>clean verify apache-rat:check clirr:check javadoc:javadoc</defaultGoal>
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<configuration>
<!-- correct config for GIT projects using staging -->
<pushChanges>false</pushChanges>
<localCheckout>true</localCheckout>
</configuration>
</plugin>
<plugin> <plugin>
<!-- Fixes org.apache.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19 --> <!-- Fixes org.apache.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19 -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
...@@ -194,7 +208,7 @@ ...@@ -194,7 +208,7 @@
<dependency> <dependency>
<groupId>org.apache.bcel</groupId> <groupId>org.apache.bcel</groupId>
<artifactId>bcel</artifactId> <artifactId>bcel</artifactId>
<version>6.2</version> <version>6.3.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>
...@@ -276,7 +290,7 @@ ...@@ -276,7 +290,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId> <artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version> <version>3.0.0</version>
<configuration> <configuration>
<configLocation>${basedir}/checkstyle.xml</configLocation> <configLocation>${basedir}/checkstyle.xml</configLocation>
<enableRulesSummary>false</enableRulesSummary> <enableRulesSummary>false</enableRulesSummary>
...@@ -326,17 +340,14 @@ ...@@ -326,17 +340,14 @@
<reportSets> <reportSets>
<reportSet> <reportSet>
<reports> <reports>
<!-- This is the only way I could find to skip generating this report --> <report>cmp-report</report>
<!-- Version 0.11.1 throws an exception because it cannot find a Geronimo class -->
<!-- Version 0.12.0 throws an NullPointerException because it seems Maven did not inject the report Mojo with any values-->
<!-- <report>cmp-report</report> -->
</reports> </reports>
</reportSet> </reportSet>
</reportSets> </reportSets>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-pmd-plugin</artifactId> <artifactId>maven-pmd-plugin</artifactId>
<version>3.10.0</version> <version>3.11.0</version>
<configuration> <configuration>
<targetJdk>${maven.compiler.target}</targetJdk> <targetJdk>${maven.compiler.target}</targetJdk>
</configuration> </configuration>
...@@ -353,50 +364,6 @@ ...@@ -353,50 +364,6 @@
</reporting> </reporting>
<profiles> <profiles>
<profile>
<id>setup-checkout</id>
<activation>
<file>
<missing>site-content</missing>
</file>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>prepare-checkout</id>
<phase>pre-site</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<exec executable="svn">
<arg line="checkout --depth immediates ${commons.scmPubUrl} ${commons.scmPubCheckoutDirectory}" />
</exec>
<exec executable="svn">
<arg line="update --set-depth exclude ${commons.scmPubCheckoutDirectory}/javadocs" />
</exec>
<pathconvert pathsep=" " property="dirs">
<dirset dir="${commons.scmPubCheckoutDirectory}" includes="*" />
</pathconvert>
<exec executable="svn">
<arg line="update --set-depth infinity ${dirs}" />
</exec>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile> <profile>
<id>java9</id> <id>java9</id>
<activation> <activation>
...@@ -407,6 +374,18 @@ ...@@ -407,6 +374,18 @@
<coveralls.skip>true</coveralls.skip> <coveralls.skip>true</coveralls.skip>
</properties> </properties>
</profile> </profile>
<profile>
<id>java11+</id>
<activation>
<jdk>[11,)</jdk>
</activation>
<properties>
<!-- Workaround for https://bugs.openjdk.java.net/browse/JDK-8212233
which causes javadoc to fail with "javadoc: error - The code being documented uses modules
but the packages defined in https://docs.oracle.com/javase/8/docs/api/ are in the unnamed module." -->
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>
</profile>
</profiles> </profiles>
</project> </project>
...@@ -43,7 +43,50 @@ The <action> type attribute can be add,update,fix,remove. ...@@ -43,7 +43,50 @@ The <action> type attribute can be add,update,fix,remove.
<title>Apache Commons Pool Changes</title> <title>Apache Commons Pool Changes</title>
</properties> </properties>
<body> <body>
<release version="2.6.0" date="2018-MM-DD" description="This is a maintenance release."> <release version="2.6.2" date="2019-03-05" description="This is a maintenance release.">
<action dev="ggregory" issue="POOL-362" type="fix">
Always null out org.apache.commons.pool2.impl.BaseGenericObjectPool.evictionIterator to match org.apache.commons.pool2.impl.BaseGenericObjectPool.evictor.
</action>
<action dev="ggregory" issue="POOL-363" type="fix" due-to="Josh Landin">
Evictor Thread prevents Spring Context shutdown in standalone app.
</action>
<action dev="ggregory" issue="POOL-348" type="fix" due-to="Josh Landin">
The commons-pool-evictor-thread should run as a Deamon.
</action>
</release>
<release version="2.6.1" date="2019-02-08" description="This is a maintenance release.">
<action dev="struberg" issue="POOL-340" type="fix" due-to="Pavel Kolesov">
Correct validateObject with concurrent borrowObject
</action>
<action dev="struberg" issue="POOL-356" type="fix">
Fix deadlock on massive concurrent requests
</action>
<action dev="ggregory" issue="POOL-345" type="update">
Update optional library cglib from 3.2.6 to 3.2.9.
</action>
<action dev="ggregory" issue="POOL-346" type="update" due-to="Michael Chen">
Move common configuration setter to BaseGenericObjectPool #9.
</action>
<action dev="ggregory" issue="POOL-347" type="fix" due-to="Shunsuke Nakamura">
Method borrowObject waits for maxWaitMillis over in pool full.
</action>
<action dev="ggregory" issue="POOL-349" type="update">
Update optional library asm-util from 6.2 to 7.0.
</action>
<action dev="ggregory" issue="POOL-359" type="fix" due-to="Michael Wintermeyer, Gary Gregory">
NullPointerException closing multiple GenericObjectPools.
</action>
<action dev="ggregory" issue="POOL-360" type="update">
Update optional library cglib from 3.2.9 to 3.2.10.
</action>
<action dev="ggregory" issue="POOL-326" type="fix" due-to="Chris Allison, Phil Steitz">
Threading issue, NullPointerException and IllegalStateException in GenericKeyedObjectPool.
</action>
<action dev="ggregory" issue="POOL-352" type="fix" due-to="Volker Kleinschmidt, Gary Gregory">
CallStackUtils mishandles security manager check (partial fix.)
</action>
</release>
<release version="2.6.0" date="2018-07-06" description="This is a maintenance release.">
<action dev="ggregory" issue="POOL-336" type="update" due-to="Wolfgang Glas"> <action dev="ggregory" issue="POOL-336" type="update" due-to="Wolfgang Glas">
GenericObjectPool's borrowObject lock if create() fails with Error. GenericObjectPool's borrowObject lock if create() fails with Error.
</action> </action>
......
...@@ -121,4 +121,7 @@ patches, or suggestions for improvement, see the Apache ${project.name} website: ...@@ -121,4 +121,7 @@ patches, or suggestions for improvement, see the Apache ${project.name} website:
${project.url} ${project.url}
Download page: ${project.url}download_pool.cgi
...@@ -36,6 +36,13 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; ...@@ -36,6 +36,13 @@ import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
*/ */
public final class PoolUtils { public final class PoolUtils {
private static final String MSG_FACTOR_NEGATIVE = "factor must be positive.";
private static final String MSG_MIN_IDLE = "minIdle must be non-negative.";
private static final String MSG_NULL_KEY = "key must not be null.";
private static final String MSG_NULL_KEYED_POOL = "keyedPool must not be null.";
private static final String MSG_NULL_KEYS = "keys must not be null.";
private static final String MSG_NULL_POOL = "pool must not be null.";
/** /**
* Timer used to periodically check pools idle object count. Because a * Timer used to periodically check pools idle object count. Because a
* {@link Timer} creates a {@link Thread}, an IODH is used. * {@link Timer} creates a {@link Thread}, an IODH is used.
...@@ -101,10 +108,10 @@ public final class PoolUtils { ...@@ -101,10 +108,10 @@ public final class PoolUtils {
final int minIdle, final long period) final int minIdle, final long period)
throws IllegalArgumentException { throws IllegalArgumentException {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("keyedPool must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
} }
if (minIdle < 0) { if (minIdle < 0) {
throw new IllegalArgumentException("minIdle must be non-negative."); throw new IllegalArgumentException(MSG_MIN_IDLE);
} }
final TimerTask task = new ObjectPoolMinIdleTimerTask<>(pool, minIdle); final TimerTask task = new ObjectPoolMinIdleTimerTask<>(pool, minIdle);
getMinIdleTimer().schedule(task, 0L, period); getMinIdleTimer().schedule(task, 0L, period);
...@@ -142,13 +149,13 @@ public final class PoolUtils { ...@@ -142,13 +149,13 @@ public final class PoolUtils {
final int minIdle, final long period) final int minIdle, final long period)
throws IllegalArgumentException { throws IllegalArgumentException {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException("keyedPool must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
} }
if (key == null) { if (key == null) {
throw new IllegalArgumentException("key must not be null."); throw new IllegalArgumentException(MSG_NULL_KEY);
} }
if (minIdle < 0) { if (minIdle < 0) {
throw new IllegalArgumentException("minIdle must be non-negative."); throw new IllegalArgumentException(MSG_MIN_IDLE);
} }
final TimerTask task = new KeyedObjectPoolMinIdleTimerTask<>( final TimerTask task = new KeyedObjectPoolMinIdleTimerTask<>(
keyedPool, key, minIdle); keyedPool, key, minIdle);
...@@ -188,7 +195,7 @@ public final class PoolUtils { ...@@ -188,7 +195,7 @@ public final class PoolUtils {
final int minIdle, final long period) final int minIdle, final long period)
throws IllegalArgumentException { throws IllegalArgumentException {
if (keys == null) { if (keys == null) {
throw new IllegalArgumentException("keys must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYS);
} }
final Map<K, TimerTask> tasks = new HashMap<>(keys.size()); final Map<K, TimerTask> tasks = new HashMap<>(keys.size());
final Iterator<K> iter = keys.iterator(); final Iterator<K> iter = keys.iterator();
...@@ -217,7 +224,7 @@ public final class PoolUtils { ...@@ -217,7 +224,7 @@ public final class PoolUtils {
public static <T> void prefill(final ObjectPool<T> pool, final int count) public static <T> void prefill(final ObjectPool<T> pool, final int count)
throws Exception, IllegalArgumentException { throws Exception, IllegalArgumentException {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("pool must not be null."); throw new IllegalArgumentException(MSG_NULL_POOL);
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
pool.addObject(); pool.addObject();
...@@ -246,10 +253,10 @@ public final class PoolUtils { ...@@ -246,10 +253,10 @@ public final class PoolUtils {
final K key, final int count) throws Exception, final K key, final int count) throws Exception,
IllegalArgumentException { IllegalArgumentException {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException("keyedPool must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
} }
if (key == null) { if (key == null) {
throw new IllegalArgumentException("key must not be null."); throw new IllegalArgumentException(MSG_NULL_KEY);
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
keyedPool.addObject(key); keyedPool.addObject(key);
...@@ -281,7 +288,7 @@ public final class PoolUtils { ...@@ -281,7 +288,7 @@ public final class PoolUtils {
final Collection<K> keys, final int count) throws Exception, final Collection<K> keys, final int count) throws Exception,
IllegalArgumentException { IllegalArgumentException {
if (keys == null) { if (keys == null) {
throw new IllegalArgumentException("keys must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYS);
} }
final Iterator<K> iter = keys.iterator(); final Iterator<K> iter = keys.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
...@@ -308,7 +315,7 @@ public final class PoolUtils { ...@@ -308,7 +315,7 @@ public final class PoolUtils {
*/ */
public static <T> ObjectPool<T> synchronizedPool(final ObjectPool<T> pool) { public static <T> ObjectPool<T> synchronizedPool(final ObjectPool<T> pool) {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("pool must not be null."); throw new IllegalArgumentException(MSG_NULL_POOL);
} }
/* /*
* assert !(pool instanceof GenericObjectPool) : * assert !(pool instanceof GenericObjectPool) :
...@@ -436,10 +443,10 @@ public final class PoolUtils { ...@@ -436,10 +443,10 @@ public final class PoolUtils {
public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool, public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool,
final float factor) { final float factor) {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("pool must not be null."); throw new IllegalArgumentException(MSG_NULL_POOL);
} }
if (factor <= 0f) { if (factor <= 0f) {
throw new IllegalArgumentException("factor must be positive."); throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
} }
return new ErodingObjectPool<>(pool, factor); return new ErodingObjectPool<>(pool, factor);
} }
...@@ -538,10 +545,10 @@ public final class PoolUtils { ...@@ -538,10 +545,10 @@ public final class PoolUtils {
final KeyedObjectPool<K, V> keyedPool, final float factor, final KeyedObjectPool<K, V> keyedPool, final float factor,
final boolean perKey) { final boolean perKey) {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException("keyedPool must not be null."); throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
} }
if (factor <= 0f) { if (factor <= 0f) {
throw new IllegalArgumentException("factor must be positive."); throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
} }
if (perKey) { if (perKey) {
return new ErodingPerKeyKeyedObjectPool<>(keyedPool, factor); return new ErodingPerKeyKeyedObjectPool<>(keyedPool, factor);
...@@ -587,7 +594,7 @@ public final class PoolUtils { ...@@ -587,7 +594,7 @@ public final class PoolUtils {
ObjectPoolMinIdleTimerTask(final ObjectPool<T> pool, final int minIdle) ObjectPoolMinIdleTimerTask(final ObjectPool<T> pool, final int minIdle)
throws IllegalArgumentException { throws IllegalArgumentException {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("pool must not be null."); throw new IllegalArgumentException(MSG_NULL_POOL);
} }
this.pool = pool; this.pool = pool;
this.minIdle = minIdle; this.minIdle = minIdle;
...@@ -665,7 +672,7 @@ public final class PoolUtils { ...@@ -665,7 +672,7 @@ public final class PoolUtils {
final K key, final int minIdle) throws IllegalArgumentException { final K key, final int minIdle) throws IllegalArgumentException {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"keyedPool must not be null."); MSG_NULL_KEYED_POOL);
} }
this.keyedPool = keyedPool; this.keyedPool = keyedPool;
this.key = key; this.key = key;
...@@ -747,7 +754,7 @@ public final class PoolUtils { ...@@ -747,7 +754,7 @@ public final class PoolUtils {
SynchronizedObjectPool(final ObjectPool<T> pool) SynchronizedObjectPool(final ObjectPool<T> pool)
throws IllegalArgumentException { throws IllegalArgumentException {
if (pool == null) { if (pool == null) {
throw new IllegalArgumentException("pool must not be null."); throw new IllegalArgumentException(MSG_NULL_POOL);
} }
this.pool = pool; this.pool = pool;
} }
...@@ -924,7 +931,7 @@ public final class PoolUtils { ...@@ -924,7 +931,7 @@ public final class PoolUtils {
throws IllegalArgumentException { throws IllegalArgumentException {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"keyedPool must not be null."); MSG_NULL_KEYED_POOL);
} }
this.keyedPool = keyedPool; this.keyedPool = keyedPool;
} }
...@@ -1605,7 +1612,7 @@ public final class PoolUtils { ...@@ -1605,7 +1612,7 @@ public final class PoolUtils {
final ErodingFactor erodingFactor) { final ErodingFactor erodingFactor) {
if (keyedPool == null) { if (keyedPool == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"keyedPool must not be null."); MSG_NULL_KEYED_POOL);
} }
this.keyedPool = keyedPool; this.keyedPool = keyedPool;
this.erodingFactor = erodingFactor; this.erodingFactor = erodingFactor;
......
...@@ -217,6 +217,29 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject { ...@@ -217,6 +217,29 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
this.blockWhenExhausted = blockWhenExhausted; this.blockWhenExhausted = blockWhenExhausted;
} }
protected void setConfig(final BaseObjectPoolConfig<T> conf) {
setLifo(conf.getLifo());
setMaxWaitMillis(conf.getMaxWaitMillis());
setBlockWhenExhausted(conf.getBlockWhenExhausted());
setTestOnCreate(conf.getTestOnCreate());
setTestOnBorrow(conf.getTestOnBorrow());
setTestOnReturn(conf.getTestOnReturn());
setTestWhileIdle(conf.getTestWhileIdle());
setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
final EvictionPolicy<T> policy = conf.getEvictionPolicy();
if (policy == null) {
// Use the class name (pre-2.6.0 compatible)
setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
} else {
// Otherwise, use the class (2.6.0 feature)
setEvictionPolicy(policy);
}
setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
}
/** /**
* Returns the maximum amount of time (in milliseconds) the * Returns the maximum amount of time (in milliseconds) the
* <code>borrowObject()</code> method should block before throwing an * <code>borrowObject()</code> method should block before throwing an
...@@ -749,11 +772,9 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject { ...@@ -749,11 +772,9 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
*/ */
final void startEvictor(final long delay) { final void startEvictor(final long delay) {
synchronized (evictionLock) { synchronized (evictionLock) {
if (null != evictor) {
EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS); EvictionTimer.cancel(evictor, evictorShutdownTimeoutMillis, TimeUnit.MILLISECONDS);
evictor = null; evictor = null;
evictionIterator = null; evictionIterator = null;
}
if (delay > 0) { if (delay > 0) {
evictor = new Evictor(); evictor = new Evictor();
EvictionTimer.schedule(evictor, delay, delay); EvictionTimer.schedule(evictor, delay, delay);
...@@ -761,6 +782,12 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject { ...@@ -761,6 +782,12 @@ public abstract class BaseGenericObjectPool<T> extends BaseObject {
} }
} }
/**
* Stops the evictor.
*/
void stopEvitor() {
startEvictor(-1L);
}
/** /**
* Tries to ensure that the configured minimum number of idle instances are * Tries to ensure that the configured minimum number of idle instances are
* available in the pool. * available in the pool.
......
...@@ -25,12 +25,6 @@ import java.security.AccessControlException; ...@@ -25,12 +25,6 @@ import java.security.AccessControlException;
*/ */
public final class CallStackUtils { public final class CallStackUtils {
private static final boolean CAN_CREATE_SECURITY_MANAGER;
static {
CAN_CREATE_SECURITY_MANAGER = canCreateSecurityManager();
}
/** /**
* @return {@code true} if it is able to create a security manager in the current environment, {@code false} * @return {@code true} if it is able to create a security manager in the current environment, {@code false}
* otherwise. * otherwise.
...@@ -76,7 +70,7 @@ public final class CallStackUtils { ...@@ -76,7 +70,7 @@ public final class CallStackUtils {
public static CallStack newCallStack(final String messageFormat, public static CallStack newCallStack(final String messageFormat,
final boolean useTimestamp, final boolean useTimestamp,
final boolean requireFullStackTrace) { final boolean requireFullStackTrace) {
return CAN_CREATE_SECURITY_MANAGER && !requireFullStackTrace return canCreateSecurityManager() && !requireFullStackTrace
? new SecurityManagerCallStack(messageFormat, useTimestamp) ? new SecurityManagerCallStack(messageFormat, useTimestamp)
: new ThrowableCallStack(messageFormat, useTimestamp); : new ThrowableCallStack(messageFormat, useTimestamp);
} }
......
...@@ -25,18 +25,20 @@ import java.util.concurrent.ThreadFactory; ...@@ -25,18 +25,20 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Provides a shared idle object eviction timer for all pools. This class is * Provides a shared idle object eviction timer for all pools.
* currently implemented using {@link ScheduledThreadPoolExecutor}. This
* implementation may change in any future release. This class keeps track of
* how many pools are using it. If no pools are using the timer, it is cancelled.
* This prevents a thread being left running which, in application server
* environments, can lead to memory leads and/or prevent applications from
* shutting down or reloading cleanly.
* <p> * <p>
* This class has package scope to prevent its inclusion in the pool public API. * This class is currently implemented using {@link ScheduledThreadPoolExecutor}. This implementation may change in any
* The class declaration below should *not* be changed to public. * future release. This class keeps track of how many pools are using it. If no pools are using the timer, it is
* cancelled. This prevents a thread being left running which, in application server environments, can lead to memory
* leads and/or prevent applications from shutting down or reloading cleanly.
* </p>
* <p>
* This class has package scope to prevent its inclusion in the pool public API. The class declaration below should
* *not* be changed to public.
* </p>
* <p> * <p>
* This class is intended to be thread-safe. * This class is intended to be thread-safe.
* </p>
* *
* @since 2.0 * @since 2.0
*/ */
...@@ -67,6 +69,7 @@ class EvictionTimer { ...@@ -67,6 +69,7 @@ class EvictionTimer {
* call to this method *must* call {@link #cancel(TimerTask)} to cancel the * call to this method *must* call {@link #cancel(TimerTask)} to cancel the
* task to prevent memory and/or thread leaks in application server * task to prevent memory and/or thread leaks in application server
* environments. * environments.
*
* @param task Task to be scheduled * @param task Task to be scheduled
* @param delay Delay in milliseconds before task is executed * @param delay Delay in milliseconds before task is executed
* @param period Time in milliseconds between executions * @param period Time in milliseconds between executions
...@@ -85,16 +88,18 @@ class EvictionTimer { ...@@ -85,16 +88,18 @@ class EvictionTimer {
/** /**
* Remove the specified eviction task from the timer. * Remove the specified eviction task from the timer.
* *
* @param task Task to be cancelled * @param evictor Task to be cancelled
* @param timeout If the associated executor is no longer required, how * @param timeout If the associated executor is no longer required, how
* long should this thread wait for the executor to * long should this thread wait for the executor to
* terminate? * terminate?
* @param unit The units for the specified timeout * @param unit The units for the specified timeout
*/ */
static synchronized void cancel( static synchronized void cancel(
final BaseGenericObjectPool<?>.Evictor task, final long timeout, final TimeUnit unit) { final BaseGenericObjectPool<?>.Evictor evictor, final long timeout, final TimeUnit unit) {
task.cancel(); if (evictor != null) {
if (executor.getQueue().size() == 0) { evictor.cancel();
}
if (executor != null && executor.getQueue().isEmpty()) {
executor.shutdown(); executor.shutdown();
try { try {
executor.awaitTermination(timeout, unit); executor.awaitTermination(timeout, unit);
...@@ -108,23 +113,23 @@ class EvictionTimer { ...@@ -108,23 +113,23 @@ class EvictionTimer {
} }
/** /**
* Thread factory that creates a thread, with the context classloader from this class. * Thread factory that creates a daemon thread, with the context class loader from this class.
*/ */
private static class EvictorThreadFactory implements ThreadFactory { private static class EvictorThreadFactory implements ThreadFactory {
@Override @Override
public Thread newThread(final Runnable r) { public Thread newThread(final Runnable runnable) {
final Thread t = new Thread(null, r, "commons-pool-evictor-thread"); final Thread thread = new Thread(null, runnable, "commons-pool-evictor-thread");
thread.setDaemon(true); // POOL-363 - Required for applications using Runtime.addShutdownHook(). --joshlandin 03.27.2019
AccessController.doPrivileged(new PrivilegedAction<Void>() { AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override @Override
public Void run() { public Void run() {
t.setContextClassLoader(EvictorThreadFactory.class.getClassLoader()); thread.setContextClassLoader(EvictorThreadFactory.class.getClassLoader());
return null; return null;
} }
}); });
return t; return thread;
} }
} }
} }
...@@ -237,30 +237,11 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T> ...@@ -237,30 +237,11 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
* @see GenericKeyedObjectPoolConfig * @see GenericKeyedObjectPoolConfig
*/ */
public void setConfig(final GenericKeyedObjectPoolConfig<T> conf) { public void setConfig(final GenericKeyedObjectPoolConfig<T> conf) {
setLifo(conf.getLifo()); super.setConfig(conf);
setMaxIdlePerKey(conf.getMaxIdlePerKey()); setMaxIdlePerKey(conf.getMaxIdlePerKey());
setMaxTotalPerKey(conf.getMaxTotalPerKey()); setMaxTotalPerKey(conf.getMaxTotalPerKey());
setMaxTotal(conf.getMaxTotal()); setMaxTotal(conf.getMaxTotal());
setMinIdlePerKey(conf.getMinIdlePerKey()); setMinIdlePerKey(conf.getMinIdlePerKey());
setMaxWaitMillis(conf.getMaxWaitMillis());
setBlockWhenExhausted(conf.getBlockWhenExhausted());
setTestOnCreate(conf.getTestOnCreate());
setTestOnBorrow(conf.getTestOnBorrow());
setTestOnReturn(conf.getTestOnReturn());
setTestWhileIdle(conf.getTestWhileIdle());
setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
final EvictionPolicy<T> policy = conf.getEvictionPolicy();
if (policy == null) {
// Use the class name (pre-2.6.0 compatible)
setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
} else {
// Otherwise, use the class (2.6.0 feature)
setEvictionPolicy(policy);
}
setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
} }
/** /**
...@@ -707,7 +688,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T> ...@@ -707,7 +688,7 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
// Stop the evictor before the pool is closed since evict() calls // Stop the evictor before the pool is closed since evict() calls
// assertOpen() // assertOpen()
startEvictor(-1L); stopEvitor();
closed = true; closed = true;
// This clear removes any idle objects // This clear removes any idle objects
...@@ -1163,26 +1144,28 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T> ...@@ -1163,26 +1144,28 @@ public class GenericKeyedObjectPool<K, T> extends BaseGenericObjectPool<T>
* @param k The key to de-register * @param k The key to de-register
*/ */
private void deregister(final K k) { private void deregister(final K k) {
Lock lock = keyLock.readLock();
ObjectDeque<T> objectDeque; ObjectDeque<T> objectDeque;
try {
lock.lock();
objectDeque = poolMap.get(k); objectDeque = poolMap.get(k);
final long numInterested = objectDeque.getNumInterested().decrementAndGet(); final long numInterested = objectDeque.getNumInterested().decrementAndGet();
if (numInterested == 0 && objectDeque.getCreateCount().get() == 0) { if (numInterested == 0 && objectDeque.getCreateCount().get() == 0) {
// Potential to remove key // Potential to remove key
final Lock writeLock = keyLock.writeLock(); // Upgrade to write lock
writeLock.lock(); lock.unlock();
try { lock = keyLock.writeLock();
if (objectDeque.getCreateCount().get() == 0 && lock.lock();
objectDeque.getNumInterested().get() == 0) { if (objectDeque.getCreateCount().get() == 0 && objectDeque.getNumInterested().get() == 0) {
// NOTE: Keys must always be removed from both poolMap and // NOTE: Keys must always be removed from both poolMap and
// poolKeyList at the same time while protected by // poolKeyList at the same time while protected by
// keyLock.writeLock() // keyLock.writeLock()
poolMap.remove(k); poolMap.remove(k);
poolKeyList.remove(k); poolKeyList.remove(k);
} }
} finally {
writeLock.unlock();
} }
} finally {
lock.unlock();
} }
} }
......
...@@ -182,6 +182,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -182,6 +182,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* <p> * <p>
* If the configured value of minIdle is greater than the configured value * If the configured value of minIdle is greater than the configured value
* for maxIdle then the value of maxIdle will be used instead. * for maxIdle then the value of maxIdle will be used instead.
* </p>
* *
* @param minIdle * @param minIdle
* The minimum number of objects. * The minimum number of objects.
...@@ -203,6 +204,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -203,6 +204,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* <p> * <p>
* If the configured value of minIdle is greater than the configured value * If the configured value of minIdle is greater than the configured value
* for maxIdle then the value of maxIdle will be used instead. * for maxIdle then the value of maxIdle will be used instead.
* </p>
* *
* @return The minimum number of objects. * @return The minimum number of objects.
* *
...@@ -297,29 +299,10 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -297,29 +299,10 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* @see GenericObjectPoolConfig * @see GenericObjectPoolConfig
*/ */
public void setConfig(final GenericObjectPoolConfig<T> conf) { public void setConfig(final GenericObjectPoolConfig<T> conf) {
setLifo(conf.getLifo()); super.setConfig(conf);
setMaxIdle(conf.getMaxIdle()); setMaxIdle(conf.getMaxIdle());
setMinIdle(conf.getMinIdle()); setMinIdle(conf.getMinIdle());
setMaxTotal(conf.getMaxTotal()); setMaxTotal(conf.getMaxTotal());
setMaxWaitMillis(conf.getMaxWaitMillis());
setBlockWhenExhausted(conf.getBlockWhenExhausted());
setTestOnCreate(conf.getTestOnCreate());
setTestOnBorrow(conf.getTestOnBorrow());
setTestOnReturn(conf.getTestOnReturn());
setTestWhileIdle(conf.getTestWhileIdle());
setNumTestsPerEvictionRun(conf.getNumTestsPerEvictionRun());
setMinEvictableIdleTimeMillis(conf.getMinEvictableIdleTimeMillis());
setTimeBetweenEvictionRunsMillis(conf.getTimeBetweenEvictionRunsMillis());
setSoftMinEvictableIdleTimeMillis(conf.getSoftMinEvictableIdleTimeMillis());
final EvictionPolicy<T> policy = conf.getEvictionPolicy();
if (policy == null) {
// Use the class name (pre-2.6.0 compatible)
setEvictionPolicyClassName(conf.getEvictionPolicyClassName());
} else {
// Otherwise, use the class (2.6.0 feature)
setEvictionPolicy(policy);
}
setEvictorShutdownTimeoutMillis(conf.getEvictorShutdownTimeoutMillis());
} }
/** /**
...@@ -359,6 +342,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -359,6 +342,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* borrowObject}({@link #getMaxWaitMillis()})</code>. * borrowObject}({@link #getMaxWaitMillis()})</code>.
* <p> * <p>
* {@inheritDoc} * {@inheritDoc}
* </p>
*/ */
@Override @Override
public T borrowObject() throws Exception { public T borrowObject() throws Exception {
...@@ -376,6 +360,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -376,6 +360,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* instance is destroyed and the next available instance is examined. This * instance is destroyed and the next available instance is examined. This
* continues until either a valid instance is returned or there are no more * continues until either a valid instance is returned or there are no more
* idle instances available. * idle instances available.
* </p>
* <p> * <p>
* If there are no idle instances available in the pool, behavior depends on * If there are no idle instances available in the pool, behavior depends on
* the {@link #getMaxTotal() maxTotal}, (if applicable) * the {@link #getMaxTotal() maxTotal}, (if applicable)
...@@ -385,6 +370,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -385,6 +370,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* instance is created, activated and (if applicable) validated and returned * instance is created, activated and (if applicable) validated and returned
* to the caller. If validation fails, a <code>NoSuchElementException</code> * to the caller. If validation fails, a <code>NoSuchElementException</code>
* is thrown. * is thrown.
* </p>
* <p> * <p>
* If the pool is exhausted (no available idle instances and no capacity to * If the pool is exhausted (no available idle instances and no capacity to
* create new ones), this method will either block (if * create new ones), this method will either block (if
...@@ -394,11 +380,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -394,11 +380,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* method will block when {@link #getBlockWhenExhausted()} is true is * method will block when {@link #getBlockWhenExhausted()} is true is
* determined by the value passed in to the <code>borrowMaxWaitMillis</code> * determined by the value passed in to the <code>borrowMaxWaitMillis</code>
* parameter. * parameter.
* </p>
* <p> * <p>
* When the pool is exhausted, multiple calling threads may be * When the pool is exhausted, multiple calling threads may be
* simultaneously blocked waiting for instances to become available. A * simultaneously blocked waiting for instances to become available. A
* "fairness" algorithm has been implemented to ensure that threads receive * "fairness" algorithm has been implemented to ensure that threads receive
* available instances in request arrival order. * available instances in request arrival order.
* </p>
* *
* @param borrowMaxWaitMillis The time to wait in milliseconds for an object * @param borrowMaxWaitMillis The time to wait in milliseconds for an object
* to become available * to become available
...@@ -516,13 +504,16 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -516,13 +504,16 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* If {@link #getMaxIdle() maxIdle} is set to a positive value and the * If {@link #getMaxIdle() maxIdle} is set to a positive value and the
* number of idle instances has reached this value, the returning instance * number of idle instances has reached this value, the returning instance
* is destroyed. * is destroyed.
* </p>
* <p> * <p>
* If {@link #getTestOnReturn() testOnReturn} == true, the returning * If {@link #getTestOnReturn() testOnReturn} == true, the returning
* instance is validated before being returned to the idle instance pool. In * instance is validated before being returned to the idle instance pool. In
* this case, if validation fails, the instance is destroyed. * this case, if validation fails, the instance is destroyed.
* </p>
* <p> * <p>
* Exceptions encountered destroying objects for any reason are swallowed * Exceptions encountered destroying objects for any reason are swallowed
* but notified via a {@link SwallowedExceptionListener}. * but notified via a {@link SwallowedExceptionListener}.
* </p>
*/ */
@Override @Override
public void returnObject(final T obj) { public void returnObject(final T obj) {
...@@ -606,6 +597,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -606,6 +597,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* <p> * <p>
* Activation of this method decrements the active count and attempts to * Activation of this method decrements the active count and attempts to
* destroy the instance. * destroy the instance.
* </p>
* *
* @throws Exception if an exception occurs destroying the * @throws Exception if an exception occurs destroying the
* object * object
...@@ -636,6 +628,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -636,6 +628,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* idle instance. * idle instance.
* <p> * <p>
* Implementation notes: * Implementation notes:
* </p>
* <ul> * <ul>
* <li>This method does not destroy or effect in any way instances that are * <li>This method does not destroy or effect in any way instances that are
* checked out of the pool when it is invoked.</li> * checked out of the pool when it is invoked.</li>
...@@ -677,6 +670,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -677,6 +670,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* objects destroyed on return. * objects destroyed on return.
* <p> * <p>
* Destroys idle instances in the pool by invoking {@link #clear()}. * Destroys idle instances in the pool by invoking {@link #clear()}.
* </p>
*/ */
@Override @Override
public void close() { public void close() {
...@@ -691,7 +685,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -691,7 +685,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
// Stop the evictor before the pool is closed since evict() calls // Stop the evictor before the pool is closed since evict() calls
// assertOpen() // assertOpen()
startEvictor(-1L); stopEvitor();
closed = true; closed = true;
// This clear removes any idle objects // This clear removes any idle objects
...@@ -709,6 +703,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -709,6 +703,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* <p> * <p>
* Successive activations of this method examine objects in sequence, * Successive activations of this method examine objects in sequence,
* cycling through objects in oldest-to-youngest order. * cycling through objects in oldest-to-youngest order.
* </p>
*/ */
@Override @Override
public void evict() throws Exception { public void evict() throws Exception {
...@@ -829,6 +824,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -829,6 +824,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* <p> * <p>
* If there are {@link #getMaxTotal()} objects already in circulation * If there are {@link #getMaxTotal()} objects already in circulation
* or in process of being created, this method returns null. * or in process of being created, this method returns null.
* </p>
* *
* @return The new wrapped pooled object * @return The new wrapped pooled object
* *
...@@ -841,6 +837,9 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -841,6 +837,9 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
localMaxTotal = Integer.MAX_VALUE; localMaxTotal = Integer.MAX_VALUE;
} }
final long localStartTimeMillis = System.currentTimeMillis();
final long localMaxWaitTimeMillis = Math.max(getMaxWaitMillis(), 0);
// Flag that indicates if create should: // Flag that indicates if create should:
// - TRUE: call the factory to create an object // - TRUE: call the factory to create an object
// - FALSE: return null // - FALSE: return null
...@@ -864,7 +863,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -864,7 +863,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
// bring the pool to capacity. Those calls might also // bring the pool to capacity. Those calls might also
// fail so wait until they complete and then re-test if // fail so wait until they complete and then re-test if
// the pool is at capacity or not. // the pool is at capacity or not.
makeObjectCountLock.wait(); makeObjectCountLock.wait(localMaxWaitTimeMillis);
} }
} else { } else {
// The pool is not at capacity. Create a new object. // The pool is not at capacity. Create a new object.
...@@ -872,6 +871,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -872,6 +871,13 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
create = Boolean.TRUE; create = Boolean.TRUE;
} }
} }
// Do not block more if maxWaitTimeMillis is set.
if (create == null &&
(localMaxWaitTimeMillis > 0 &&
System.currentTimeMillis() - localStartTimeMillis >= localMaxWaitTimeMillis)) {
create = Boolean.FALSE;
}
} }
if (!create.booleanValue()) { if (!create.booleanValue()) {
...@@ -923,6 +929,15 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -923,6 +929,15 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
destroyedCount.incrementAndGet(); destroyedCount.incrementAndGet();
createCount.decrementAndGet(); createCount.decrementAndGet();
} }
if (idleObjects.isEmpty() && idleObjects.hasTakeWaiters()) {
// POOL-356.
// In case there are already threads waiting on something in the pool
// (e.g. idleObjects.takeFirst(); then we need to provide them a fresh instance.
// Otherwise they will be stuck forever (or until timeout)
final PooledObject<T> freshPooled = create();
idleObjects.put(freshPooled);
}
} }
@Override @Override
...@@ -937,6 +952,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -937,6 +952,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* or the total number of objects (idle, checked out, or being created) reaches * or the total number of objects (idle, checked out, or being created) reaches
* {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless * {@link #getMaxTotal()}. If {@code always} is false, no instances are created unless
* there are threads waiting to check out instances from the pool. * there are threads waiting to check out instances from the pool.
* </p>
* *
* @param idleCount the number of idle instances desired * @param idleCount the number of idle instances desired
* @param always true means create instances even if the pool has no threads waiting * @param always true means create instances even if the pool has no threads waiting
...@@ -1123,6 +1139,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T> ...@@ -1123,6 +1139,7 @@ public class GenericObjectPool<T> extends BaseGenericObjectPool<T>
* JMX. That means it won't be invoked unless the explicitly requested * JMX. That means it won't be invoked unless the explicitly requested
* whereas all attributes will be automatically requested when viewing the * whereas all attributes will be automatically requested when viewing the
* attributes for an object in a tool like JConsole. * attributes for an object in a tool like JConsole.
* </p>
* *
* @return Information grouped on all the objects in the pool * @return Information grouped on all the objects in the pool
*/ */
......