Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-02-15 15:41:54 +0000
committerThomas Watson2019-02-15 16:43:17 +0000
commit9e200a3c15f8161fef93b241012ecb3d0f1f1b7d (patch)
treee0a86411948a370e61ce2f8f17203afc4807a417
parent27e73a64c9a38f98b23838f2279c227238541f09 (diff)
downloadrt.equinox.framework-9e200a3c15f8161fef93b241012ecb3d0f1f1b7d.tar.gz
rt.equinox.framework-9e200a3c15f8161fef93b241012ecb3d0f1f1b7d.tar.xz
rt.equinox.framework-9e200a3c15f8161fef93b241012ecb3d0f1f1b7d.zip
Bug 544477 - allow hook to prevent resource load
Change-Id: I6286f7b427d54ad0f3961bd2b21658cb573552d7 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/classloader.hooks.a/org/eclipse/osgi/tests/classloader/hooks/a/TestHookConfigurator.java18
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/ClassLoaderHookTests.java31
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/ClassLoaderHook.java18
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java23
4 files changed, 78 insertions, 12 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 61e86e9a0..0daec7d29 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
@@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.osgi.tests.classloader.hooks.a;
+import java.net.URL;
+import java.util.NoSuchElementException;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.internal.hookregistry.ClassLoaderHook;
import org.eclipse.osgi.internal.hookregistry.HookConfigurator;
@@ -27,6 +29,8 @@ public class TestHookConfigurator implements HookConfigurator {
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 static final String FILTER_CLASS_PATHS = "classloader.hooks.a.filter.class.paths";
+ private static final String PREVENT_RESOURCE_LOAD_PRE = "classloader.hooks.a.fail.resource.load.pre";
+ private static final String PREVENT_RESOURCE_LOAD_POST = "classloader.hooks.a.fail.resource.load.post";
final ThreadLocal<Boolean> doingRecursionLoad = new ThreadLocal<Boolean>() {
protected Boolean initialValue() {
return false;
@@ -81,6 +85,20 @@ public class TestHookConfigurator implements HookConfigurator {
}
return super.getClassPathEntries(name, manager);
}
+
+ @Override
+ public void preFindLocalResource(String name, ClasspathManager manager) {
+ if (Boolean.getBoolean(PREVENT_RESOURCE_LOAD_PRE)) {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
+ if (Boolean.getBoolean(PREVENT_RESOURCE_LOAD_POST)) {
+ throw new NoSuchElementException();
+ }
+ }
});
}
}
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 131d77a03..3185a16c9 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
@@ -37,6 +37,7 @@ import org.osgi.framework.wiring.FrameworkWiring;
public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
private static final String TEST_BUNDLE = "substitutes.a";
private static final String TEST_CLASSNAME = "substitutes.x.Ax";
+ private static final String TEST_CLASSNAME_RESOURCE = "substitutes/x/Ax.class";
private static final String HOOK_CONFIGURATOR_BUNDLE = "classloader.hooks.a";
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";
@@ -44,6 +45,8 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
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 static final String FILTER_CLASS_PATHS = "classloader.hooks.a.filter.class.paths";
+ private static final String PREVENT_RESOURCE_LOAD_PRE = "classloader.hooks.a.fail.resource.load.pre";
+ private static final String PREVENT_RESOURCE_LOAD_POST = "classloader.hooks.a.fail.resource.load.post";
private Map<String, String> configuration;
private Framework framework;
@@ -56,6 +59,8 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
setRecursionLoad(false);
setRecursionLoadSupported(false);
setFilterClassPaths(false);
+ setPreventResourceLoadPre(false);
+ setPreventResourceLoadPost(false);
String loc = bundleInstaller.getBundleLocation(HOOK_CONFIGURATOR_BUNDLE);
loc = loc.substring(loc.indexOf("file:"));
classLoader.addURL(new URL(loc));
@@ -100,6 +105,14 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
System.setProperty(FILTER_CLASS_PATHS, Boolean.toString(value));
}
+ private void setPreventResourceLoadPre(boolean value) {
+ System.setProperty(PREVENT_RESOURCE_LOAD_PRE, Boolean.toString(value));
+ }
+
+ private void setPreventResourceLoadPost(boolean value) {
+ System.setProperty(PREVENT_RESOURCE_LOAD_POST, Boolean.toString(value));
+ }
+
public void testRejectTransformationFromWeavingHook() throws Exception {
setRejectTransformation(true);
initAndStartFramework();
@@ -193,4 +206,22 @@ public class ClassLoaderHookTests extends AbstractFrameworkHookTests {
// expected
}
}
+
+ public void testPreventResourceLoadFromClassLoadingHook() throws Exception {
+ setPreventResourceLoadPre(false);
+ setPreventResourceLoadPost(false);
+ initAndStartFramework();
+ Bundle b = installBundle();
+ URL resource = b.getResource(TEST_CLASSNAME_RESOURCE);
+ assertNotNull("Could not find resource.", resource);
+
+ setPreventResourceLoadPre(true);
+ resource = b.getResource(TEST_CLASSNAME_RESOURCE);
+ assertNull("Could find resource.", resource);
+
+ setPreventResourceLoadPre(false);
+ setPreventResourceLoadPost(true);
+ resource = b.getResource(TEST_CLASSNAME_RESOURCE);
+ assertNull("Could find resource.", resource);
+ }
}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/ClassLoaderHook.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/ClassLoaderHook.java
index 557544b60..8e0a52949 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/ClassLoaderHook.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/hookregistry/ClassLoaderHook.java
@@ -18,6 +18,7 @@ import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.NoSuchElementException;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.loader.ModuleClassLoader;
@@ -61,7 +62,7 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager when looking for ClasspathEntry objects. This method allows
- * a classloading hook to add additional ClasspathEntry objects
+ * a class loading hook to add additional ClasspathEntry objects
* @param cpEntries the list of ClasspathEntry objects currently available for the requested classpath
* @param cp the name of the requested classpath
* @param hostmanager the classpath manager the requested ClasspathEntry is for
@@ -223,7 +224,7 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} before
* searching the local classloader for a class. A classpath manager will call this method for
- * each configured class loading stat hook.
+ * each configured class loading hook.
* @param name the name of the requested class
* @param manager the classpath manager used to find and load the requested class
* @throws ClassNotFoundException to prevent the requested class from loading
@@ -235,11 +236,12 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager during {@link ClasspathManager#findLocalClass(String)} after
* searching the local classloader for a class. A classpath manager will call this method for
- * each configured class loading stat hook.
+ * each configured class loading hook.
* @param name the name of the requested class
* @param clazz the loaded class or null if not found
* @param manager the classpath manager used to find and load the requested class
- * @throws ClassNotFoundException
+ * @throws ClassNotFoundException to prevent the requested class from loading. This is highly discouraged
+ * because if the class is non-null it is already too late to throw an exception.
*/
public void postFindLocalClass(String name, Class<?> clazz, ClasspathManager manager) throws ClassNotFoundException {
// do nothing
@@ -248,9 +250,10 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} before
* searching the local classloader for a resource. A classpath manager will call this method for
- * each configured class loading stat hook.
+ * each configured class loading hook.
* @param name the name of the requested resource
* @param manager the classpath manager used to find the requested resource
+ * @throws NoSuchElementException will prevent the local resource from loading
*/
public void preFindLocalResource(String name, ClasspathManager manager) {
// do nothing
@@ -259,10 +262,11 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager during {@link ClasspathManager#findLocalResource(String)} after
* searching the local classloader for a resource. A classpath manager will call this method for
- * each configured class loading stat hook.
+ * each configured class loading hook.
* @param name the name of the requested resource
* @param resource the URL to the requested resource or null if not found
* @param manager the classpath manager used to find the requested resource
+ * @throws NoSuchElementException will prevent the local resource from loading
*/
public void postFindLocalResource(String name, URL resource, ClasspathManager manager) {
// do nothing
@@ -270,7 +274,7 @@ public abstract class ClassLoaderHook {
/**
* Gets called by a classpath manager after an attempt is made to define a class. This method allows
- * a class loading stat hook to record data about a class definition.
+ * a class loading hook to record data about a class definition.
* @param name the name of the class that got defined
* @param clazz the class object that got defined or null if an error occurred while defining a class
* @param classbytes the class bytes used to define the class
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
index af0115e47..dc6ea5bb1 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/classpath/ClasspathManager.java
@@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.ListIterator;
+import java.util.NoSuchElementException;
import org.eclipse.osgi.container.Module;
import org.eclipse.osgi.container.ModuleCapability;
import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent;
@@ -357,18 +358,30 @@ public class ClasspathManager {
*/
public URL findLocalResource(String resource) {
List<ClassLoaderHook> hooks = hookRegistry.getClassLoaderHooks();
+ boolean hookFailed = false;
for (ClassLoaderHook hook : hooks) {
- hook.preFindLocalResource(resource, this);
+ try {
+ hook.preFindLocalResource(resource, this);
+ } catch (NoSuchElementException e) {
+ // mark the resource load as failed, but continue to all the hooks
+ hookFailed = true;
+ }
}
URL result = null;
try {
- result = findLocalResourceImpl(resource, -1);
- return result;
+ if (!hookFailed) {
+ result = findLocalResourceImpl(resource, -1);
+ }
} finally {
for (ClassLoaderHook hook : hooks) {
- hook.postFindLocalResource(resource, result, this);
+ try {
+ hook.postFindLocalResource(resource, result, this);
+ } catch (NoSuchElementException e) {
+ result = null;
+ }
}
}
+ return result;
}
private URL findLocalResourceImpl(String resource, int classPathIndex) {
@@ -431,7 +444,7 @@ public class ClasspathManager {
ClasspathEntry[] hookEntries = hook.getClassPathEntries(resource, this);
if (hookEntries != null) {
findLocalResources(resource, hookEntries, m, classPathIndex, resources);
- return resources.size() > 0 ? Collections.enumeration(resources): EMPTY_ENUMERATION;
+ return resources.size() > 0 ? Collections.enumeration(resources) : EMPTY_ENUMERATION;
}
}

Back to the top