JDK-6832540 : IllegalArgumentException in ClassLoader.definePackage when classes are loaded in parallel
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2009-04-21
  • Updated: 2025-02-06
  • Resolved: 2009-07-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b66Fixed
Related Reports
Relates :  
Description
Starting from jdk7b55, a number of VM tests from ParallelClassLoading suite start to fail intermittenlty with the following error:
java.lang.IllegalArgumentException exception is caught in "Loading Thread #10": custom
java.lang.IllegalArgumentException: custom
        at java.lang.ClassLoader.definePackage(ClassLoader.java:1591)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:343)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:75)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:294)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:288)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:287)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:391)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:307)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:331)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at runtime.ParallelClassLoading.shared.ProvokeType.provoke(ProvokeType.java:83)
        at runtime.ParallelClassLoading.shared.CustomProvokeType.provoke(CustomProvokeType.java:20)
        at runtime.ParallelClassLoading.shared.ClassLoadingThread.run(ClassLoadingThread.java:81)

Test scenario is:
	1) create custom class loader
	2) initiate loading of some class hierarchy from multiple threads
	3) go to step #1 if the time & iteration limit isn't reached

The failure always occurs during first loading iteration. Seems like the problem relates to initialization stage.

According to ClassLoader.definePackage contract, it throws IllegalArgumentException if "package name duplicates an existing package either in this class loader or one of its ancestors". Test code doesn't explicitly call defineClass.

How to reproduce: 
	1) login to vm-t2000-01a.sfbay
	2) cd /net/sqenfs-2.sfbay/export2/results/vm/gtee/HSX/PIT/VM/16/b01/jdk7b56/product/vm/solaris-sparc/client/mixed/solaris-sparc_client_mixed_vm.parallel_class_loading.testlist/ResultDir/anonymous-complex
	3) bash rerun.sh

Test sources can be found at: /net/vmsqe.russia/export/testbase/sqe/vm/7/ws_int_spb/vm/src/runtime/ParallelClassLoading/shared

Comments
EVALUATION Updated URLClassLoader to re-try and re-verify the package when ClassLoader.definePackage(...) throws IllegalArgumentException for parallel-capable class loaders.
13-07-2009

EVALUATION After further investigation, it appears that using the same lock object for classes within the same package may lead to some deadlock scenarios such as com.a.A extends com.b.SupA and com.b.B extends com.a.SupB. Thus, will have to adopt a different approach. One possible alternative fix is - for parallel class loaders, duplicate definePackage(...) calls will be ignored rather than throwing IllegalArgumentException.
08-06-2009

EVALUATION There is a race condition when calling java.net.URLClassLoader.findClass(...) method which leads to a check-then-set kind of actions on the private field "packages" in the java.lang.ClassLoader. To address this race condition problem, the most natural fix would be to change the impl of java.lang.ClassLoader.getClassLoadingLock(String className) to return the same lock object for classes within the same package for parallel class loaders. This is more restrictive than what we have now, but conceptually makes sense. Checking with a few people to see if they agree with this approach.
28-05-2009