[
https://issues.apache.org/jira/browse/OPENJPA-2257?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13540513#comment-13540513
]
Heath Thomann commented on OPENJPA-2257:
----------------------------------------
In addition to Albert's changes, I've found that more changes were necessary.
That is, synchronizing on '_supportedKeys' in ConfigurationImpl.getPropertyKeys
is necessary and fixes one ConcurrentModificationException/NPE, however, I
found another spot which causes a ConcurrentModificationException when the
returned '_supportedKeys' is added to by other areas of code. The exception
and stack I saw was the following:
java.util.ConcurrentModification
at java.util.TreeMap$AbstractMapIterator.makeNext(TreeMap.java:5794)
at java.util.TreeMap$UnboundedKeyIterator.next(TreeMap.java:5896)
at
org.apache.openjpa.persistence.EntityManagerImpl.getProperties(EntityManagerImpl.java:1624)
at Test.run(Test.java:26)
>From the stack, EntityManagerImpl.getProperties is operating on the the set
>(i.e. '_supportedKeys') returned by ConfigurationImpl.getPropertyKeys. In a
>single threaded environment, operating on the set is just fine. However, in
>my test, I had found that if one thread is operating on the set (as shown in
>the stack above), yet another thread is adding to the set, the
>ConcurrentModification exception can occur. While the details of my tests are
>rather long and nearly impossible to hit in a real world situation, let me
>basically state that I found that if a thread was in the
>'EntityManagerImpl.getProperties' listed above, and another thread was in this
>portion of code in BrokerImpl:
public Set<String> getSupportedProperties() {
Set<String> keys = _conf.getPropertyKeys();
for (String s : _supportedPropertyNames)
keys.add("openjpa." + s);
A ConcurrentModification exception could occur given that the one thread
operating in 'getSupportedProperties' could add to 'keys' (which is really the
'_supportedKeys'), and another thread could be iterating over this same set.
This issue seemed to be further complicated, and dependent on, the JDK in use.
I created the above exception by using an IBM JDK which appears to add some
inner classes (e.g. .TreeMap$UnboundedKeyIterator) to a TreeMap which performs
some additional checks for concurrent access. Bottom line is that the fix
appears to be to return a copy of '_supportedKeys' which is returned by
ConfigurationImpl.getPropertyKeys.
> Concurreny in org.apache.openjpa.persistence.EntityManagerImpl.getProperties
> leads to NullPointer and ConcurrentModificationException
> -------------------------------------------------------------------------------------------------------------------------------------
>
> Key: OPENJPA-2257
> URL: https://issues.apache.org/jira/browse/OPENJPA-2257
> Project: OpenJPA
> Issue Type: Bug
> Components: jpa
> Affects Versions: 2.1.2
> Environment: AIX 6.1 (64-bit)
> WebSphere Application Server V8.0 (32-bit)
> Reporter: Stephan Hagedorn
> Assignee: Albert Lee
> Labels: concurrency, concurrentmodificationexception,
> nullpointerexception
> Fix For: 2.3.0
>
> Attachments: OPENJPA-2257.patch, OpenJPABugTest.zip
>
>
> A call of EntityManager.getProperties() can lead to NullPointer and
> ConcurrentModificationException. Issue occurs right after start up of the
> overlying JEE application if multiple EntityManager instance are created at
> same time.
> Please find the issued stack trace below:
> Caused by: java.lang.NullPointerException
> at java.lang.String.compareTo(String.java:482)
> at java.lang.String.compareTo(String.java:31)
> at java.util.TreeMap.cmp(TreeMap.java:4514)
> at java.util.TreeMap.putImpl(TreeMap.java:4556)
> at java.util.TreeMap.put(TreeMap.java:4536)
> at java.util.TreeSet.add(TreeSet.java:122)
> at
> org.apache.openjpa.lib.conf.ConfigurationImpl.getPropertyKeys(ConfigurationImpl.java:708)
> at
> org.apache.openjpa.kernel.BrokerImpl.getSupportedProperties(BrokerImpl.java:729)
> at
> org.apache.openjpa.kernel.DelegatingBroker.getSupportedProperties(DelegatingBroker.java:223)
> at
> org.apache.openjpa.persistence.EntityManagerImpl.getProperties(EntityManagerImpl.java:1624)
> ... 33 more
--
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