Bug 478234 - ResolverHookFactory services are looked up and used during dynamic resolution but the framework is not using doPriv
diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath
index c4bb1a5..7290c97 100644
--- a/bundles/org.eclipse.osgi.tests/.classpath
+++ b/bundles/org.eclipse.osgi.tests/.classpath
@@ -132,5 +132,6 @@
 	<classpathentry kind="src" output="bundle_tests/wrapper.hooks.a" path="bundles_src/wrapper.hooks.a"/>
 	<classpathentry kind="src" output="bundle_tests/test.protocol.handler" path="bundles_src/test.protocol.handler"/>
 	<classpathentry kind="src" output="bundle_tests/test.bug471551" path="bundles_src/test.bug471551"/>
+	<classpathentry kind="src" output="bundle_tests/test.dynamicimport" path="bundles_src/test.dynamicimport"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/bundles/org.eclipse.osgi.tests/build.properties b/bundles/org.eclipse.osgi.tests/build.properties
index 899fea3..a1f5404 100644
--- a/bundles/org.eclipse.osgi.tests/build.properties
+++ b/bundles/org.eclipse.osgi.tests/build.properties
@@ -268,6 +268,8 @@
 manifest.bundle_tests/test.protocol.handler.jar = META-INF/MANIFEST.MF
 source.bundle_tests/test.bug471551.jar = bundles_src/test.bug471551/
 manifest.bundle_tests/test.bug471551.jar = META-INF/MANIFEST.MF
+source.bundle_tests/test.dynamicimport.jar = bundles_src/test.dynamicimport/
+manifest.bundle_tests/test.dynamicimport.jar = META-INF/MANIFEST.MF
 
 jars.compile.order = bundle_tests/ext.framework.b.jar,\
                      osgitests.jar,\
@@ -397,4 +399,5 @@
                      bundle_tests/test.bug449484.jar,\
                      bundle_tests/wrapper.hooks.a.jar,\
                      bundle_tests/test.protocol.handler.jar,\
-                     bundle_tests/test.bug471551.jar
+                     bundle_tests/test.bug471551.jar,\
+                     bundle_tests/test.dynamicimport.jar
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a5462c3
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/META-INF/MANIFEST.MF
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name:  test.dynamicimport
+Bundle-SymbolicName: test.dynamicimport
+Bundle-Version: 1.0.0
+Bundle-Activator: test.dynamicimport.Activator
+Import-Package: org.osgi.framework
+DynamicImport-Package: *
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/test/dynamicimport/Activator.java b/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/test/dynamicimport/Activator.java
new file mode 100644
index 0000000..dcb7d47
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.dynamicimport/test/dynamicimport/Activator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2015 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 test.dynamicimport;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+	public void start(BundleContext context) throws Exception {
+		try {
+			Class.forName("org.osgi.framework.hooks.resolver.ResolverHook");
+			throw new RuntimeException("Should have failed to dynamically import the package.");
+		} catch (ClassNotFoundException e) {
+			// expected because dynamic imports should be filtered out
+		}
+	}
+
+	public void stop(BundleContext context) throws Exception {
+		//nothing
+	}
+
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityManagerTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityManagerTests.java
index 4d3caab..a08eab0 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityManagerTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityManagerTests.java
@@ -19,6 +19,11 @@
 import org.eclipse.osgi.tests.OSGiTestsActivator;
 import org.eclipse.osgi.tests.bundles.AbstractBundleTests;
 import org.osgi.framework.*;
+import org.osgi.framework.hooks.resolver.ResolverHook;
+import org.osgi.framework.hooks.resolver.ResolverHookFactory;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.framework.wiring.*;
+import org.osgi.resource.Namespace;
 import org.osgi.service.condpermadmin.*;
 import org.osgi.service.packageadmin.*;
 import org.osgi.service.permissionadmin.PermissionInfo;
@@ -658,4 +663,86 @@
 		assertEquals("Wrong state for SystemBundle", Bundle.RESOLVED, equinox.getState()); //$NON-NLS-1$
 		assertNull("SecurityManager is not null", System.getSecurityManager()); //$NON-NLS-1$
 	}
+
+	public void testDynamicImportWithSecurity() throws BundleException {
+		File config = OSGiTestsActivator.getContext().getDataFile(getName());
+		Map<String, Object> configuration = new HashMap<String, Object>();
+		configuration.put(Constants.FRAMEWORK_STORAGE, config.getAbsolutePath());
+		configuration.put(Constants.FRAMEWORK_SECURITY, Constants.FRAMEWORK_SECURITY_OSGI);
+		Equinox equinox = new Equinox(configuration);
+		try {
+			equinox.start();
+		} catch (BundleException e) {
+			fail("Failed to start the framework", e); //$NON-NLS-1$
+		}
+
+		BundleContext systemContext = equinox.getBundleContext();
+
+		// register a no-op resolver hook to test security
+		ResolverHookFactory dummyHook = new ResolverHookFactory() {
+
+			@Override
+			public ResolverHook begin(Collection<BundleRevision> triggers) {
+				return new ResolverHook() {
+
+					@Override
+					public void filterResolvable(Collection<BundleRevision> candidates) {
+						// nothing
+					}
+
+					@Override
+					public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
+						// nothing
+					}
+
+					@Override
+					public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
+						// always remove candidates for dynamic import
+						if (PackageNamespace.RESOLUTION_DYNAMIC.equals(requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE))) {
+							candidates.clear();
+						}
+					}
+
+					@Override
+					public void end() {
+						// nothing
+					}
+
+				};
+			}
+		};
+		systemContext.registerService(ResolverHookFactory.class, dummyHook, null);
+
+		assertNotNull("System context is null", systemContext); //$NON-NLS-1$
+		// try installing host and fragment to test bug 245678
+		String testDynamicImportLocation = installer.getBundleLocation("test.dynamicimport"); //$NON-NLS-1$
+		// set the security for the bundle
+		ConditionalPermissionAdmin ca = (ConditionalPermissionAdmin) systemContext.getService(systemContext.getServiceReference(ConditionalPermissionAdmin.class.getName()));
+		ConditionalPermissionUpdate update = ca.newConditionalPermissionUpdate();
+		List rows = update.getConditionalPermissionInfos();
+		rows.add(ca.newConditionalPermissionInfo(null, null, new PermissionInfo[] {allPackagePermission}, ConditionalPermissionInfo.ALLOW));
+		assertTrue("Cannot commit rows", update.commit()); //$NON-NLS-1$
+
+		Bundle testDynamicImport = systemContext.installBundle(testDynamicImportLocation);
+
+		try {
+			testDynamicImport.start();
+		} catch (BundleException e) {
+			fail("Did not start test bundle successfully.", e);
+		}
+
+		// put the framework back to the RESOLVED state
+		try {
+			equinox.stop();
+		} catch (BundleException e) {
+			fail("Unexpected error stopping framework", e); //$NON-NLS-1$
+		}
+		try {
+			equinox.waitForStop(10000);
+		} catch (InterruptedException e) {
+			fail("Unexpected interrupted exception", e); //$NON-NLS-1$
+		}
+		assertEquals("Wrong state for SystemBundle", Bundle.RESOLVED, equinox.getState()); //$NON-NLS-1$
+		assertNull("SecurityManager is not null", System.getSecurityManager()); //$NON-NLS-1$
+	}
 }
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
index c0b7511..ad54396 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/OSGiFrameworkHooks.java
@@ -164,15 +164,21 @@
 			throw new RuntimeException(message, new BundleException(message, BundleException.REJECTED_BY_HOOK, t));
 		}
 
-		private ServiceReferenceImpl<ResolverHookFactory>[] getHookReferences(ServiceRegistry registry, BundleContextImpl context) {
-			try {
-				@SuppressWarnings("unchecked")
-				ServiceReferenceImpl<ResolverHookFactory>[] result = (ServiceReferenceImpl<ResolverHookFactory>[]) registry.getServiceReferences(context, ResolverHookFactory.class.getName(), null, false);
-				return result;
-			} catch (InvalidSyntaxException e) {
-				// cannot happen; no filter
-				return null;
-			}
+		private ServiceReferenceImpl<ResolverHookFactory>[] getHookReferences(final ServiceRegistry registry, final BundleContextImpl context) {
+			return AccessController.doPrivileged(new PrivilegedAction<ServiceReferenceImpl<ResolverHookFactory>[]>() {
+				@Override
+				public ServiceReferenceImpl<ResolverHookFactory>[] run() {
+					try {
+						@SuppressWarnings("unchecked")
+						ServiceReferenceImpl<ResolverHookFactory>[] result = (ServiceReferenceImpl<ResolverHookFactory>[]) registry.getServiceReferences(context, ResolverHookFactory.class.getName(), null, false);
+						return result;
+					} catch (InvalidSyntaxException e) {
+						// cannot happen; no filter
+						return null;
+					}
+				}
+			});
+
 		}
 
 		public ResolverHook begin(Collection<BundleRevision> triggers) {
@@ -192,7 +198,7 @@
 			List<HookReference> hookRefs = refs == null ? Collections.<CoreResolverHookFactory.HookReference> emptyList() : new ArrayList<CoreResolverHookFactory.HookReference>(refs.length);
 			if (refs != null) {
 				for (ServiceReferenceImpl<ResolverHookFactory> hookRef : refs) {
-					ResolverHookFactory factory = context.getService(hookRef);
+					ResolverHookFactory factory = EquinoxContainer.secureAction.getService(hookRef, context);
 					if (factory != null) {
 						try {
 							ResolverHook hook = factory.begin(triggers);