diff options
author | Thomas Watson | 2018-10-25 18:34:28 +0000 |
---|---|---|
committer | Thomas Watson | 2018-10-25 18:34:28 +0000 |
commit | 34ff143fce6643a6a318fd6878b0f5677a78e471 (patch) | |
tree | 5491e5ac55ebc3683b3d2af7df3b3197c825650f | |
parent | 7ccdd7e69de9f01a94e786a28611352172e8d424 (diff) | |
download | rt.equinox.framework-Y20181026-0120.tar.gz rt.equinox.framework-Y20181026-0120.tar.xz rt.equinox.framework-Y20181026-0120.zip |
Bug 540446 - Should issue a warning if an invalidated class loader isY20181026-0120I20181027-1800I20181026-1800I20181025-1800
used
Change-Id: Ia6585a0910a019d774fc071a4c83a774187544ec
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
2 files changed, 37 insertions, 3 deletions
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 414007839..f53778a2b 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 @@ -34,7 +34,9 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.AssertionFailedError; @@ -2369,7 +2371,7 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { exporter.start(); Bundle importer = getContext().installBundle(getName() + "-importer", new FileInputStream(importerBundleFile)); importer.start(); - Bundle requirer = getContext().installBundle(getName() + "-requirer", new FileInputStream(requirerBundleFile)); + final Bundle requirer = getContext().installBundle(getName() + "-requirer", new FileInputStream(requirerBundleFile)); requirer.start(); BundleWiring importerWiring = importer.adapt(BundleWiring.class); @@ -2400,6 +2402,17 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { // invalid wires by refreshing the exporter refreshBundles(Collections.singleton(exporter)); + // add a framework event listener to find error message about invalud class loaders + final BlockingQueue<FrameworkEvent> events = new LinkedBlockingQueue<>(); + getContext().addFrameworkListener(new FrameworkListener() { + @Override + public void frameworkEvent(FrameworkEvent event) { + if (event.getBundle() == requirer) { + events.add(event); + } + } + }); + try { importerCL.loadClass("export2.SomeClass"); fail("Expecting LinkageError."); @@ -2424,6 +2437,17 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { export4Resource = requirerCL.getResource("export4/resource.txt"); assertNull("Found resource from invalid wire.", export4Resource); + + // find the expected event + FrameworkEvent event = events.poll(5, TimeUnit.SECONDS); + assertNotNull("No FrameworkEvent found.", event); + assertEquals("Wrong bundle for event.", requirer, event.getBundle()); + assertEquals("Wrong event type.", FrameworkEvent.ERROR, event.getType()); + assertTrue("Wrong exception: " + event.getThrowable(), event.getThrowable() instanceof RuntimeException); + assertTrue("Wrong message: " + event.getThrowable().getMessage(), event.getThrowable().getMessage().startsWith("Invalid class loader")); + + // make sure there are no others + assertNull("Found more events.", events.poll(1, TimeUnit.SECONDS)); } void refreshBundles(Collection<Bundle> bundles) throws InterruptedException { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java index 3db16962b..461dc3101 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2017 IBM Corporation and others. + * Copyright (c) 2004, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -59,6 +59,7 @@ import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; +import org.osgi.framework.FrameworkEvent; import org.osgi.framework.namespace.BundleNamespace; import org.osgi.framework.namespace.HostNamespace; import org.osgi.framework.namespace.PackageNamespace; @@ -127,6 +128,7 @@ public class BundleLoader extends ModuleLoader { private volatile ModuleClassLoader classloader; private final ClassLoader parent; private final AtomicBoolean triggerClassLoaded = new AtomicBoolean(false); + private final AtomicBoolean firstUseOfInvalidLoader = new AtomicBoolean(false); /** * Returns the package name from the specified class name. @@ -964,7 +966,15 @@ public class BundleLoader extends ModuleLoader { private BundleLoader getProviderLoader(ModuleWire wire) { ModuleWiring provider = wire.getProviderWiring(); - return provider == null ? null : (BundleLoader) provider.getModuleLoader(); + if (provider == null) { + if (firstUseOfInvalidLoader.getAndSet(true)) { + // publish a framework event once per loader, include an exception to show the stack + String message = "Invalid class loader from a refreshed bundle is being used: " + toString(); //$NON-NLS-1$ + container.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, wiring.getBundle(), new IllegalStateException(message)); + } + return null; + } + return (BundleLoader) provider.getModuleLoader(); } final void addProvidedPackageNames(String packageName, List<String> result, boolean subPackages, Collection<BundleLoader> visited) { |