From 3abb7d44e251e90572583d096d71b03b24941239 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 4 Sep 2008 18:59:58 +0000 Subject: Bug 246132 Refactor loader layer --- .../buddy/dependent/a/test1/ATest.java | 15 +++ .../buddy.dependent.a.test1/resources/test1.txt | 1 + .../buddy/dependent/a/test2/ATest.java | 15 +++ .../buddy.dependent.a.test2/resources/test2.txt | 1 + .../buddy/registered/a/test1/ATest.java | 15 +++ .../buddy.registered.a.test1/resources/test1.txt | 1 + .../buddy/registered/a/test2/ATest.java | 15 +++ .../buddy.registered.a.test2/resources/test2.txt | 1 + .../tests/bundles/ClassLoadingBundleTests.java | 114 +++++++++++++++++++++ .../osgi/internal/loader/buddy/PolicyHandler.java | 41 +++++--- 10 files changed, 205 insertions(+), 14 deletions(-) create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/buddy/dependent/a/test1/ATest.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/resources/test1.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/buddy/dependent/a/test2/ATest.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/resources/test2.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/buddy/registered/a/test1/ATest.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/resources/test1.txt create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/buddy/registered/a/test2/ATest.java create mode 100644 bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/resources/test2.txt diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/buddy/dependent/a/test1/ATest.java b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/buddy/dependent/a/test1/ATest.java new file mode 100644 index 000000000..6709bc4f8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/buddy/dependent/a/test1/ATest.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2008 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 buddy.dependent.a.test1; + +public class ATest { + +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/resources/test1.txt b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/resources/test1.txt new file mode 100644 index 000000000..6bddbfe0e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test1/resources/test1.txt @@ -0,0 +1 @@ +buddy.dependent.a.test1 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/buddy/dependent/a/test2/ATest.java b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/buddy/dependent/a/test2/ATest.java new file mode 100644 index 000000000..6eac55867 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/buddy/dependent/a/test2/ATest.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2008 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 buddy.dependent.a.test2; + +public class ATest { + +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/resources/test2.txt b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/resources/test2.txt new file mode 100644 index 000000000..d629a675a --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.dependent.a.test2/resources/test2.txt @@ -0,0 +1 @@ +buddy.dependent.a.test2 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/buddy/registered/a/test1/ATest.java b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/buddy/registered/a/test1/ATest.java new file mode 100644 index 000000000..195d5533f --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/buddy/registered/a/test1/ATest.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2008 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 buddy.registered.a.test1; + +public class ATest { + +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/resources/test1.txt b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/resources/test1.txt new file mode 100644 index 000000000..ac6c0131e --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test1/resources/test1.txt @@ -0,0 +1 @@ +buddy.registered.a.test1 \ No newline at end of file diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/buddy/registered/a/test2/ATest.java b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/buddy/registered/a/test2/ATest.java new file mode 100644 index 000000000..14e3e3c99 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/buddy/registered/a/test2/ATest.java @@ -0,0 +1,15 @@ +/******************************************************************************* + * Copyright (c) 2008 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 buddy.registered.a.test2; + +public class ATest { + +} diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/resources/test2.txt b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/resources/test2.txt new file mode 100644 index 000000000..b23305444 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/buddy.registered.a.test2/resources/test2.txt @@ -0,0 +1 @@ +buddy.registered.a.test2 \ No newline at end of file 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 f7784409e..3eda90872 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 @@ -836,6 +836,62 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { assertTrue("buddy.registered.a.test2", texts.contains("buddy.registered.a.test2")); //$NON-NLS-1$ //$NON-NLS-2$ } + public void testBuddyClassLoadingRegistered2() throws Exception { + Bundle registeredA = installer.installBundle("buddy.registered.a"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {registeredA}); + URL testFile = registeredA.getResource("resources/test1.txt"); //$NON-NLS-1$ + assertNull("test1.txt", testFile); //$NON-NLS-1$ + + testFile = registeredA.getResource("resources/test2.txt"); //$NON-NLS-1$ + assertNull("test2.txt", testFile); //$NON-NLS-1$ + + Bundle registeredATest1 = installer.installBundle("buddy.registered.a.test1"); //$NON-NLS-1$ + Bundle registeredATest2 = installer.installBundle("buddy.registered.a.test2"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {registeredATest1, registeredATest2}); + + testFile = registeredA.getResource("resources/test1.txt"); //$NON-NLS-1$ + assertNotNull("test1.txt", testFile); //$NON-NLS-1$ + assertEquals("buddy.registered.a.test1", "buddy.registered.a.test1", readURL(testFile)); //$NON-NLS-1$ //$NON-NLS-2$ + + testFile = registeredA.getResource("resources/test2.txt"); //$NON-NLS-1$ + assertNotNull("test2.txt", testFile); //$NON-NLS-1$ + assertEquals("buddy.registered.a.test2", "buddy.registered.a.test2", readURL(testFile)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void testBuddyClassLoadingRegistered3() throws Exception { + Bundle registeredA = installer.installBundle("buddy.registered.a"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {registeredA}); + try { + registeredA.loadClass("buddy.registered.a.test1.ATest"); //$NON-NLS-1$ + fail("expected ClassNotFoundException"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + // expected + } + try { + registeredA.loadClass("buddy.registered.a.test2.ATest"); //$NON-NLS-1$ + fail("expected ClassNotFoundException"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + // expected + } + Bundle registeredATest1 = installer.installBundle("buddy.registered.a.test1"); //$NON-NLS-1$ + Bundle registeredATest2 = installer.installBundle("buddy.registered.a.test2"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {registeredATest1, registeredATest2}); + + try { + Class testClass = registeredA.loadClass("buddy.registered.a.test1.ATest"); //$NON-NLS-1$ + assertNotNull("testClass", testClass); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + fail("Unexpected ClassNotFoundException", e); //$NON-NLS-1$ + } + + try { + Class testClass = registeredA.loadClass("buddy.registered.a.test2.ATest"); //$NON-NLS-1$ + assertNotNull("testClass", testClass); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + fail("Unexpected ClassNotFoundException", e); //$NON-NLS-1$ + } + } + public void testBuddyClassLoadingDependent1() throws Exception { Bundle dependentA = installer.installBundle("buddy.dependent.a"); //$NON-NLS-1$ installer.resolveBundles(new Bundle[] {dependentA}); @@ -861,6 +917,64 @@ public class ClassLoadingBundleTests extends AbstractBundleTests { assertTrue("buddy.dependent.a.test2", texts.contains("buddy.dependent.a.test2")); //$NON-NLS-1$ //$NON-NLS-2$ } + public void testBuddyClassLoadingDependent2() throws Exception { + Bundle dependentA = installer.installBundle("buddy.dependent.a"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {dependentA}); + URL testFile = dependentA.getResource("resources/test1.txt"); //$NON-NLS-1$ + assertNull("test1.txt", testFile); //$NON-NLS-1$ + + testFile = dependentA.getResource("resources/test2.txt"); //$NON-NLS-1$ + assertNull("test2.txt", testFile); //$NON-NLS-1$ + + Bundle dependentATest1 = installer.installBundle("buddy.dependent.a.test1"); //$NON-NLS-1$ + Bundle dependentATest2 = installer.installBundle("buddy.dependent.a.test2"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {dependentATest1, dependentATest2}); + + testFile = dependentA.getResource("resources/test1.txt"); //$NON-NLS-1$ + assertNotNull("test1.txt", testFile); //$NON-NLS-1$ + assertEquals("buddy.dependent.a.test1", "buddy.dependent.a.test1", readURL(testFile)); //$NON-NLS-1$ //$NON-NLS-2$ + + testFile = dependentA.getResource("resources/test2.txt"); //$NON-NLS-1$ + assertNotNull("test2.txt", testFile); //$NON-NLS-1$ + assertEquals("buddy.dependent.a.test2", "buddy.dependent.a.test2", readURL(testFile)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + public void testBuddyClassLoadingDependent3() throws Exception { + Bundle dependentA = installer.installBundle("buddy.dependent.a"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {dependentA}); + + try { + dependentA.loadClass("buddy.dependent.a.test1.ATest"); //$NON-NLS-1$ + fail("expected ClassNotFoundException"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + // expected + } + + try { + dependentA.loadClass("buddy.dependent.a.test2.ATest"); //$NON-NLS-1$ + fail("expected ClassNotFoundException"); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + // expected + } + + Bundle dependentATest1 = installer.installBundle("buddy.dependent.a.test1"); //$NON-NLS-1$ + Bundle dependentATest2 = installer.installBundle("buddy.dependent.a.test2"); //$NON-NLS-1$ + installer.resolveBundles(new Bundle[] {dependentATest1, dependentATest2}); + + try { + Class testClass = dependentA.loadClass("buddy.dependent.a.test1.ATest"); //$NON-NLS-1$ + assertNotNull("testClass", testClass); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + fail("Unexpected ClassNotFoundException", e); //$NON-NLS-1$ + } + try { + Class testClass = dependentA.loadClass("buddy.dependent.a.test2.ATest"); //$NON-NLS-1$ + assertNotNull("testClass", testClass); //$NON-NLS-1$ + } catch (ClassNotFoundException e) { + fail("Unexpected ClassNotFoundException", e); //$NON-NLS-1$ + } + } + private String readURL(URL url) throws IOException { StringBuffer sb = new StringBuffer(); BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java index 2bc93c638..99a992f24 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java @@ -30,8 +30,8 @@ public class PolicyHandler implements SynchronousBundleListener { //The loader to which this policy is attached. private final BundleLoader policedLoader; //List of the policies as well as cache for the one that have been created. The size of this array never changes over time. This is why the synchronization is not done when iterating over it. - // @GuardedBy this - Object[] policies = null; + // @GuardedBy (this) + private Object[] policies = null; //Support to cut class / resource loading cycles in the context of one thread. The contained object is a set of classname private final ThreadLocal beingLoaded; @@ -58,6 +58,8 @@ public class PolicyHandler implements SynchronousBundleListener { } private synchronized IBuddyPolicy getPolicyImplementation(int policyOrder) { + if (policyOrder >= policies.length) + return null; if (policies[policyOrder] instanceof String) { String buddyName = (String) policies[policyOrder]; @@ -124,8 +126,11 @@ public class PolicyHandler implements SynchronousBundleListener { return null; Class result = null; - for (int i = 0; i < policies.length && result == null; i++) { - result = getPolicyImplementation(i).loadClass(name); + int policyCount = getPolicyCount(); + for (int i = 0; i < policyCount && result == null; i++) { + IBuddyPolicy policy = getPolicyImplementation(i); + if (policy != null) + result = policy.loadClass(name); } stopLoading(name); return result; @@ -135,11 +140,12 @@ public class PolicyHandler implements SynchronousBundleListener { if (startLoading(name) == false) return null; - if (policies == null) - return null; + int policyCount = getPolicyCount(); URL result = null; - for (int i = 0; i < policies.length && result == null; i++) { - result = getPolicyImplementation(i).loadResource(name); + for (int i = 0; i < policyCount && result == null; i++) { + IBuddyPolicy policy = getPolicyImplementation(i); + if (policy != null) + result = policy.loadResource(name); } stopLoading(name); return result; @@ -149,14 +155,16 @@ public class PolicyHandler implements SynchronousBundleListener { if (startLoading(name) == false) return null; - if (policies == null) - return null; + int policyCount = getPolicyCount();; Vector results = null; - for (int i = 0; i < policies.length; i++) { - Enumeration result = getPolicyImplementation(i).loadResources(name); + for (int i = 0; i < policyCount; i++) { + IBuddyPolicy policy = getPolicyImplementation(i); + if (policy == null) + continue; + Enumeration result = policy.loadResources(name); if (result != null) { if (results == null) - results = new Vector(policies.length); + results = new Vector(policyCount); while (result.hasMoreElements()) { Object url = result.nextElement(); if (!results.contains(url)) //only add if not already added @@ -185,6 +193,10 @@ public class PolicyHandler implements SynchronousBundleListener { ((Set) beingLoaded.get()).remove(name); } + private synchronized int getPolicyCount() { + return policies == null ? 0 : policies.length; + } + public void open(BundleContext context) { context.addBundleListener(this); } @@ -194,8 +206,9 @@ public class PolicyHandler implements SynchronousBundleListener { } public void bundleChanged(BundleEvent event) { - if ((event.getType() & (BundleEvent.RESOLVED | BundleEvent.UNRESOLVED)) != 0) + if ((event.getType() & (BundleEvent.RESOLVED | BundleEvent.UNRESOLVED)) == 0) return; + // reinitialize the policies try { String list = (String) policedLoader.getBundle().getBundleData().getManifest().get(Constants.BUDDY_LOADER); synchronized (this) { -- cgit v1.2.3