[ https://issues.apache.org/jira/browse/POOL-363?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16803301#comment-16803301 ]
Josh Landin edited comment on POOL-363 at 3/27/19 8:59 PM: ----------------------------------------------------------- PR - https://github.com/apache/commons-pool/pull/20 As described [here|https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-], shutdown hooks cannot be started until all non-daemon threads have exited. In the case of commons-pool, historically the Evictor thread is not a daemon and does not exit while the object pool is open. This results in a deadlock in stand-alone application environments where DBCP is configured and managed by a Spring context, since the {{BasicDataSource}} is only closed during the Spring context shutdown hook. Changing the Evictor thread to be a daemon allows the Runtime shutdown process to proceed normally, the {{BasicDataSource}} to be closed, the Evictor thread to terminate, and VM to exit normally. was (Author: jlandin): PR - https://github.com/apache/commons-pool/pull/20 As described [here|https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-], shutdown hooks cannot be started until all non-daemon threads have exited. In the case of commons-pool, historically the Evictor thread is not a daemon and does not exit while the object pool is open. This results in a deadlock in stand-alone application environments where DBCP is configured and managed by a Spring context, since the {{BasicDataSource}} is only closed during the Spring context shutdown hook. Changing the Evictor thread to be a daemon allows the Runtime shutdown process to proceed normally. > Evictor Thread prevents Spring Context shutdown in standalone app > ----------------------------------------------------------------- > > Key: POOL-363 > URL: https://issues.apache.org/jira/browse/POOL-363 > Project: Commons Pool > Issue Type: Bug > Affects Versions: 2.4.3, 2.5.0, 2.6.0, 2.6.1 > Environment: Java {{1.8.0_92}} > Reporter: Josh Landin > Priority: Major > Attachments: 2019.03.26_screen281.jpg > > Time Spent: 10m > Remaining Estimate: 0h > > Given a DBCP2 connection pool configured in a Spring Application context with > the POOL evictor thread enabled, a standalone main() application hangs on > shutdown. Example below: > Maven pom.xml: > {code:xml} > <dependencies> > <dependency> > <groupId>org.apache.commons</groupId> > <artifactId>commons-dbcp2</artifactId> > <version>2.6.0</version><!-- Uses commons-pool2 : 2.6.1 --> > </dependency> > <dependency> > <groupId>mysql</groupId> > <artifactId>mysql-connector-java</artifactId> > <version>8.0.15</version> > </dependency> > <dependency> > <groupId>org.springframework</groupId> > <artifactId>spring-context</artifactId> > <version>5.1.5.RELEASE</version> > </dependency> > </dependencies> > {code} > MainTest.java: > {code:java} > import java.sql.Connection; > import java.sql.ResultSet; > import java.sql.SQLException; > import java.sql.Statement; > import javax.sql.DataSource; > import org.apache.commons.dbcp2.BasicDataSource; > import > org.springframework.context.annotation.AnnotationConfigApplicationContext; > import org.springframework.context.annotation.Bean; > import org.springframework.context.annotation.Configuration; > public class MainTest > { > @Configuration > public static class Config > { > @Bean > public DataSource getBasicDataSource() > { > BasicDataSource d = new BasicDataSource(); > d.setUrl("jdbc:mysql://localhost:3306/anydb"); > d.setUsername("myuser"); > d.setPassword("mypass"); > d.setTimeBetweenEvictionRunsMillis(1000); // Turn on Evictor Thread. > return d; > } > } > public static void main(String[] args) > { > AnnotationConfigApplicationContext ctx = new > AnnotationConfigApplicationContext(Config.class); > ctx.registerShutdownHook(); // Ensures context.close() on JVM shutdown. > > try( > Connection conn = ctx.getBean(BasicDataSource.class).getConnection(); > Statement stmt = conn.createStatement(); > ResultSet result = stmt.executeQuery("SELECT 1"); > ) > { > int records = result.last() ? result.getRow() : 0; > System.out.println("Records: "+records); > } > catch(SQLException e) > { > e.printStackTrace(); > } > System.out.println("End."); > } > } > {code} > The issue is not present when turning off the eviction thread by setting > {{timeBetweenEvictionRunsMillis}} to {{-1}}. > Jconsole thread summary attached for reference. -- This message was sent by Atlassian JIRA (v7.6.3#76005)