Make extension bundles use the system bundle context and clean-up some of the code around extension bundles. Furthermore, refactor the protection domain assignment to make it possible to hook into it via an extension bundle. (FELIX-30)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@618095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index e039b53..40112d5 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -448,13 +448,6 @@
                 case Bundle.STOPPING:
                     return;
             }
-
-            // As an exception we allow extension bundles to use their bundle
-            // context while not being active.
-            if (m_bundle.getInfo().isExtension())
-            {
-                return;
-            }
         }
 
         throw new IllegalStateException("Invalid BundleContext.");
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 71d1e61..3cd685a 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -405,6 +405,6 @@
 
     Object getSignerMatcher()
     {
-        return null;
+        return m_felix.getSignerMatcher(this);
     }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleInfo.java b/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
index 1f3aaeb..214e9a7 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
@@ -20,6 +20,7 @@
 
 import java.io.IOException;
 import java.net.URL;
+import java.security.ProtectionDomain;
 import java.util.*;
 
 import org.apache.felix.framework.cache.BundleArchive;
@@ -37,7 +38,7 @@
     private BundleContext m_context = null;
     private Map m_cachedHeaders = new HashMap();
     private long m_cachedHeadersTimestamp;
-
+    
     // Indicates whether the bundle is stale, meaning that it has
     // been refreshed and completely removed from the framework.
     private boolean m_stale = false;
@@ -532,4 +533,22 @@
         m_lockCount = info.m_lockCount;
         m_lockThread = info.m_lockThread;
     }
+    
+    public synchronized void setProtectionDomain(ProtectionDomain pd)
+    {
+        getCurrentModule().getContentLoader().setSecurityContext(pd);
+    }
+    
+    public synchronized ProtectionDomain getProtectionDomain()
+    {
+        ProtectionDomain pd = null;
+        
+        for (int i = m_modules.length - 1; (i >= 0) && (pd == null); i--)
+        {
+            pd = (ProtectionDomain) 
+                m_modules[i].getContentLoader().getSecurityContext();
+        }
+        
+        return pd;
+    }
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
new file mode 100644
index 0000000..4166895
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/BundleProtectionDomain.java
@@ -0,0 +1,37 @@
+package org.apache.felix.framework;
+
+import java.security.Permission;
+import java.security.ProtectionDomain;
+
+class BundleProtectionDomain extends ProtectionDomain
+{
+    private final Felix m_felix;
+    private final FelixBundle m_bundle;
+
+    public BundleProtectionDomain(Felix felix, FelixBundle bundle)
+    {
+        super(null, null);
+        m_felix = felix;
+        m_bundle = bundle;
+    }
+
+    public boolean implies(Permission permission)
+    {
+        return m_felix.impliesBundlePermission(this, permission, false);
+    }
+
+    FelixBundle getBundle()
+    {
+        return m_bundle;
+    }
+
+    public int hashCode()
+    {
+        return m_bundle.hashCode();
+    }
+
+    public boolean equals(Object other)
+    {
+        return m_bundle.equals(other);
+    }
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
index 78186bc..c7fdce9 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -25,7 +25,6 @@
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
 import java.security.AllPermission;
-import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -112,10 +111,11 @@
     private Set m_exportNames = null;
     private ISearchPolicy m_searchPolicy = null;
     private IURLPolicy m_urlPolicy = null;
+    private Object m_securityContext = null;
     private final List m_extensions;
     private final Set m_names;
     private final Map m_sourceToExtensions;
-    
+
     // This constructor is only used for the private instance added to the parent
     // classloader.
     private ExtensionManager()
@@ -124,7 +124,7 @@
         m_names = new HashSet();
         m_sourceToExtensions = new HashMap();
     }
-    
+
     /**
      * This constructor is used to create one instance per framework instance.
      * The general approach is to have one private static instance that we register 
@@ -180,6 +180,16 @@
         }
     }
 
+    public synchronized Object getSecurityContext()
+    {
+        return m_securityContext;
+    }
+
+    public synchronized void setSecurityContext(Object securityContext)
+    {
+        m_securityContext = securityContext;
+    }
+
     /**
      * Check whether the given manifest headers are from an extension bundle.
      */
@@ -187,7 +197,7 @@
     {
         R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
             headers.get(Constants.FRAGMENT_HOST));
-    
+
         return (dir != null) && (Constants.EXTENSION_FRAMEWORK.equals(
             dir.getValue()) || Constants.EXTENSION_BOOTCLASSPATH.equals(
             dir.getValue()));
@@ -216,21 +226,15 @@
             ((SecurityManager) sm).checkPermission(
                 new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
         }
-    
-        ProtectionDomain pd = (ProtectionDomain)
-        bundle.getInfo().getCurrentModule().getSecurityContext();
-    
-        if (pd != null)
+
+        if (!bundle.getInfo().getProtectionDomain().implies(new AllPermission()))
         {
-            if (!pd.implies(new AllPermission()))
-            {
-                throw new SecurityException("Extension Bundles must have AllPermission");
-            }
+            throw new SecurityException("Extension Bundles must have AllPermission");
         }
-    
+
         R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
             bundle.getInfo().getCurrentHeader().get(Constants.FRAGMENT_HOST));
-    
+
         // We only support classpath extensions (not bootclasspath).
         if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
         {
@@ -238,17 +242,17 @@
                 dir.getValue(), new UnsupportedOperationException(
                 "Unsupported Extension Bundle type!"));
         }
-    
+
         // Not sure whether this is a good place to do it but we need to lock
         felix.acquireBundleLock(felix);
-    
+
         try
         {
             bundle.getInfo().setExtension(true);
-    
+
             SystemBundleArchive systemArchive =
                 (SystemBundleArchive) felix.getInfo().getArchive();
-        
+
             // Merge the exported packages with the exported packages of the systembundle.
             Map headers = null;
             ICapability[] exports = null;
@@ -265,7 +269,7 @@
                     + bundle.getInfo().getCurrentHeader().get(Constants.EXPORT_PACKAGE), ex);
                 return;
             }
-        
+
             // Add the bundle as extension if we support extensions
             if (m_extensionManager != null) 
             {
@@ -318,17 +322,21 @@
                 BundleActivator activator = (BundleActivator)
                     felix.getClass().getClassLoader().loadClass(
                         activatorClass.trim()).newInstance();
+                
                 felix.m_activatorList.add(activator);
-                if (felix.m_activatorContextMap == null)
+                
+                BundleContext context = m_systemBundleInfo.getBundleContext();
+                
+                bundle.getInfo().setBundleContext(context);
+                
+                if (felix.getInfo().getState() == Bundle.ACTIVE)
                 {
-                    felix.m_activatorContextMap = new HashMap();
+                    Felix.m_secureAction.startActivator(activator, context);
                 }
-                BundleContext context = new BundleContextImpl(m_logger, felix, bundle);
-                felix.m_activatorContextMap.put(activator, context);
-                Felix.m_secureAction.startActivator(activator, context);
             }
             catch (Throwable ex)
             {
+                ex.printStackTrace();
                 m_logger.log(Logger.LOG_WARNING,
                     "Unable to start Felix Extension Activator", ex);
             }
@@ -363,7 +371,7 @@
         m_capabilities = capabilities;
 
         Map map = ((SystemBundleArchive) m_systemBundleInfo.getArchive()).getManifestHeader(0);
-        map.put(FelixConstants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(map));
+        map.put(Constants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(map));
         ((SystemBundleArchive) m_systemBundleInfo.getArchive()).setManifestHeader(map);
     }
 
@@ -490,12 +498,12 @@
         return null;
     }
 
-    public boolean hasInputStream(int index, String urlPath) throws IOException
+    public boolean hasInputStream(int index, String urlPath)
     {
         return (getClass().getClassLoader().getResource(urlPath) != null);
     }
 
-    public InputStream getInputStream(int index, String urlPath) throws IOException
+    public InputStream getInputStream(int index, String urlPath)
     {
         return getClass().getClassLoader().getResourceAsStream(urlPath);
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index b687ff7..c528733 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -21,10 +21,10 @@
 import java.io.*;
 import java.net.*;
 import java.security.*;
-import java.security.cert.Certificate;
 import java.util.*;
 
 import org.apache.felix.framework.cache.*;
+import org.apache.felix.framework.ext.SecurityProvider;
 import org.apache.felix.framework.searchpolicy.*;
 import org.apache.felix.framework.util.*;
 import org.apache.felix.framework.util.manifestparser.*;
@@ -89,7 +89,6 @@
     private BundleInfo m_systemBundleInfo = null;
     // System bundle activator list.
     List m_activatorList = null;
-    Map m_activatorContextMap = null;
 
     // Next available bundle identifier.
     private long m_nextId = 1L;
@@ -218,7 +217,7 @@
         m_configMutableMap = (configMutableMap == null)
             ? new StringMap(false) : configMutableMap;
         m_configMap = createUnmodifiableMap(m_configMutableMap);
-        m_activatorList = activatorList;
+        m_activatorList = (activatorList == null) ? new ArrayList() : activatorList;
 
         // Create logger with appropriate log level. Even though the
         // logger needs the system bundle's context for tracking log
@@ -570,6 +569,11 @@
     {
         return true;
     }
+    
+    Object getSignerMatcher()
+    {
+        return null;
+    }
 
     public Class loadClass(String name) throws ClassNotFoundException
     {
@@ -721,12 +725,27 @@
         m_factory.setContentLoader(
             m_systemBundleInfo.getCurrentModule(),
             cl);
-        m_factory.setSecurityContext(
-            m_systemBundleInfo.getCurrentModule(),
-            getClass().getProtectionDomain());
 
+        addSecurity(this);
+
+        // Note: we need this ordering to launch:
+        // 1) create all stuff of the system bundle (extension manager needs it)
+        // 2) install all bundles from cache (will start extension bundles)
+        // 3) start the system bundle (will start custom activators)
+        // 4) start the other bundles via the start level
+        // it is important to keep this order because bundles are installed 
+        // from added activators in step 3 and extension bundles are started 
+        // in 2 and need the stuff from 1. 
         m_installedBundleMap.put(
             m_systemBundleInfo.getLocation(), this);
+
+        // Create system bundle activator.
+        m_systemBundleInfo.setActivator(new SystemBundleActivator());
+
+        // Create the bundle context for the system bundle and
+        // then activate it.
+        m_systemBundleInfo.setBundleContext(
+            new BundleContextImpl(m_logger, this, this));
         
         FelixBundle bundle = null;
 
@@ -817,14 +836,7 @@
                     "Unresolved package in System Bundle:"
                     + ex.getRequirement());
             }
-
-            // Create system bundle activator.
-            m_systemBundleInfo.setActivator(new SystemBundleActivator());
-
-            // Create the bundle context for the system bundle and
-            // then activate it.
-            m_systemBundleInfo.setBundleContext(
-                new BundleContextImpl(m_logger, this, this));
+            
             Felix.m_secureAction.startActivator(m_systemBundleInfo.getActivator(), 
                 m_systemBundleInfo.getBundleContext());
         }
@@ -1432,9 +1444,10 @@
             try
             {
                 return (obj instanceof java.security.Permission)
-                    ? ((ProtectionDomain)
-                    bundle.getInfo().getCurrentModule().getSecurityContext())
-                    .implies((java.security.Permission) obj)
+                    ? impliesBundlePermission(
+                    (BundleProtectionDomain) 
+                    bundle.getInfo().getProtectionDomain(), 
+                    (java.security.Permission) obj, true)
                     : false;
             }
             catch (Exception ex)
@@ -1637,8 +1650,7 @@
         // to import the necessary packages.
         if (System.getSecurityManager() != null)
         {
-            ProtectionDomain pd = (ProtectionDomain)
-                bundle.getInfo().getCurrentModule().getSecurityContext();
+            ProtectionDomain pd = bundle.getInfo().getProtectionDomain();
 
             IRequirement[] imports =
                 bundle.getInfo().getCurrentModule().getDefinition().getRequirements();
@@ -1784,20 +1796,21 @@
                         info.getBundleId(),
                         archive.getRevisionCount() - 1,
                         info.getCurrentHeader(),
-                        createBundleProtectionDomain(archive),
-                        bundle.getInfo().isExtension() || m_extensionManager.isExtensionBundle(
-                            bundle.getInfo().getCurrentHeader()));
+                        (bundle.getInfo().isExtension() || 
+                        m_extensionManager.isExtensionBundle(
+                            bundle.getInfo().getCurrentHeader())));
 
                     // Add module to bundle info.
                     info.addModule(module);
 
                     // If this is an update from a normal to an extension bundle
                     // then attach the extension or else if this already is
-                    // an extension bundle then done allow it to be resolved
+                    // an extension bundle then dont allow it to be resolved
                     // again as per spec.
                     if (!bundle.getInfo().isExtension() &&
                         m_extensionManager.isExtensionBundle(bundle.getInfo().getCurrentHeader()))
                     {
+                        addSecurity(bundle);
                         m_extensionManager.addExtensionBundle(this, bundle);
                         m_factory.refreshModule(m_systemBundleInfo.getCurrentModule());
                         bundle.getInfo().setState(Bundle.RESOLVED);
@@ -1806,6 +1819,10 @@
                     {
                         bundle.getInfo().setState(Bundle.INSTALLED);
                     }
+                    else
+                    {
+                        addSecurity(bundle);
+                    }
                 }
                 catch (Throwable ex)
                 {
@@ -2283,6 +2300,8 @@
 
                 verifyExecutionEnvironment(bundle);
 
+                addSecurity(bundle);
+
                 if (!bundle.getInfo().isExtension())
                 {
                     Object sm = System.getSecurityManager();
@@ -2664,7 +2683,7 @@
             BundleInfo info = bundle.getInfo();
 
             // Can only register services if starting or active.
-            if ((info.getState() & (Bundle.STARTING | Bundle.ACTIVE)) == 0)
+            if (((info.getState() & (Bundle.STARTING | Bundle.ACTIVE)) == 0) && !info.isExtension())
             {
                 throw new IllegalStateException(
                     "Can only register services while bundle is active or activating.");
@@ -2842,19 +2861,13 @@
 
     protected File getDataFile(FelixBundle bundle, String s)
     {
-        // The spec says to throw an error if the bundle
-        // is stopped, which I assume means not active,
-        // starting, or stopping.
-        // Additionally, we make an exception for extension bundles
-        if ((bundle.getInfo().getState() != Bundle.ACTIVE) &&
-            (bundle.getInfo().getState() != Bundle.STARTING) &&
-            (bundle.getInfo().getState() != Bundle.STOPPING) &&
-            !bundle.getInfo().isExtension())
-        {
-            throw new IllegalStateException("Only active bundles can create files.");
-        }
         try
         {
+            if (bundle == this)
+            {
+                return m_systemBundleInfo.getArchive().getDataFile(s);
+            }
+            
             return m_cache.getArchive(
                 bundle.getInfo().getBundleId()).getDataFile(s);
         }
@@ -3329,8 +3342,8 @@
         // ever be one revision at this point, create the module for
         // the current revision to be safe.
         IModule module = createModule(
-            archive.getId(), archive.getRevisionCount() - 1, headerMap,
-            createBundleProtectionDomain(archive), isExtension);
+            archive.getId(), archive.getRevisionCount() - 1, headerMap, 
+            isExtension);
 
         // Finally, create an return the bundle info.
         BundleInfo info = new BundleInfo(m_logger, archive, module);
@@ -3339,20 +3352,34 @@
         return info;
     }
 
-    private ProtectionDomain createBundleProtectionDomain(BundleArchive archive)
-        throws Exception
-    {
-// TODO: Security - create a real ProtectionDomain for the Bundle
-        FakeURLStreamHandler handler = new FakeURLStreamHandler();
-        URL context = new URL(null, "location:", handler);
-        CodeSource codesource = new CodeSource(m_secureAction.createURL(context,
-            archive.getLocation(), handler), (Certificate[]) null);
+    private volatile SecurityProvider m_securityProvider;
 
-        Permissions allPerms = new Permissions();
-        allPerms.add(new AllPermission());
-        ProtectionDomain pd = new ProtectionDomain(codesource,
-            allPerms);
-        return pd;
+    void setSecurityProvider(SecurityProvider securityProvider)
+    {
+        m_securityProvider = securityProvider;
+    }
+
+    Object getSignerMatcher(FelixBundle bundle)
+    {
+        if (m_securityProvider != null)
+        {
+            return m_securityProvider.getSignerMatcher(bundle);
+        }
+        return null;
+    }
+
+    boolean impliesBundlePermission(BundleProtectionDomain bundleProtectionDomain, Permission permission, boolean direct)
+    {
+        if (m_securityProvider != null)
+        {
+            return m_securityProvider.hasBundlePermission(bundleProtectionDomain, permission, direct);
+        }
+        return true;
+    }
+
+    void addSecurity(final FelixBundle bundle)
+    {
+        bundle.getInfo().setProtectionDomain(new BundleProtectionDomain(this, bundle));
     }
 
     /**
@@ -3365,8 +3392,7 @@
      * @return The initialized and/or newly created module.
     **/
     private IModule createModule(long targetId, int revision, Map headerMap,
-        Object securityContext, boolean isExtensionBundle)
-        throws Exception
+        boolean isExtensionBundle) throws Exception
     {
         ManifestParser mp = new ManifestParser(m_logger, m_configMap, headerMap);
 
@@ -3412,14 +3438,11 @@
         IModule module = m_factory.createModule(
             Long.toString(targetId) + "." + Integer.toString(revision), md);
 
-        m_factory.setSecurityContext(module, securityContext);
-
         // Create the content loader from the module archive.
         IContentLoader contentLoader = new ContentLoaderImpl(
                 m_logger,
                 m_cache.getArchive(targetId).getRevision(revision).getContent(),
-                m_cache.getArchive(targetId).getRevision(revision).getContentPath(),
-                (ProtectionDomain) module.getSecurityContext());
+                m_cache.getArchive(targetId).getRevision(revision).getContentPath());
         // Set the content loader's search policy.
         contentLoader.setSearchPolicy(
                 new R4SearchPolicy(m_policyCore, module));
@@ -3752,12 +3775,6 @@
     {
         public void start(BundleContext context) throws Exception
         {
-            // Create an activator list if necessary.
-            if (m_activatorList == null)
-            {
-                m_activatorList = new ArrayList();
-            }
-
             // Add the bundle activator for the package admin service.
             m_activatorList.add(0, new PackageAdminActivator(Felix.this));
             // Add the bundle activator for the start level service.
@@ -3891,17 +3908,8 @@
                 {
                     try
                     {
-                        if ((m_activatorContextMap != null) &&
-                            m_activatorContextMap.containsKey(m_activatorList.get(i)))
-                        {
-                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
-                                (BundleContext) m_activatorContextMap.get(m_activatorList.get(i)));
-                        }
-                        else
-                        {
-                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
-                                getInfo().getBundleContext());
-                        }
+                        Felix.m_secureAction.stopActivator((BundleActivator) 
+                            m_activatorList.get(i), getInfo().getBundleContext());
                     }
                     catch (Throwable throwable)
                     {
@@ -4007,6 +4015,7 @@
                         info.isExtension());
                     newInfo.syncLock(info);
                     ((BundleImpl) m_bundle).setInfo(newInfo);
+                    addSecurity(m_bundle);
                     fireBundleEvent(BundleEvent.UNRESOLVED, m_bundle);
                 }
                 catch (Exception ex)
diff --git a/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java b/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java
new file mode 100644
index 0000000..e35893e
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/ext/SecurityProvider.java
@@ -0,0 +1,13 @@
+package org.apache.felix.framework.ext;
+
+import java.security.Permission;
+import java.security.ProtectionDomain;
+
+import org.osgi.framework.Bundle;
+
+public interface SecurityProvider
+{
+    boolean hasBundlePermission(ProtectionDomain pd, Permission p, boolean direct);
+
+    Object getSignerMatcher(Bundle bundle);
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
index f2f0f14..4d12c90 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ContentLoaderImpl.java
@@ -40,19 +40,12 @@
     private ProtectionDomain m_protectionDomain = null;
     private static SecureAction m_secureAction = new SecureAction();
 
-    public ContentLoaderImpl(Logger logger, IContent content,
+    public ContentLoaderImpl(Logger logger, IContent content, 
         IContent[] contentPath)
     {
-        this(logger, content, contentPath, null);
-    }
-
-    public ContentLoaderImpl(Logger logger, IContent content,
-        IContent[] contentPath, ProtectionDomain protectionDomain)
-    {
         m_logger = logger;
         m_content = content;
         m_contentPath = contentPath;
-        m_protectionDomain = protectionDomain;
     }
 
     public Logger getLogger()
@@ -107,6 +100,16 @@
     {
         return m_urlPolicy;
     }
+    
+    public synchronized void setSecurityContext(Object securityContext)
+    {
+        m_protectionDomain = (ProtectionDomain) securityContext; 
+    }
+
+    public synchronized Object getSecurityContext()
+    {
+        return m_protectionDomain;
+    }
 
     public Class getClass(String name)
     {
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
index af22f6f..dfe6d86 100755
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/R4SearchPolicyCore.java
@@ -859,7 +859,7 @@
                     {
 // TODO: RB - Is this permission check correct.
                         if ((System.getSecurityManager() != null) &&
-                            !((ProtectionDomain) modules[modIdx].getSecurityContext()).implies(
+                            !((ProtectionDomain) modules[modIdx].getContentLoader().getSecurityContext()).implies(
                                 new PackagePermission(pkgName,
                                     PackagePermission.EXPORT)))
                         {
@@ -894,7 +894,7 @@
 // TODO: RB - Is this permission check correct.
                             if (inUseCaps[capIdx].getNamespace().equals(ICapability.PACKAGE_NAMESPACE) &&
                                 (System.getSecurityManager() != null) &&
-                                !((ProtectionDomain) module.getSecurityContext()).implies(
+                                !((ProtectionDomain) module.getContentLoader().getSecurityContext()).implies(
                                     new PackagePermission(
                                         (String) inUseCaps[capIdx].getProperties().get(ICapability.PACKAGE_PROPERTY),
                                         PackagePermission.EXPORT)))
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java b/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
index 8a01119..4420a44 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/IContentLoader.java
@@ -36,6 +36,9 @@
     public void setURLPolicy(IURLPolicy urlPolicy);
     public IURLPolicy getURLPolicy();
 
+    public void setSecurityContext(Object securityContext);
+    public Object getSecurityContext();
+
     public Class getClass(String name);
     public URL getResource(String name);
     public Enumeration getResources(String name);
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IModule.java b/framework/src/main/java/org/apache/felix/moduleloader/IModule.java
index 58cd74a..5987ac8 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IModule.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/IModule.java
@@ -33,6 +33,4 @@
     public Class getClass(String name);
     public URL getResource(String name);
     public Enumeration getResources(String name);
-
-    public Object getSecurityContext();
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/IModuleFactory.java b/framework/src/main/java/org/apache/felix/moduleloader/IModuleFactory.java
index 657c73b..2bb3b3d 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/IModuleFactory.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/IModuleFactory.java
@@ -31,8 +31,6 @@
     public void addModuleListener(ModuleListener l);
     public void removeModuleListener(ModuleListener l);
 
-    public void setSecurityContext(IModule module, Object securityContext);
-
     /**
      * This is an experimental method that is likely to change or go
      * away - so don't use it for now.
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/ModuleFactoryImpl.java b/framework/src/main/java/org/apache/felix/moduleloader/ModuleFactoryImpl.java
index 4487aa2..bd49aa5 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/ModuleFactoryImpl.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/ModuleFactoryImpl.java
@@ -134,14 +134,6 @@
         }
     }
 
-    public void setSecurityContext(IModule module, Object securityContext)
-    {
-        synchronized (this)
-        {
-            ((ModuleImpl) module).setSecurityContext(securityContext);
-        }
-    }
-
     /**
      * <p>
      * Adds a listener to the <tt>IModuleFactory</tt> to listen for
diff --git a/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java b/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
index 6f2d84f..32d50cb 100644
--- a/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/moduleloader/ModuleImpl.java
@@ -32,7 +32,6 @@
     private IContentLoader m_contentLoader = null;
     private IWire[] m_wires = null;
     private IModule[] m_dependents = new IModule[0];
-    private Object m_securityContext = null;
 
     ModuleImpl(Logger logger, String id, IModuleDefinition md)
     {
@@ -61,11 +60,6 @@
         m_contentLoader = contentLoader;
     }
 
-    protected void setSecurityContext(Object securityContext)
-    {
-        m_securityContext = securityContext;
-    }
-
     public synchronized IWire[] getWires()
     {
         return m_wires;
@@ -197,9 +191,4 @@
     {
         return m_id;
     }
-
-    public Object getSecurityContext()
-    {
-        return m_securityContext;
-    }
 }
\ No newline at end of file