Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2017-02-28 15:03:45 +0000
committerThomas Watson2017-03-02 20:50:36 +0000
commit64c504c7f56e523b3a70c065bf793acc7c397487 (patch)
treeab116274d3bfc00d447054f407a49652f7f72327 /bundles/org.eclipse.osgi.tests
parent6e3d3967c4052a93abc26281fe7809f4abbc5e69 (diff)
downloadrt.equinox.framework-64c504c7f56e523b3a70c065bf793acc7c397487.tar.gz
rt.equinox.framework-64c504c7f56e523b3a70c065bf793acc7c397487.tar.xz
rt.equinox.framework-64c504c7f56e523b3a70c065bf793acc7c397487.zip
Change-Id: I3223216586d1cb5bf399132b26293cf0e787377f Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi.tests')
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java35
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java81
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java33
3 files changed, 146 insertions, 3 deletions
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java b/bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java
index 0259d4fd2..db458e144 100644
--- a/bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2016 IBM Corporation and others.
+ * Copyright (c) 2013, 2017 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
@@ -10,6 +10,7 @@
*******************************************************************************/
package org.eclipse.osgi.tests.classloader.hooks.a;
+import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.internal.hookregistry.*;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
@@ -18,6 +19,13 @@ import org.eclipse.osgi.storage.bundlefile.BundleEntry;
public class TestHookConfigurator implements HookConfigurator {
private static final String REJECT_PROP = "classloader.hooks.a.reject";
private static final String BAD_TRANSFORM_PROP = "classloader.hooks.a.bad.transform";
+ private static final String RECURSION_LOAD = "classloader.hooks.a.recursion.load";
+ private static final String RECURSION_LOAD_SUPPORTED = "classloader.hooks.a.recursion.load.supported";
+ final ThreadLocal<Boolean> doingRecursionLoad = new ThreadLocal<Boolean>() {
+ protected Boolean initialValue() {
+ return false;
+ };
+ };
public void addHooks(HookRegistry hookRegistry) {
hookRegistry.addClassLoaderHook(new ClassLoaderHook() {
@@ -32,9 +40,34 @@ public class TestHookConfigurator implements HookConfigurator {
if (Boolean.getBoolean(BAD_TRANSFORM_PROP)) {
return new byte[] {'b', 'a', 'd', 'b', 'y', 't', 'e', 's'};
}
+ if (Boolean.getBoolean(RECURSION_LOAD)) {
+ if (isProcessClassRecursionSupported() && doingRecursionLoad.get()) {
+ return null;
+ }
+ Module m = manager.getGeneration().getBundleInfo().getStorage().getModuleContainer().getModule(1);
+ doingRecursionLoad.set(true);
+ try {
+ m.getCurrentRevision().getWiring().getClassLoader().loadClass("substitutes.x.Ax");
+ if (!isProcessClassRecursionSupported()) {
+ throw new LinkageError("Recursion is no supported.");
+ }
+ } catch (ClassNotFoundException e) {
+ if (isProcessClassRecursionSupported()) {
+ throw new LinkageError("Recursion should be supported.");
+ }
+ // expected
+ } finally {
+ doingRecursionLoad.set(false);
+ }
+ }
return null;
}
+ @Override
+ public boolean isProcessClassRecursionSupported() {
+ return Boolean.getBoolean(RECURSION_LOAD_SUPPORTED);
+ }
+
});
}
}
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 20fbe4366..1acbfb4a1 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
@@ -15,6 +15,7 @@ import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.ws.Endpoint;
@@ -25,6 +26,8 @@ import org.eclipse.osgi.tests.OSGiTestsActivator;
import org.osgi.framework.*;
import org.osgi.framework.hooks.resolver.ResolverHook;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
+import org.osgi.framework.hooks.weaving.WeavingHook;
+import org.osgi.framework.hooks.weaving.WovenClass;
import org.osgi.framework.namespace.PackageNamespace;
import org.osgi.framework.wiring.*;
import org.osgi.service.packageadmin.ExportedPackage;
@@ -2221,6 +2224,84 @@ public class ClassLoadingBundleTests extends AbstractBundleTests {
}
}
+ public void testRecursiveWeavingHookFactory() {
+ final ThreadLocal<Boolean> testThread = new ThreadLocal<Boolean>() {
+ @Override
+ protected Boolean initialValue() {
+ return Boolean.FALSE;
+ }
+ };
+
+ testThread.set(Boolean.TRUE);
+ final Set<String> weavingHookClasses = new HashSet<String>();
+ final List<WovenClass> called = new ArrayList<WovenClass>();
+ final AtomicBoolean loadNewClassInWeave = new AtomicBoolean(false);
+
+ ServiceFactory<WeavingHook> topFactory = new ServiceFactory<WeavingHook>() {
+ @Override
+ public WeavingHook getService(Bundle bundle, ServiceRegistration<WeavingHook> registration) {
+ if (!testThread.get()) {
+ return null;
+ }
+ WeavingHook hook = new WeavingHook() {
+
+ @Override
+ public void weave(WovenClass wovenClass) {
+ if (loadNewClassInWeave.get()) {
+ // Force a load of inner class
+ Runnable run = new Runnable() {
+ @Override
+ public void run() {
+ // nothing
+ }
+ };
+ run.run();
+ weavingHookClasses.add(run.getClass().getName());
+ }
+ called.add(wovenClass);
+ }
+ };
+ weavingHookClasses.add(hook.getClass().getName());
+ return hook;
+ }
+
+ @Override
+ public void ungetService(Bundle bundle, ServiceRegistration<WeavingHook> registration, WeavingHook service) {
+ // nothing
+ }
+ };
+ ServiceRegistration<WeavingHook> reg = getContext().registerService(WeavingHook.class, topFactory, null);
+
+ Runnable run = null;
+ try {
+ // force call to factory without protection of the framework recursion checks
+ topFactory.getService(null, null);
+
+ // set flag to load inner class while weaving
+ loadNewClassInWeave.set(true);
+
+ // Force a load of inner class
+ run = new Runnable() {
+ @Override
+ public void run() {
+ // nothing
+ }
+ };
+ run.run();
+ } finally {
+ reg.unregister();
+ }
+
+ assertEquals("Unexpected number of woven classes.", 3, called.size());
+ for (WovenClass wovenClass : called) {
+ if (weavingHookClasses.contains(wovenClass.getClassName())) {
+ assertNull("Did not expect to find class: " + wovenClass.getDefinedClass(), wovenClass.getDefinedClass());
+ } else {
+ assertEquals("Expected the inner runnable class.", run.getClass(), wovenClass.getDefinedClass());
+ }
+ }
+ }
+
public void testLoaderUninstalledBundle() throws BundleException, IOException {
String testResourcePath = "testResource";
File config = OSGiTestsActivator.getContext().getDataFile(getName()); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java
index 56d2b76e1..d342e8ecd 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2016 IBM Corporation and others.
+ * Copyright (c) 2013, 2017 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
@@ -32,6 +32,8 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
private static final String HOOK_CONFIGURATOR_CLASS = "org.eclipse.osgi.tests.classloader.hooks.a.TestHookConfigurator";
private static final String REJECT_PROP = "classloader.hooks.a.reject";
private static final String BAD_TRANSFORM_PROP = "classloader.hooks.a.bad.transform";
+ private static final String RECURSION_LOAD = "classloader.hooks.a.recursion.load";
+ private static final String RECURSION_LOAD_SUPPORTED = "classloader.hooks.a.recursion.load.supported";
private Map<String, String> configuration;
private Framework framework;
@@ -41,6 +43,8 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
super.setUp();
setRejectTransformation(false);
setBadTransform(false);
+ setRecursionLoad(false);
+ setRecursionLoadSupported(false);
String loc = bundleInstaller.getBundleLocation(HOOK_CONFIGURATOR_BUNDLE);
loc = loc.substring(loc.indexOf("file:"));
classLoader.addURL(new URL(loc));
@@ -65,7 +69,7 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
return framework.getBundleContext().installBundle(location);
}
- private void setRejectTransformation(boolean value) throws Exception {
+ private void setRejectTransformation(boolean value) {
System.setProperty(REJECT_PROP, Boolean.toString(value));
}
@@ -73,6 +77,14 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
System.setProperty(BAD_TRANSFORM_PROP, Boolean.toString(value));
}
+ private void setRecursionLoad(boolean value) {
+ System.setProperty(RECURSION_LOAD, Boolean.toString(value));
+ }
+
+ private void setRecursionLoadSupported(boolean value) {
+ System.setProperty(RECURSION_LOAD_SUPPORTED, Boolean.toString(value));
+ }
+
public void testRejectTransformationFromWeavingHook() throws Exception {
setRejectTransformation(true);
initAndStartFramework();
@@ -95,6 +107,7 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
refreshBundles(Collections.singleton(b));
try {
b.loadClass(TEST_CLASSNAME);
+ fail("Expected a ClassFormatError.");
} catch (ClassFormatError e) {
// expected
}
@@ -115,11 +128,27 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
refreshBundles(Collections.singleton(b));
try {
b.loadClass(TEST_CLASSNAME);
+ fail("Expected a ClassFormatError.");
} catch (ClassFormatError e) {
// expected
}
}
+ public void testRecursionFromClassLoadingHookNotSupported() throws Exception {
+ setRecursionLoad(true);
+ initAndStartFramework();
+ Bundle b = installBundle();
+ b.loadClass(TEST_CLASSNAME);
+ }
+
+ public void testRecursionFromClassLoadingHookIsSupported() throws Exception {
+ setRecursionLoad(true);
+ setRecursionLoadSupported(true);
+ initAndStartFramework();
+ Bundle b = installBundle();
+ b.loadClass(TEST_CLASSNAME);
+ }
+
private void refreshBundles(Collection<Bundle> bundles) throws InterruptedException {
final CountDownLatch refreshSignal = new CountDownLatch(1);
framework.adapt(FrameworkWiring.class).refreshBundles(bundles, new FrameworkListener() {

Back to the top