[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[equinox-dev] buddy classloading & deadlock

Hi all,

I noticed that multithreading combined with buddy classloading can
produce some scary deadlocks. I had one in a project last week and
managed to recreate it in a toy example. Now I'm wondering if this is
just one of the dangers of breaking the classloading hierarchy or if
the framework could do something to avoid this ?

My toy example (also in attachment):

The main project has just one Application class:

public class Application implements IPlatformRunnable{
	
	public Object run(Object args) throws Exception {
		new Activator();
		return true;
	}
	
}


and the dependent project has an Activator

public class Activator implements BundleActivator {

public void start(BundleContext context) throws Exception {
 new Thread(new Runnable() {
	public void run() {
	try {
                   Class.forName("main.Application");
               } catch (ClassNotFoundException e) { }
 }).start();

 // let other thread run to induce deadlock		
 try { Thread.sleep(100); } catch (InterruptedException e) {}
}

public void stop(BundleContext context) throws Exception {}

}


The main project depends on dependent, and the dependent project has a global buddy policy.


This causes the following deadlock:

Thread [main] (Suspended)	
	owns: DefaultClassLoader  (id=16)	
	waiting for: DefaultClassLoader  (id=15)	
	ClasspathManager.findLocalClassImpl(String, ClassLoadingStatsHook[]) line: 422	
	ClasspathManager.findLocalClass(String) line: 410	
	DefaultClassLoader.findLocalClass(String) line: 188	
	BundleLoader.findLocalClass(String) line: 339	
	SingleSourcePackage.loadClass(String) line: 37	
	BundleLoader.findClass(String, boolean) line: 388	
	BundleLoader.findClass(String) line: 352	
	DefaultClassLoader.loadClass(String, boolean) line: 83	
	DefaultClassLoader(ClassLoader).loadClass(String) line: 251	
	DefaultClassLoader(ClassLoader).loadClassInternal(String) line: 319	
	Application.run(Object) line: 11	
	PlatformActivator$1.run(Object) line: 78	
	EclipseAppLauncher.runApplication(Object) line: 92	
	EclipseAppLauncher.start(Object) line: 68	
	EclipseStarter.run(Object) line: 400	
	EclipseStarter.run(String[], Runnable) line: 177	
	NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not
available [native method]
	NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39	
	DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25	
	Method.invoke(Object, Object...) line: 585	
	Main.invokeFramework(String[], URL[]) line: 336	
	Main.basicRun(String[]) line: 280	
	Main.run(String[]) line: 977	
	Main.main(String[]) line: 952	

Thread [Thread-1] (Suspended)	
	owns: DefaultClassLoader  (id=15)	
	waiting for: DefaultClassLoader  (id=16)	
	ClasspathManager.findLocalClassImpl(String, ClassLoadingStatsHook[]) line: 422	
	ClasspathManager.findLocalClass(String) line: 410	
	DefaultClassLoader.findLocalClass(String) line: 188	
	BundleLoader.findLocalClass(String) line: 339	
	BundleLoader.findClass(String, boolean) line: 391	
	BundleLoader.findClass(String) line: 352	
	DefaultClassLoader.loadClass(String, boolean) line: 83	
	DefaultClassLoader(ClassLoader).loadClass(String) line: 251	
	BundleLoader.loadClass(String) line: 276	
	BundleHost.loadClass(String, boolean) line: 227	
	BundleHost(AbstractBundle).loadClass(String) line: 1245	
	GlobalPolicy.loadClass(String) line: 39	
	PolicyHandler.doBuddyClassLoading(String) line: 138	
	BundleLoader.findClass(String, boolean) line: 402	
	BundleLoader.findClass(String) line: 352	
	DefaultClassLoader.loadClass(String, boolean) line: 83	
	DefaultClassLoader(ClassLoader).loadClass(String) line: 251	
	DefaultClassLoader(ClassLoader).loadClassInternal(String) line: 319	
	Class<T>.forName0(String, boolean, ClassLoader) line: not available
[native method]
	Class<T>.forName(String) line: 164	
	Activator$1.run() line: 12	
	Thread.run() line: 595

Attachment: buddy-classloading-deadlock.zip
Description: Zip archive