You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Michael Pradel (Created) (JIRA)" <ji...@apache.org> on 2011/10/12 09:35:11 UTC

[jira] [Created] (DBCP-369) Exception when using SharedPoolDataSource concurrently

Exception when using SharedPoolDataSource concurrently
------------------------------------------------------

                 Key: DBCP-369
                 URL: https://issues.apache.org/jira/browse/DBCP-369
             Project: Commons Dbcp
          Issue Type: Bug
    Affects Versions: 1.4
         Environment: Java Hotspot Server VM 1.6.0_07, Linux
            Reporter: Michael Pradel


Hi,

I get a ConcurrentModificationException when using instances of SharedPoolDataSource concurrently. The problem occurs when one thread calls setDataSourceName() while another thread calls close(), either on the same instance of SharedPoolDataSource or on different instances. I'll attach a short example program that leads to an exception for almost every run on my machine.

The cause of the exception seems to be in InstanceKeyObjectFactory. registerNewInstance() is synchronized, but removeInstance() isn't. This allows concurrent accesses to the non-thread-safe 'instanceMap'.

Is this a bug? Or are SharedPoolDataSource and InstanceKeyObjectFactory not supposed to be thread-safe?

Thanks!


import java.util.ArrayList;
import org.apache.commons.dbcp.datasources.SharedPoolDataSource;

public class SharedPoolDataSourceTest {

	public static void main(String[] args) {
		new SharedPoolDataSourceTest().run();
	}
	
	private void run() {
		final ArrayList<SharedPoolDataSource> dataSources = new ArrayList<SharedPoolDataSource>();
		for (int j = 0; j < 10000; j++) {
			SharedPoolDataSource dataSource = new SharedPoolDataSource();
			dataSources.add(dataSource);
		}
	
		Thread t1 = new Thread(new Runnable() {
			public void run() {
				for (SharedPoolDataSource dataSource : dataSources) {
					dataSource.setDataSourceName("a");	
				}					
			}
		});
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				for (SharedPoolDataSource dataSource : dataSources) {
					try { dataSource.close(); } catch (Exception e) {}	
				}
				
			}
		});
		t1.start();
		t2.start();
		try {
			t1.join();
			t2.join();
		} catch (InterruptedException ie) {}
	}	
}



Exception in thread "Thread-0" java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
	at org.apache.commons.dbcp.datasources.InstanceKeyObjectFactory.registerNewInstance(InstanceKeyObjectFactory.java:51)
	at org.apache.commons.dbcp.datasources.InstanceKeyDataSource.setDataSourceName(InstanceKeyDataSource.java:246)
	at potentialBugs.SharedPoolDataSourceTest$1.run(SharedPoolDataSourceTest.java:23)
	at java.lang.Thread.run(Thread.java:619)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Updated] (DBCP-369) Exception when using SharedPoolDataSource concurrently

Posted by "Thomas Neidhart (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DBCP-369?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Thomas Neidhart updated DBCP-369:
---------------------------------

    Attachment: DBCP-369.patch

The access to the InstanceKeyObjectFactory is not fully synchronized. Some methods (registerNewInstance) were already synchronized, while others (removeInstance, closeAll) not.

This lead to the ConcurrentModificationExceptions when multiple threads try to modify the internal instanceMap.

The attached patch adds a unit test and fixes the problem by synchronizing all public/protected methods in the factory that modify / access the instanceMap.
                
> Exception when using SharedPoolDataSource concurrently
> ------------------------------------------------------
>
>                 Key: DBCP-369
>                 URL: https://issues.apache.org/jira/browse/DBCP-369
>             Project: Commons Dbcp
>          Issue Type: Bug
>    Affects Versions: 1.4
>         Environment: Java Hotspot Server VM 1.6.0_07, Linux
>            Reporter: Michael Pradel
>             Fix For: 1.4.1
>
>         Attachments: DBCP-369.patch
>
>
> Hi,
> I get a ConcurrentModificationException when using instances of SharedPoolDataSource concurrently. The problem occurs when one thread calls setDataSourceName() while another thread calls close(), either on the same instance of SharedPoolDataSource or on different instances. I'll attach a short example program that leads to an exception for almost every run on my machine.
> The cause of the exception seems to be in InstanceKeyObjectFactory. registerNewInstance() is synchronized, but removeInstance() isn't. This allows concurrent accesses to the non-thread-safe 'instanceMap'.
> Is this a bug? Or are SharedPoolDataSource and InstanceKeyObjectFactory not supposed to be thread-safe?
> Thanks!
> import java.util.ArrayList;
> import org.apache.commons.dbcp.datasources.SharedPoolDataSource;
> public class SharedPoolDataSourceTest {
> 	public static void main(String[] args) {
> 		new SharedPoolDataSourceTest().run();
> 	}
> 	
> 	private void run() {
> 		final ArrayList<SharedPoolDataSource> dataSources = new ArrayList<SharedPoolDataSource>();
> 		for (int j = 0; j < 10000; j++) {
> 			SharedPoolDataSource dataSource = new SharedPoolDataSource();
> 			dataSources.add(dataSource);
> 		}
> 	
> 		Thread t1 = new Thread(new Runnable() {
> 			public void run() {
> 				for (SharedPoolDataSource dataSource : dataSources) {
> 					dataSource.setDataSourceName("a");	
> 				}					
> 			}
> 		});
> 		Thread t2 = new Thread(new Runnable() {
> 			public void run() {
> 				for (SharedPoolDataSource dataSource : dataSources) {
> 					try { dataSource.close(); } catch (Exception e) {}	
> 				}
> 				
> 			}
> 		});
> 		t1.start();
> 		t2.start();
> 		try {
> 			t1.join();
> 			t2.join();
> 		} catch (InterruptedException ie) {}
> 	}	
> }
> Exception in thread "Thread-0" java.util.ConcurrentModificationException
> 	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
> 	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
> 	at org.apache.commons.dbcp.datasources.InstanceKeyObjectFactory.registerNewInstance(InstanceKeyObjectFactory.java:51)
> 	at org.apache.commons.dbcp.datasources.InstanceKeyDataSource.setDataSourceName(InstanceKeyDataSource.java:246)
> 	at potentialBugs.SharedPoolDataSourceTest$1.run(SharedPoolDataSourceTest.java:23)
> 	at java.lang.Thread.run(Thread.java:619)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

[jira] [Updated] (DBCP-369) Exception when using SharedPoolDataSource concurrently

Posted by "Phil Steitz (Updated) (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/DBCP-369?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Phil Steitz updated DBCP-369:
-----------------------------

    Fix Version/s: 1.4.1
    
> Exception when using SharedPoolDataSource concurrently
> ------------------------------------------------------
>
>                 Key: DBCP-369
>                 URL: https://issues.apache.org/jira/browse/DBCP-369
>             Project: Commons Dbcp
>          Issue Type: Bug
>    Affects Versions: 1.4
>         Environment: Java Hotspot Server VM 1.6.0_07, Linux
>            Reporter: Michael Pradel
>             Fix For: 1.4.1
>
>
> Hi,
> I get a ConcurrentModificationException when using instances of SharedPoolDataSource concurrently. The problem occurs when one thread calls setDataSourceName() while another thread calls close(), either on the same instance of SharedPoolDataSource or on different instances. I'll attach a short example program that leads to an exception for almost every run on my machine.
> The cause of the exception seems to be in InstanceKeyObjectFactory. registerNewInstance() is synchronized, but removeInstance() isn't. This allows concurrent accesses to the non-thread-safe 'instanceMap'.
> Is this a bug? Or are SharedPoolDataSource and InstanceKeyObjectFactory not supposed to be thread-safe?
> Thanks!
> import java.util.ArrayList;
> import org.apache.commons.dbcp.datasources.SharedPoolDataSource;
> public class SharedPoolDataSourceTest {
> 	public static void main(String[] args) {
> 		new SharedPoolDataSourceTest().run();
> 	}
> 	
> 	private void run() {
> 		final ArrayList<SharedPoolDataSource> dataSources = new ArrayList<SharedPoolDataSource>();
> 		for (int j = 0; j < 10000; j++) {
> 			SharedPoolDataSource dataSource = new SharedPoolDataSource();
> 			dataSources.add(dataSource);
> 		}
> 	
> 		Thread t1 = new Thread(new Runnable() {
> 			public void run() {
> 				for (SharedPoolDataSource dataSource : dataSources) {
> 					dataSource.setDataSourceName("a");	
> 				}					
> 			}
> 		});
> 		Thread t2 = new Thread(new Runnable() {
> 			public void run() {
> 				for (SharedPoolDataSource dataSource : dataSources) {
> 					try { dataSource.close(); } catch (Exception e) {}	
> 				}
> 				
> 			}
> 		});
> 		t1.start();
> 		t2.start();
> 		try {
> 			t1.join();
> 			t2.join();
> 		} catch (InterruptedException ie) {}
> 	}	
> }
> Exception in thread "Thread-0" java.util.ConcurrentModificationException
> 	at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
> 	at java.util.HashMap$KeyIterator.next(HashMap.java:828)
> 	at org.apache.commons.dbcp.datasources.InstanceKeyObjectFactory.registerNewInstance(InstanceKeyObjectFactory.java:51)
> 	at org.apache.commons.dbcp.datasources.InstanceKeyDataSource.setDataSourceName(InstanceKeyDataSource.java:246)
> 	at potentialBugs.SharedPoolDataSourceTest$1.run(SharedPoolDataSourceTest.java:23)
> 	at java.lang.Thread.run(Thread.java:619)

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira