This message came up on equinox-dev recently. It highlights a
potential deadlock when the Sun VM locks the classloader prior to
calling loadClassInternal. I have no idea if this is an issue for the
VM we're using, but if it is, we ought to consider what can be done to
fix it.
Alex.
---------- Forwarded message ----------
From: Thomas Watson
Date: 03-Aug-2006 16:32
Subject: Re: [equinox-dev] buddy classloading & deadlock
To: Equinox development mailing list
What vendor/version of the VM are you using?
There has been a long standing bug open against Sun on a similar
issue. It all boils down to the native VM locking the classloader
before loading a class from it using the ClassLoader.loadClassInternal
method. In your stacktrace below this happens when the VM calls
ClassLoader.loadClassInternal
(DefaultClassLoader(ClassLoader).loadClassInternal(String) line: 319).
The VM locks the classloader in native code before it ever calls into
the ClassLoader. This leaves us with no options, even if we override
the loadClassInternal method to make it non-synchronized it will make
no difference because the native code locks the ClassLoader no matter
what the method signature is for loadClassInternal. I have been told
that Sun plans to fix this in a future release of the VM, it may be
fixed in the latest 1.5 Sun VM. The IBM VMs have fixed this issue,
they will NOT lock the classloader before invoking it from the native
VM code.
Tom
---
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" deleted by Thomas
Watson/Austin/IBM] _______________________________________________
equinox-dev mailing list
https://dev.eclipse.org/mailman/listinfo/equinox-dev
_______________________________________________
equinox-dev mailing list
https://dev.eclipse.org/mailman/listinfo/equinox-dev
---------------------------------------------------------------------
Terms of use : http://incubator.apache.org/harmony/mailing.html
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]