Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2018-10-25 14:34:28 -0400
committerThomas Watson2018-10-25 14:34:28 -0400
commit34ff143fce6643a6a318fd6878b0f5677a78e471 (patch)
tree5491e5ac55ebc3683b3d2af7df3b3197c825650f
parent7ccdd7e69de9f01a94e786a28611352172e8d424 (diff)
downloadrt.equinox.framework-34ff143fce6643a6a318fd6878b0f5677a78e471.tar.gz
rt.equinox.framework-34ff143fce6643a6a318fd6878b0f5677a78e471.tar.xz
rt.equinox.framework-34ff143fce6643a6a318fd6878b0f5677a78e471.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>
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java26
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java14
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) {

Back to the top