Details
-
Type:
Bug
-
Status:
Closed
-
Priority:
Major
-
Resolution: Cannot Reproduce
-
Affects Version/s: 1.5
-
Fix Version/s: 1.5.1
-
Component/s: Taverna Core
-
Labels:None
Description
The findClass
of ArtifactClassLoader is not synchronised. It is theoretically possible that two concurrent threads (for instance threads that are loading SPIs) could call findClass() on the same class - in effect loading the class bytecode twice and constructing (and returning) two different Class instances.
However, just one of these will survive in the caching classMap. This means that on the next call a different Class object will be returned for the unlucky thread.
To complicate the picture, findClass() is a protected method, and is invoked by ClassLoader.loadClass() - which does cache. However, we have multiple class loaders, and it seems likely that each of these could cache the class object as it goes upstream. If two class instances has been made, they might survive in different class loaders, which will return them on future calls to loadClass().
In theory, two instances of the same class should be compatible if they have the same name and classloader (according to a random blog I found on Google on this). However, they will have separate static fields, and static initializers will be run for each of them, possibly creating havoc.
What is suggested is to create a test that for instance creates 100 threads that each try to load a class in a loop. If more than 1 instance of the class occurs, the test fails. Then, if this can be reproduced, we can try to to a quick-fix of findClass() by just making it protected. However, note that this will lock all classloaders pending down dependencies, and not just the classloader that is actually responsible for the artifact. This is partly because our internal findClass() calls findClass() directly on parent - and children classloaders - and not the synchronized loadClass(). (Why? to pass on seenLoaders to avoid cyclic trouble)
Attachments
Issue Links
| Duplicate | |||
|---|---|---|---|
|
|||
We see stack traces suggesting that this is the case now and then: