United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-4406709 change in class loading in jdk 1.3 causes customer app to deadlock
JDK-4406709 : change in class loading in jdk 1.3 causes customer app to deadlock

Details
Type:
Bug
Submit Date:
2001-01-22
Status:
Closed
Updated Date:
2001-03-02
Project Name:
JDK
Resolved Date:
2001-03-02
Component:
hotspot
OS:
solaris_2.6
Sub-Component:
runtime
CPU:
sparc
Priority:
P2
Resolution:
Not an Issue
Affected Versions:
1.3_01
Fixed Versions:

Related Reports
Relates:

Sub Tasks

Description
Wanted to get this logged but still working with customer and engineering to
determine if this is a bug in the customers app or a jdk 1.3 issue.



I wonder if you could help us with a rather serious problem we're seeing
>	with the Standard Edition JDK 1.3 release?  It appears that the contract
>	between the Java VM and the ClassLoader has changed in a subtle but
>	important way in JDK 1.3 compared to previous releases: in JDK 1.3 when
>	the VM needs to load a class (e.g. to resolve a dynamically-linked 
>reference),
>	the VM calls a new private method on java.lang.ClassLoader called
>	"loadClassInternal".  This private method is synchronized on the class
>	loader object, and that's what causes the problem.
>	
>	In prior releases, the VM simply called the loadClass(String) method on
>	the class loader, which was NOT synchronized; this gave the class loader
>	the opportunity to manage its own synchronization by appropriately
>	overloading the loadClass(String) or loadClass(String, boolean) methods.
>	Now, however, the class loader has no control over synchronization -- 
>because
>	loadClassInternal is private and synchronized, the class loader is
>	always called with the lock on the class loader object held.
>	
>	SilverStream uses a rather complicated class loading scheme to try to
>	permit on-the-fly replacement of classes in a running app server; this
>	involves using multiple class loaders including one which implements
>	class path semantics (e.g. first look in Jar file A, then in Jar file
>	B, etc.)  This means that we often need to call more than one class
>	loader in the course of loading a class, and that sometimes a call
>	to loadClass() on class loader A actually results in the class being
>	loaded (and defined) by class loader B.  This no longer works reliably
>	in JDK 1.3, because of deadlocks introduced by the new synchronized
>	loadClassInternal method -- if the VM calls class loader A's
>	loadClassInternal method, class loader A is now locked; A then must
>	call a synchronized method in B.  Other threads can perform these
>	operations in the opposite order, resulting in a deadlock.
>	
>	We think that the change to use the synchronized loadClassInternal()
>	method was an incompatible semantic change to class loading.  We'd
>	like to request that either:
>	 1) The change be backed out; or
>	 2) The loadClassInternal() method be made protected, so we can
>	    overload it in our class loaders to avoid the deadlock.
>	
>	Can you please contact the appropriate engineers in the JDK group
>	to find out why this change was made and what the prospects for a
>	fix to our problem are?  Needless to say, this is pretty high-priority
>	for us -- customers have already reported this deadlock when using
>	the SilverStream application server with JDK 1.3, and we have no
>	workaround for them at present.
>	

                                    

Comments
EVALUATION

As has been mentioned in emails to the customer, the VM locks the classloader
internally before it makes the upcall to loadClassInternal. For this reason the
"synchronized" statement is actually a no-op. This hang would almost certainly
have been reproducible under 1.2 as well.

kenneth.russell@eng 2001-02-09


fred.oliver@East 2001-03-01
In the 1.3 case, HotSpot locks the ClassLoader object BEFORE beginning the
search for the class, and holds the lock until the loading of the class
(and superclasses, interfaces, etc.) is complete.

In the 1.2 case (assuming the production release for Solaris), ExactVM
locks the ClassLoader object AFTER the search for the class, during the
definition of the class, and holds the lock until the loading of the class
(and superclasses, interfaces, etc.) is complete.

It is the fact that ExactVM locked the ClassLoader at a slightly later time
which allows the multi-threaded behavior demonstrated by this customer
application.

While the class loading strategy this particular application uses appears
to work with ExactVM, loading base classes from delegated classloaders in
parallel, it should be able to contrive a similar situation using
superclasses are loaded from delegated classloaders which deadlocks ExactVM
as well.


fred.oliver@East 2001-03-02
In my view the HotSpot behavior is more correct with respect to the JVM
Specification, section 5.3.2.  If a JVM allowed multiple calls to an 
initiating classloader's loadClass (or loadClassInternal), and if those
calls delegated to different defining classloaders, then the JVM would
not be able to choose between them.

http://java.sun.com/docs/books/vmspec/2nd-edition/html/ConstantPool.doc.html#79441

This is not a bug in the 1.3 SDK (it's a bug in the 1.2 SDK which
allowed this behavior).

Perhaps it is possible for some of the synchronized methods in the 
customer's classloaders to be moved to separate objects, so that they
are not affected by the classloader's locks.

fred.oliver@East 2001-03-02
Also, the requirement that loadClass() be called once is mentioned in 
the following paper:

http://java.sun.com/people/gbracha/classloaders.ps
                                     
2001-03-02



Hardware and Software, Engineered to Work Together