You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2013/06/04 10:30:08 UTC

svn commit: r1489332 - /sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java

Author: cziegeler
Date: Tue Jun  4 08:30:07 2013
New Revision: 1489332

URL: http://svn.apache.org/r1489332
Log:
SLING-2617 : Make sure the dynamic class loader used as the parent to the repository class loader is acquired for the same bundle which acquired the ClassLoaderWriter

Modified:
    sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java

Modified: sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java?rev=1489332&r1=1489331&r2=1489332&view=diff
==============================================================================
--- sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java (original)
+++ sling/trunk/contrib/commons/fsclassloader/src/main/java/org/apache/sling/commons/fsclassloader/impl/FSClassLoaderProvider.java Tue Jun  4 08:30:07 2013
@@ -28,12 +28,17 @@ import java.io.OutputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 
+import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.commons.classloader.ClassLoaderWriter;
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
 
 /**
@@ -42,8 +47,8 @@ import org.osgi.service.component.Compon
  *
  */
 @Component
-@Service(value={ClassLoaderWriter.class})
-@Property( name="service.ranking", intValue=100)
+@Service(value={ClassLoaderWriter.class}, serviceFactory = true)
+@Property( name=Constants.SERVICE_RANKING, intValue=100)
 public class FSClassLoaderProvider
     implements ClassLoaderWriter {
 
@@ -56,8 +61,73 @@ public class FSClassLoaderProvider
     /** Current class loader */
     private FSDynamicClassLoader loader;
 
-    @Reference
-    private DynamicClassLoaderManager dynamicClassLoaderManager;
+    @Reference(
+            referenceInterface = DynamicClassLoaderManager.class,
+            bind = "bindDynamicClassLoaderManager",
+            unbind = "unbindDynamicClassLoaderManager")
+    private ServiceReference dynamicClassLoaderManager;
+
+    /** The bundle asking for this service instance */
+    private Bundle callerBundle;
+
+    /**
+     * Activate this component.
+     * Create the root directory.
+     * @param componentContext
+     * @throws MalformedURLException
+     */
+    @Activate
+    protected void activate(final ComponentContext componentContext) throws MalformedURLException {
+        // get the file root
+        this.root = new File(componentContext.getBundleContext().getDataFile(""), "classes");
+        this.root.mkdirs();
+        this.rootURL = this.root.toURI().toURL();
+        this.callerBundle = componentContext.getUsingBundle();
+    }
+
+    /**
+     * Deactivate this component.
+     * Create the root directory.
+     */
+    @Deactivate
+    protected void deactivate() {
+        this.root = null;
+        this.rootURL = null;
+        this.destroyClassLoader();
+    }
+
+    /**
+     * Called to handle binding the DynamicClassLoaderManager service
+     * reference
+     */
+    @SuppressWarnings("unused")
+    private void bindDynamicClassLoaderManager(final ServiceReference ref) {
+        this.dynamicClassLoaderManager = ref;
+    }
+
+    /**
+     * Called to handle unbinding of the DynamicClassLoaderManager service
+     * reference
+     */
+    @SuppressWarnings("unused")
+    private void unbindDynamicClassLoaderManager(final ServiceReference ref) {
+        if (this.dynamicClassLoaderManager == ref) {
+            this.dynamicClassLoaderManager = null;
+        }
+    }
+
+    private void destroyClassLoader() {
+        final ClassLoader rcl = this.loader;
+        if (rcl != null) {
+            this.loader = null;
+
+            final ServiceReference localDynamicClassLoaderManager = this.dynamicClassLoaderManager;
+            final Bundle localCallerBundle = this.callerBundle;
+            if ( localDynamicClassLoaderManager != null && localCallerBundle != null ) {
+                localCallerBundle.getBundleContext().ungetService(localDynamicClassLoaderManager);
+            }
+        }
+    }
 
     /**
      * @see org.apache.sling.commons.classloader.ClassLoaderWriter#getClassLoader()
@@ -65,7 +135,13 @@ public class FSClassLoaderProvider
     public ClassLoader getClassLoader() {
         synchronized ( this ) {
             if ( loader == null || !loader.isLive() ) {
-                loader = new FSDynamicClassLoader(new URL[] {this.rootURL}, this.dynamicClassLoaderManager.getDynamicClassLoader());
+                this.destroyClassLoader();
+                // get the dynamic class loader for the bundle using this
+                // class loader writer
+                final DynamicClassLoaderManager dclm = (DynamicClassLoaderManager) this.callerBundle.getBundleContext().getService(
+                    this.dynamicClassLoaderManager);
+
+                loader = new FSDynamicClassLoader(new URL[] {this.rootURL}, dclm.getDynamicClassLoader());
             }
             return this.loader;
         }
@@ -180,27 +256,4 @@ public class FSClassLoaderProvider
         // fallback to "non-existant" in case of problems
         return -1;
     }
-
-    /**
-     * Activate this component.
-     * Create the root directory.
-     * @param componentContext
-     * @throws MalformedURLException
-     */
-    protected void activate(final ComponentContext componentContext) throws MalformedURLException {
-        // get the file root
-        this.root = new File(componentContext.getBundleContext().getDataFile(""), "classes");
-        this.root.mkdirs();
-        this.rootURL = this.root.toURI().toURL();
-    }
-
-    /**
-     * Deactivate this component.
-     * Create the root directory.
-     * @param componentContext
-     */
-    protected void deactivate(final ComponentContext componentContext) {
-        this.root = null;
-        this.rootURL = null;
-    }
 }