diff options
author | Thomas Watson | 2016-04-06 15:11:46 +0000 |
---|---|---|
committer | Thomas Watson | 2016-04-07 20:59:19 +0000 |
commit | 4ce5a47c68bdb8696bf725c512105b08bc2d9d69 (patch) | |
tree | 60fcbd13eef58fe2a13371e844d788a3e574cea9 | |
parent | 996537033657df4dd4505606efdd752114a2e097 (diff) | |
download | rt.equinox.framework-4ce5a47c68bdb8696bf725c512105b08bc2d9d69.tar.gz rt.equinox.framework-4ce5a47c68bdb8696bf725c512105b08bc2d9d69.tar.xz rt.equinox.framework-4ce5a47c68bdb8696bf725c512105b08bc2d9d69.zip |
Bug 490902 - LinkageError in parallel class loading of ModuleClassLoader
Attempt at a testcase to reproduce
Change-Id: I0f3660b06e4c5cba6c8fe98f31c94d87ece19bf0
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
9 files changed, 143 insertions, 4 deletions
diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath index 7290c9716..41bd4f9ad 100644 --- a/bundles/org.eclipse.osgi.tests/.classpath +++ b/bundles/org.eclipse.osgi.tests/.classpath @@ -133,5 +133,7 @@ <classpathentry kind="src" output="bundle_tests/test.protocol.handler" path="bundles_src/test.protocol.handler"/> <classpathentry kind="src" output="bundle_tests/test.bug471551" path="bundles_src/test.bug471551"/> <classpathentry kind="src" output="bundle_tests/test.dynamicimport" path="bundles_src/test.dynamicimport"/> + <classpathentry kind="src" output="bundle_tests/test.bug490902.a" path="bundles_src/test.bug490902.a"/> + <classpathentry kind="src" output="bundle_tests/test.bug490902.b" path="bundles_src/test.bug490902.b"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/bundles/org.eclipse.osgi.tests/build.properties b/bundles/org.eclipse.osgi.tests/build.properties index a00fd2ade..8676259ad 100644 --- a/bundles/org.eclipse.osgi.tests/build.properties +++ b/bundles/org.eclipse.osgi.tests/build.properties @@ -270,6 +270,10 @@ source.bundle_tests/test.bug471551.jar = bundles_src/test.bug471551/ manifest.bundle_tests/test.bug471551.jar = META-INF/MANIFEST.MF source.bundle_tests/test.dynamicimport.jar = bundles_src/test.dynamicimport/ manifest.bundle_tests/test.dynamicimport.jar = META-INF/MANIFEST.MF +source.bundle_tests/test.bug490902.b.jar = bundles_src/test.bug490902.b/ +manifest.bundle_tests/test.bug490902.b.jar = META-INF/MANIFEST.MF +source.bundle_tests/test.bug490902.a.jar = bundles_src/test.bug490902.a/ +manifest.bundle_tests/test.bug490902.a.jar = META-INF/MANIFEST.MF jars.compile.order = bundle_tests/ext.framework.b.jar,\ .,\ @@ -400,4 +404,6 @@ jars.compile.order = bundle_tests/ext.framework.b.jar,\ bundle_tests/wrapper.hooks.a.jar,\ bundle_tests/test.protocol.handler.jar,\ bundle_tests/test.bug471551.jar,\ - bundle_tests/test.dynamicimport.jar + bundle_tests/test.dynamicimport.jar,\ + bundle_tests/test.bug490902.b.jar,\ + bundle_tests/test.bug490902.a.jar diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/META-INF/MANIFEST.MF new file mode 100755 index 000000000..ed517a5b8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: test.bug490902.a +Bundle-SymbolicName: test.bug490902.a +Bundle-Version: 1.0.0 +Import-Package: test.bug490902.b + diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/A1.java b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/A1.java new file mode 100755 index 000000000..0de280315 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/A1.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2016 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package test.bug490902.a; + +import test.bug490902.b.B1; + +public class A1 extends B1 { + // nothing +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/TestLoadA1.java b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/TestLoadA1.java new file mode 100755 index 000000000..7b3a2fd6b --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.a/test/bug490902/a/TestLoadA1.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2016 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package test.bug490902.a; + +public class TestLoadA1 { + public TestLoadA1() { + new A1(); + } +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/META-INF/MANIFEST.MF new file mode 100755 index 000000000..cb5ea7d9e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: test.bug490902.b +Bundle-SymbolicName: test.bug490902.b +Bundle-Version: 1.0.0 +Export-Package: test.bug490902.b +Bundle-ActivationPolicy: lazy diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/test/bug490902/b/B1.java b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/test/bug490902/b/B1.java new file mode 100755 index 000000000..36b49b44d --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.bug490902.b/test/bug490902/b/B1.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2016 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package test.bug490902.b; + +public class B1 { + // nothing +} diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java index b984c2c8b..b4d6729ee 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java @@ -14,6 +14,7 @@ import java.io.*; import java.lang.reflect.Method; import java.net.*; import java.util.*; +import java.util.concurrent.CountDownLatch; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.osgi.tests.OSGiTestsActivator; @@ -2054,4 +2055,69 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { String bundleName = headers.get(Constants.BUNDLE_NAME); assertEquals("Wrong bundle name header.", "default", bundleName); } + + public void testBug490902() throws BundleException, InterruptedException, ClassNotFoundException, InstantiationException, IllegalAccessException { + final Bundle a1 = installer.installBundle("test.bug490902.a"); + final Bundle b1 = installer.installBundle("test.bug490902.b"); + installer.resolveBundles(new Bundle[] {a1, b1}); + + final CountDownLatch startingB = new CountDownLatch(1); + final CountDownLatch endedSecondThread = new CountDownLatch(1); + BundleListener delayB1 = new SynchronousBundleListener() { + @Override + public void bundleChanged(BundleEvent event) { + if (event.getBundle() == b1 && BundleEvent.STARTING == event.getType()) { + try { + startingB.countDown(); + System.out.println(getName() + ": Delaying now ..."); + Thread.sleep(15000); + System.out.println(getName() + ": Done delaying."); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + }; + getContext().addBundleListener(delayB1); + try { + new Thread(new Runnable() { + + @Override + public void run() { + try { + System.out.println(getName() + ": Initial load test."); + a1.loadClass("test.bug490902.a.TestLoadA1").newInstance(); + } catch (Throwable e) { + e.printStackTrace(); + } + } + }, "Initial load test thread.").start(); + + startingB.await(); + Thread secondThread = new Thread(new Runnable() { + + @Override + public void run() { + try { + System.out.println(getName() + ": Second load test."); + a1.loadClass("test.bug490902.a.TestLoadA1").newInstance(); + } catch (Throwable e) { + e.printStackTrace(); + } finally { + endedSecondThread.countDown(); + } + } + }, "Second load test thread."); + secondThread.start(); + // hack to make sure secondThread is in the middle of Class.forName + Thread.sleep(10000); + + System.out.println(getName() + ": About to interrupt:" + secondThread.getName()); + secondThread.interrupt(); + endedSecondThread.await(); + a1.loadClass("test.bug490902.a.TestLoadA1").newInstance(); + } finally { + getContext().removeBundleListener(delayB1); + } + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java index 199599389..1c81488f1 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/ModuleClassLoader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2014 IBM Corporation and others. + * Copyright (c) 2005, 2016 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -414,8 +414,10 @@ public abstract class ModuleClassLoader extends ClassLoader implements BundleRef lockingThread = classNameLocks.get(classname); } } catch (InterruptedException e) { - current.interrupt(); - throw (LinkageError) new LinkageError(classname).initCause(e); + previousInterruption = true; + // must not throw LinkageError or ClassNotFoundException here because that will cause all threads + // to fail to load the class (see bug 490902) + throw new Error("Interrupted while waiting for classname lock: " + classname, e); //$NON-NLS-1$ } finally { if (previousInterruption) { current.interrupt(); |