You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:19:27 UTC

[sling-org-apache-sling-commons-classloader] annotated tag org.apache.sling.commons.classloader-0.9.0 created (now 60b8fd1)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git.


      at 60b8fd1  (tag)
 tagging 463e2d7d511d3f3fea78268af03819932ccd54a2 (commit)
      by Carsten Ziegeler
      on Tue Sep 29 13:13:40 2009 +0000

- Log -----------------------------------------------------------------
org.apache.sling.commons.classloader-0.9.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new 046ba4f  SLING-1007 : Initial work of a dynamic class loader loading classes through package admin. In addition dynamic class loader providers can be registered.
     new 5836631  Add simple junit test for dynamic class loading through package admin.
     new ea90c38  Move classloader to main bundle area - as discussed recently
     new 6b8a1f4  Correct activator.
     new 3ffeb64  Ignore target directory.
     new cc3b40d  Fix class cast.
     new 2813fc7  Fix resource handling (packages are separated by a slash not by a dot)
     new 97bcc33  Register classloader as a service factory to get access to the client bundle for class loading.
     new 54194d4  Fix AIOOB
     new c5338c1  forgot to commit test case
     new 8023ea1  Provide parent class loader to dynamic class loader providers; check for null reference.
     new a2ba64a  Experimental class loader writer for scripting engines.
     new ce0fe40  SLING-1070 : Change class loading of package admin class loader to parent first, cache classes and resources in the class loader facade and reregister manager factory, if a used bundle is changed.
     new 3c831d4  Activator must implement BundleActivator
     new bf847ec  Remove duplicate interface
     new 0891b68  Don't cache classes in the facade, cache them in the package admin class loader.
     new a391329  Remove warnings
     new 61594f5  svn:ignore
     new 8dd47bc  Use latest parent pom.
     new 9fc087f  [maven-release-plugin] prepare release org.apache.sling.commons.classloader-0.9.0
     new 463e2d7  [maven-scm] copy for tag org.apache.sling.commons.classloader-0.9.0

The 21 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-commons-classloader] 14/21: Activator must implement BundleActivator

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 3c831d4910e4b499438034eb49cef7cc985ea55a
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Aug 5 12:51:12 2009 +0000

    Activator must implement BundleActivator
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@801199 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/commons/classloader/impl/Activator.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
index 33ea4f5..6cd29d7 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -24,6 +24,7 @@ import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
+import org.osgi.framework.BundleActivator;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.SynchronousBundleListener;
@@ -35,7 +36,7 @@ import org.osgi.util.tracker.ServiceTracker;
  * It listens for bundle events and reregisters the class loader manager
  * if a bundle event for a used bundle occurs.
  */
-public class Activator implements SynchronousBundleListener, BundleListener {
+public class Activator implements SynchronousBundleListener, BundleListener, BundleActivator {
 
     /** Package admin service name */
     private static String PACKAGE_ADMIN_NAME = PackageAdmin.class.getName();

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 17/21: Remove warnings

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit a3913297f54da6e716f4db799e43fe543b6f50f9
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 5 15:29:44 2009 +0000

    Remove warnings
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@801267 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/commons/classloader/impl/ClassLoadingTest.java | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
index e60256f..2c2d5a0 100644
--- a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
+++ b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
@@ -73,12 +73,12 @@ public class ClassLoadingTest {
         DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin, null,
             new DynamicClassLoaderManagerFactory(bundleContext, packageAdmin));
         final ClassLoader cl = manager.getDynamicClassLoader();
-        final Class c1 = cl.loadClass("org.apache.sling.test.A");
+        final Class<?> c1 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c1.getName());
-        final Class c2 = cl.loadClass("org.apache.sling.test.A");
+        final Class<?> c2 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c2.getName());
         // as we cache the result, we still get the map!
-        final Class c3 = cl.loadClass("org.apache.sling.test.A");
+        final Class<?> c3 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c3.getName());
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 16/21: Don't cache classes in the facade, cache them in the package admin class loader.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 0891b6877e340936dc4c2d0aab11cccf485675a1
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 5 15:07:52 2009 +0000

    Don't cache classes in the facade, cache them in the package admin class loader.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@801254 13f79535-47bb-0310-9956-ffa450edef68
---
 .../classloader/impl/ClassLoaderFacade.java        | 19 ----------
 .../classloader/impl/PackageAdminClassLoader.java  | 40 +++++++++++++++++++++-
 2 files changed, 39 insertions(+), 20 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
index d080d67..5b4cd68 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
@@ -21,8 +21,6 @@ package org.apache.sling.commons.classloader.impl;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Enumeration;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 
 /**
@@ -37,12 +35,6 @@ public class ClassLoaderFacade extends ClassLoader {
 
     private final DynamicClassLoaderManagerImpl manager;
 
-    /** A cache for resolved classes. */
-    private Map<String, Class<?>> classCache = new ConcurrentHashMap<String, Class<?>>();
-
-    /** A cache for resolved urls. */
-    private Map<String, URL> urlCache = new ConcurrentHashMap<String, URL>();
-
     public ClassLoaderFacade(final DynamicClassLoaderManagerImpl manager) {
         this.manager = manager;
     }
@@ -54,16 +46,11 @@ public class ClassLoaderFacade extends ClassLoader {
         if ( !this.manager.isActive() ) {
             throw new RuntimeException("Dynamic class loader has already been deactivated.");
         }
-        final URL cachedURL = urlCache.get(name);
-        if ( cachedURL != null ) {
-            return cachedURL;
-        }
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
             if ( cl != null ) {
                 final URL u = cl.getResource(name);
                 if ( u != null ) {
-                    urlCache.put(name, u);
                     return u;
                 }
             }
@@ -97,19 +84,13 @@ public class ClassLoaderFacade extends ClassLoader {
         if ( !this.manager.isActive() ) {
             throw new RuntimeException("Dynamic class loader has already been deactivated.");
         }
-        final Class<?> cachedClass = this.classCache.get(name);
-        if ( cachedClass != null ) {
-            return cachedClass;
-        }
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
             if ( cl != null ) {
                 try {
                     final Class<?> c = cl.loadClass(name);
-                    this.classCache.put(name, c);
                     return c;
                 } catch (Exception cnfe) {
-                    cnfe.printStackTrace();
                     // we just ignore this and try the next class loader
                 }
             }
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
index f27bc8d..d5a3077 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -20,7 +20,12 @@ package org.apache.sling.commons.classloader.impl;
 
 import java.io.IOException;
 import java.net.URL;
+import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.osgi.framework.Bundle;
 import org.osgi.service.packageadmin.ExportedPackage;
@@ -38,6 +43,15 @@ class PackageAdminClassLoader extends ClassLoader {
     /** The manager factory. */
     private final DynamicClassLoaderManagerFactory factory;
 
+    /** A cache for resolved classes. */
+    private Map<String, Class<?>> classCache = new ConcurrentHashMap<String, Class<?>>();
+
+    /** Negative class cache. */
+    private Set<String> negativeClassCache = Collections.synchronizedSet(new HashSet<String>());
+
+    /** A cache for resolved urls. */
+    private Map<String, URL> urlCache = new ConcurrentHashMap<String, URL>();
+
     public PackageAdminClassLoader(final PackageAdmin pckAdmin,
                                    final ClassLoader parent,
                                    final DynamicClassLoaderManagerFactory factory) {
@@ -101,6 +115,10 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#findResource(java.lang.String)
      */
     public URL findResource(String name) {
+        final URL cachedURL = urlCache.get(name);
+        if ( cachedURL != null ) {
+            return cachedURL;
+        }
         URL url = super.findResource(name);
         if ( url == null ) {
             final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
@@ -108,6 +126,7 @@ class PackageAdminClassLoader extends ClassLoader {
                 url = bundle.getResource(name);
                 if ( url != null ) {
                     this.factory.addUsedBundle(bundle);
+                    urlCache.put(name, url);
                 }
             }
         }
@@ -118,6 +137,10 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#findClass(java.lang.String)
      */
     public Class<?> findClass(String name) throws ClassNotFoundException {
+        final Class<?> cachedClass = this.classCache.get(name);
+        if ( cachedClass != null ) {
+            return cachedClass;
+        }
         Class<?> clazz = null;
         try {
             clazz = super.findClass(name);
@@ -131,6 +154,7 @@ class PackageAdminClassLoader extends ClassLoader {
         if ( clazz == null ) {
             throw new ClassNotFoundException("Class not found " + name);
         }
+        this.classCache.put(name, clazz);
         return clazz;
     }
 
@@ -138,19 +162,33 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
      */
     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        final Class<?> cachedClass = this.classCache.get(name);
+        if ( cachedClass != null ) {
+            return cachedClass;
+        }
+        if ( negativeClassCache.contains(name) ) {
+            throw new ClassNotFoundException("Class not found " + name);
+        }
         Class<?> clazz = null;
         try {
             clazz = super.loadClass(name, resolve);
         } catch (ClassNotFoundException cnfe) {
             final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
             if ( bundle != null ) {
-                clazz = bundle.loadClass(name);
+                try {
+                    clazz = bundle.loadClass(name);
+                } catch (ClassNotFoundException inner) {
+                    negativeClassCache.add(name);
+                    throw inner;
+                }
                 this.factory.addUsedBundle(bundle);
             }
         }
         if ( clazz == null ) {
+            negativeClassCache.add(name);
             throw new ClassNotFoundException("Class not found " + name);
         }
+        this.classCache.put(name, clazz);
         return clazz;
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 21/21: [maven-scm] copy for tag org.apache.sling.commons.classloader-0.9.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 463e2d7d511d3f3fea78268af03819932ccd54a2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Sep 29 13:13:40 2009 +0000

    [maven-scm] copy for tag org.apache.sling.commons.classloader-0.9.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.classloader-0.9.0@819928 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 12/21: Experimental class loader writer for scripting engines.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit a2ba64aa4f0828db3e4e281fca0bae327579acb3
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Fri Jul 17 06:16:52 2009 +0000

    Experimental class loader writer for scripting engines.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794977 13f79535-47bb-0310-9956-ffa450edef68
---
 .../commons/classloader/ClassLoaderWriter.java     | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java b/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java
new file mode 100644
index 0000000..b39b746
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * The class loader writer allows to modify the resources loaded by a
+ * {@link DynamicClassLoaderProvider}. For example a class loader writer
+ * could write generated class files into the repository or the temporary
+ * file system.
+ */
+public interface ClassLoaderWriter {
+
+    OutputStream getOutputStream(String name);
+
+    InputStream getInputStream(String name) throws IOException;
+
+    long getLastModified(String name);
+
+    boolean delete(String name);
+
+    boolean rename(String oldName, String newName);
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 13/21: SLING-1070 : Change class loading of package admin class loader to parent first, cache classes and resources in the class loader facade and reregister manager factory, if a used bundle is changed.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit ce0fe406f4b477265a12ebb0cdf5f514e657802f
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Aug 4 14:03:59 2009 +0000

    SLING-1070 : Change class loading of package admin class loader to parent first, cache classes and resources in the class loader facade and reregister manager factory, if a used bundle is changed.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@800803 13f79535-47bb-0310-9956-ffa450edef68
---
 .../commons/classloader/ClassLoaderWriter.java     | 42 ++++++++--
 .../classloader/DynamicClassLoaderManager.java     |  5 ++
 .../sling/commons/classloader/impl/Activator.java  | 54 +++++++++++--
 .../classloader/impl/BundleProxyClassLoader.java   |  2 +
 .../classloader/impl/ClassLoaderFacade.java        | 49 ++++++++----
 .../impl/DynamicClassLoaderManagerFactory.java     | 26 +++++-
 .../impl/DynamicClassLoaderManagerImpl.java        | 21 ++++-
 .../classloader/impl/PackageAdminClassLoader.java  | 92 +++++++++++++++++-----
 .../commons/classloader/impl/ClassLoadingTest.java |  8 +-
 9 files changed, 243 insertions(+), 56 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java b/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java
index b39b746..82e6634 100644
--- a/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java
+++ b/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java
@@ -30,13 +30,45 @@ import java.io.OutputStream;
  */
 public interface ClassLoaderWriter {
 
-    OutputStream getOutputStream(String name);
+    /**
+     * Get the output stream for a class or resource handled
+     * by the underlying class loader.
+     * If the resource/class does not exists it should be created.
+     * @param path The path of the class/resource.
+     * @return The output stream.
+     */
+    OutputStream getOutputStream(String path);
 
-    InputStream getInputStream(String name) throws IOException;
+    /**
+     * Get the input stream for a class or resource handled
+     * by the underlying class loader.
+     * @param path The path of the class/resource.
+     * @return The input stream for the resource/class.
+     * @throws IOException If the resource/class does not exist.
+     */
+    InputStream getInputStream(String path) throws IOException;
 
-    long getLastModified(String name);
+    /**
+     * Return the last modified for the class or resource.
+     * @param path The path of the class/resource.
+     * @return The last modified information or <code>-1</code> if
+     *         the information can't be detected.
+     */
+    long getLastModified(String path);
 
-    boolean delete(String name);
+    /**
+     * Delete the class/resource
+     * @param path The path of the class/resource.
+     * @return <code>true</code> if the resource exists and could be deleted,
+     *     <code>false</code> otherwise.
+     */
+    boolean delete(String path);
 
-    boolean rename(String oldName, String newName);
+    /**
+     * Rename a class/resource.
+     * @param oldPath The path of the class/resource.
+     * @param newPath The new path.
+     * @return <code>true</code> if the renaming has been successful.
+     */
+    boolean rename(String oldPath, String newPath);
 }
diff --git a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java
index ff23e78..25aae5b 100644
--- a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java
+++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java
@@ -24,6 +24,11 @@ package org.apache.sling.commons.classloader;
  * It provides a class loader that can be used by
  * bundles requiring access to all publically available
  * classes.
+ *
+ * The default implementation uses the package admin
+ * service to load classes and resources. The search
+ * path can be extended by providing
+ * {@link DynamicClassLoaderProvider}s.
  */
 public interface DynamicClassLoaderManager {
 
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
index 1ca885e..33ea4f5 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -21,17 +21,21 @@ package org.apache.sling.commons.classloader.impl;
 import java.util.Hashtable;
 
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
-import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.BundleListener;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.SynchronousBundleListener;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.util.tracker.ServiceTracker;
 
 /**
  * This activator registers the dynamic class loader manager.
+ * It listens for bundle events and reregisters the class loader manager
+ * if a bundle event for a used bundle occurs.
  */
-public class Activator implements BundleActivator {
+public class Activator implements SynchronousBundleListener, BundleListener {
 
     /** Package admin service name */
     private static String PACKAGE_ADMIN_NAME = PackageAdmin.class.getName();
@@ -45,26 +49,39 @@ public class Activator implements BundleActivator {
     /** The dynamic class loader service factory. */
     private DynamicClassLoaderManagerFactory service;
 
+    /** The bundle context. */
+    private BundleContext bundleContext;
+
     /**
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
      */
-    public void start(BundleContext context) throws Exception {
-        this.packageAdminTracker = new ServiceTracker(context, PACKAGE_ADMIN_NAME, null);
+    public void start(BundleContext context) {
+        this.bundleContext = context;
+
+        this.packageAdminTracker = new ServiceTracker(this.bundleContext, PACKAGE_ADMIN_NAME, null);
         this.packageAdminTracker.open();
 
         // register service
+        this.registerManagerFactory();
+        this.bundleContext.addBundleListener(this);
+    }
+
+    /**
+     * Register the dynamic class loader manager factory.
+     */
+    protected void registerManagerFactory() {
         final Hashtable<String, String> props = new Hashtable<String, String>();
         props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Dynamic Class Loader Service");
         props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-        this.service = new DynamicClassLoaderManagerFactory(context,
+        this.service = new DynamicClassLoaderManagerFactory(this.bundleContext,
                 (PackageAdmin)this.packageAdminTracker.getService());
-        this.serviceReg = context.registerService(new String[] {DynamicClassLoaderManager.class.getName()}, service, props);
+        this.serviceReg = this.bundleContext.registerService(new String[] {DynamicClassLoaderManager.class.getName()}, service, props);
     }
 
     /**
-     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     * Unregister the dynamic class loader manager factory.
      */
-    public void stop(BundleContext context) throws Exception {
+    protected void unregisterManagerFactory() {
         if ( this.serviceReg != null ) {
             this.serviceReg.unregister();
             this.serviceReg = null;
@@ -72,9 +89,30 @@ public class Activator implements BundleActivator {
         if ( this.service != null ) {
             this.service = null;
         }
+    }
+
+    /**
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) {
+        context.removeBundleListener(this);
+        this.unregisterManagerFactory();
         if ( this.packageAdminTracker != null ) {
             this.packageAdminTracker.close();
             this.packageAdminTracker = null;
         }
+        this.bundleContext = null;
+    }
+
+    /**
+     * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+     */
+    public void bundleChanged(BundleEvent event) {
+        final long bundleId = event.getBundle().getBundleId();
+        boolean needsUpdate = this.service.isBundleUsed(bundleId);
+        if ( needsUpdate ) {
+            this.unregisterManagerFactory();
+            this.registerManagerFactory();
+        }
     }
 }
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
index 75cb21d..efef5db 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
@@ -27,6 +27,8 @@ import org.osgi.framework.Bundle;
 /**
  * The <code>BundleProxyClassLoader</code> is a class loader
  * delegating to a bundle.
+ * We don't need to cache as the {@link ClassLoaderFacade} is
+ * already doing this.
  */
 public class BundleProxyClassLoader extends ClassLoader {
 
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
index e852bd8..d080d67 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
@@ -19,19 +19,30 @@
 package org.apache.sling.commons.classloader.impl;
 
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.URL;
 import java.util.Enumeration;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 
 /**
  * The <code>ClassLoaderFacade</code> is a facade
  * for the dynamic class loading.
+ * This class loader is returned to the clients of the
+ * dynamic class loader manager.
+ * This class loader delegates to other class loaders
+ * but caches its result for performance.
  */
 public class ClassLoaderFacade extends ClassLoader {
 
     private final DynamicClassLoaderManagerImpl manager;
 
+    /** A cache for resolved classes. */
+    private Map<String, Class<?>> classCache = new ConcurrentHashMap<String, Class<?>>();
+
+    /** A cache for resolved urls. */
+    private Map<String, URL> urlCache = new ConcurrentHashMap<String, URL>();
+
     public ClassLoaderFacade(final DynamicClassLoaderManagerImpl manager) {
         this.manager = manager;
     }
@@ -40,11 +51,19 @@ public class ClassLoaderFacade extends ClassLoader {
      * @see java.lang.ClassLoader#getResource(java.lang.String)
      */
     public URL getResource(String name) {
+        if ( !this.manager.isActive() ) {
+            throw new RuntimeException("Dynamic class loader has already been deactivated.");
+        }
+        final URL cachedURL = urlCache.get(name);
+        if ( cachedURL != null ) {
+            return cachedURL;
+        }
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
             if ( cl != null ) {
                 final URL u = cl.getResource(name);
                 if ( u != null ) {
+                    urlCache.put(name, u);
                     return u;
                 }
             }
@@ -53,25 +72,12 @@ public class ClassLoaderFacade extends ClassLoader {
     }
 
     /**
-     * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
-     */
-    public InputStream getResourceAsStream(String name) {
-        final ClassLoader[] loaders = manager.getDynamicClassLoaders();
-        for(final ClassLoader cl : loaders) {
-            if ( cl != null ) {
-                final InputStream i = cl.getResourceAsStream(name);
-                if ( i != null ) {
-                    return i;
-                }
-            }
-        }
-        return null;
-    }
-
-    /**
      * @see java.lang.ClassLoader#getResources(java.lang.String)
      */
     public Enumeration<URL> getResources(String name) throws IOException {
+        if ( !this.manager.isActive() ) {
+            throw new RuntimeException("Dynamic class loader has already been deactivated.");
+        }
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
             if ( cl != null ) {
@@ -88,13 +94,22 @@ public class ClassLoaderFacade extends ClassLoader {
      * @see java.lang.ClassLoader#loadClass(java.lang.String)
      */
     public Class<?> loadClass(String name) throws ClassNotFoundException {
+        if ( !this.manager.isActive() ) {
+            throw new RuntimeException("Dynamic class loader has already been deactivated.");
+        }
+        final Class<?> cachedClass = this.classCache.get(name);
+        if ( cachedClass != null ) {
+            return cachedClass;
+        }
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
             if ( cl != null ) {
                 try {
                     final Class<?> c = cl.loadClass(name);
+                    this.classCache.put(name, c);
                     return c;
                 } catch (Exception cnfe) {
+                    cnfe.printStackTrace();
                     // we just ignore this and try the next class loader
                 }
             }
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
index cad3a05..3a257d2 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
@@ -16,6 +16,10 @@
  */
 package org.apache.sling.commons.classloader.impl;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceFactory;
@@ -34,6 +38,8 @@ public class DynamicClassLoaderManagerFactory
     /** The bundle context. */
     private final BundleContext context;
 
+    private final Set<Long> usedBundles = Collections.synchronizedSet(new HashSet<Long>());
+
     /**
      * Create a new service instance
      * @param ctx The bundle context.
@@ -50,7 +56,7 @@ public class DynamicClassLoaderManagerFactory
      */
     public Object getService(final Bundle bundle,
                              final ServiceRegistration registration) {
-        return new DynamicClassLoaderManagerImpl(this.context, this.pckAdmin, new BundleProxyClassLoader(bundle));
+        return new DynamicClassLoaderManagerImpl(this.context, this.pckAdmin, new BundleProxyClassLoader(bundle), this);
     }
 
     /**
@@ -63,4 +69,22 @@ public class DynamicClassLoaderManagerFactory
             ((DynamicClassLoaderManagerImpl)service).deactivate();
         }
     }
+
+    /**
+     * Check if a bundle has been used for class loading.
+     * @param bundleId The bundle id.
+     * @return <code>true</code> if the bundle has been used.
+     */
+    public boolean isBundleUsed(final long bundleId) {
+        return usedBundles.contains(bundleId);
+    }
+
+    /**
+     * Notify that a bundle is used as a source for class loading.
+     * @param bundle The bundle.
+     */
+    public void addUsedBundle(final Bundle bundle) {
+        final long id = bundle.getBundleId();
+        this.usedBundles.add(id);
+    }
 }
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
index 2e5c6e1..2388b5b 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
@@ -44,10 +44,15 @@ public class DynamicClassLoaderManagerImpl
     /** The bundle context. */
     private final BundleContext context;
 
+    /** The cached chain of class loaders. */
     private ClassLoader[] cache;
 
+    /** Needs the cache an update? */
     private boolean updateCache = false;
 
+    /** Is this service still active? */
+    private boolean active = true;
+
     /**
      * Create a new service instance
      * @param ctx The bundle context of the class loader bundle
@@ -56,10 +61,11 @@ public class DynamicClassLoaderManagerImpl
      */
     public DynamicClassLoaderManagerImpl(final BundleContext ctx,
             final PackageAdmin pckAdmin,
-            final ClassLoader parent) {
+            final ClassLoader parent,
+            final DynamicClassLoaderManagerFactory factory) {
         super(ctx, DynamicClassLoaderProvider.class.getName(), null);
         this.context = ctx;
-        this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, parent);
+        this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, parent, factory);
         this.cache = new ClassLoader[] {this.pckAdminCL};
         this.open();
         this.facade = new ClassLoaderFacade(this);
@@ -85,8 +91,7 @@ public class DynamicClassLoaderManagerImpl
             final ServiceReference[] refs = this.getServiceReferences();
             final ClassLoader[] loaders = new ClassLoader[1 + refs.length];
             Arrays.sort(refs, ServiceReferenceComparator.INSTANCE);
-            loaders[0] = this.pckAdminCL;
-            int index = 1;
+            int index = 0;
             for(final ServiceReference ref : refs) {
                 final DynamicClassLoaderProvider provider = (DynamicClassLoaderProvider)this.getService(ref);
                 if ( provider != null ) {
@@ -94,6 +99,7 @@ public class DynamicClassLoaderManagerImpl
                 }
                 index++;
             }
+            loaders[index] = this.pckAdminCL;
             // and now use new array
             this.cache = loaders;
             this.updateCache = false;
@@ -104,9 +110,16 @@ public class DynamicClassLoaderManagerImpl
      * Deactivate this service.
      */
     public void deactivate() {
+        this.active = false;
         this.close();
     }
 
+    /**
+     * Check if this service is still active.
+     */
+    public boolean isActive() {
+        return this.active;
+    }
 
     /**
      * @see org.apache.sling.commons.classloader.DynamicClassLoaderManager#getDynamicClassLoader()
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
index dc98f88..f27bc8d 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -27,28 +27,52 @@ import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 
 /**
- * The <code>PackageAdminClassLoader</code>
+ * The <code>PackageAdminClassLoader</code> loads
+ * classes and resources through the package admin service.
  */
 class PackageAdminClassLoader extends ClassLoader {
 
+    /** The package admin service. */
     private final PackageAdmin packageAdmin;
 
-    public PackageAdminClassLoader(final PackageAdmin pckAdmin, final ClassLoader parent) {
+    /** The manager factory. */
+    private final DynamicClassLoaderManagerFactory factory;
+
+    public PackageAdminClassLoader(final PackageAdmin pckAdmin,
+                                   final ClassLoader parent,
+                                   final DynamicClassLoaderManagerFactory factory) {
         super(parent);
         this.packageAdmin = pckAdmin;
+        this.factory = factory;
     }
 
+    /**
+     * Find the bundle for a given package.
+     * @param pckName The package name.
+     * @return The bundle or <code>null</code>
+     */
     private Bundle findBundleForPackage(final String pckName) {
         final ExportedPackage exportedPackage = this.packageAdmin.getExportedPackage(pckName);
-        return (exportedPackage == null ? null : exportedPackage.getExportingBundle());
+        final Bundle bundle = (exportedPackage == null ? null : exportedPackage.getExportingBundle());
+        return bundle;
     }
 
+    /**
+     * Return the package from a resource.
+     * @param resource The resource path.
+     * @return The package name.
+     */
     private String getPackageFromResource(final String resource) {
         final int lastSlash = resource.lastIndexOf('/');
         final String pckName = (lastSlash == -1 ? "" : resource.substring(0, lastSlash).replace('/', '.'));
         return pckName;
     }
 
+    /**
+     * Return the package from a class.
+     * @param resource The class name.
+     * @return The package name.
+     */
     private String getPackageFromClassName(final String name) {
         final int lastDot = name.lastIndexOf('.');
         final String pckName = (lastDot == -1 ? "" : name.substring(0, lastDot));
@@ -60,43 +84,73 @@ class PackageAdminClassLoader extends ClassLoader {
      */
     @SuppressWarnings("unchecked")
     public Enumeration<URL> getResources(String name) throws IOException {
-        final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
-        if ( bundle == null ) {
-            return super.getResources(name);
+        Enumeration<URL> e = super.getResources(name);
+        if ( e == null || !e.hasMoreElements() ) {
+            final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
+            if ( bundle != null ) {
+                e = bundle.getResources(name);
+                if ( e != null && e.hasMoreElements() ) {
+                    this.factory.addUsedBundle(bundle);
+                }
+            }
         }
-        return bundle.getResources(name);
+        return e;
     }
 
     /**
      * @see java.lang.ClassLoader#findResource(java.lang.String)
      */
     public URL findResource(String name) {
-        final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
-        if ( bundle == null ) {
-            return super.findResource(name);
+        URL url = super.findResource(name);
+        if ( url == null ) {
+            final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
+            if ( bundle != null ) {
+                url = bundle.getResource(name);
+                if ( url != null ) {
+                    this.factory.addUsedBundle(bundle);
+                }
+            }
         }
-        return bundle.getResource(name);
+        return url;
     }
 
     /**
      * @see java.lang.ClassLoader#findClass(java.lang.String)
      */
     public Class<?> findClass(String name) throws ClassNotFoundException {
-        final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
-        if ( bundle == null ) {
-            return super.findClass(name);
+        Class<?> clazz = null;
+        try {
+            clazz = super.findClass(name);
+        } catch (ClassNotFoundException cnfe) {
+            final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
+            if ( bundle != null ) {
+                clazz = bundle.loadClass(name);
+                this.factory.addUsedBundle(bundle);
+            }
         }
-        return bundle.loadClass(name);
+        if ( clazz == null ) {
+            throw new ClassNotFoundException("Class not found " + name);
+        }
+        return clazz;
     }
 
     /**
      * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
      */
     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
-        if ( bundle == null ) {
-            return super.loadClass(name, resolve);
+        Class<?> clazz = null;
+        try {
+            clazz = super.loadClass(name, resolve);
+        } catch (ClassNotFoundException cnfe) {
+            final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
+            if ( bundle != null ) {
+                clazz = bundle.loadClass(name);
+                this.factory.addUsedBundle(bundle);
+            }
+        }
+        if ( clazz == null ) {
+            throw new ClassNotFoundException("Class not found " + name);
         }
-        return bundle.loadClass(name);
+        return clazz;
     }
 }
diff --git a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
index e08be6e..e60256f 100644
--- a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
+++ b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
@@ -61,6 +61,8 @@ public class ClassLoadingTest {
             will(returnValue(ep));
             allowing(ep).getExportingBundle();
             will(returnValue(bundle));
+            allowing(bundle).getBundleId();
+            will(returnValue(2L));
             one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
             will(returnValue(java.util.Map.class));
             one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
@@ -68,13 +70,15 @@ public class ClassLoadingTest {
             one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
             will(returnValue(java.util.ArrayList.class));
         }});
-        DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin, null);
+        DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin, null,
+            new DynamicClassLoaderManagerFactory(bundleContext, packageAdmin));
         final ClassLoader cl = manager.getDynamicClassLoader();
         final Class c1 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c1.getName());
         final Class c2 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c2.getName());
+        // as we cache the result, we still get the map!
         final Class c3 = cl.loadClass("org.apache.sling.test.A");
-        Assert.assertEquals("java.util.ArrayList", c3.getName());
+        Assert.assertEquals("java.util.Map", c3.getName());
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 04/21: Correct activator.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 6b8a1f428e88a82bdb2af603ee7db8a7e23ca243
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jul 14 12:59:21 2009 +0000

    Correct activator.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@793893 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/commons/classloader/impl/Activator.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
index a58d83e..89a08a8 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -20,6 +20,7 @@ package org.apache.sling.commons.classloader.impl;
 
 import java.util.Hashtable;
 
+import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -57,7 +58,7 @@ public class Activator implements BundleActivator {
         props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
         this.service = new DynamicClassLoaderManagerImpl(context,
                 (PackageAdmin)this.packageAdminTracker.getService());
-        this.serviceReg = context.registerService(new String[] {DynamicClassLoaderManagerImpl.class.getName()}, service, props);
+        this.serviceReg = context.registerService(new String[] {DynamicClassLoaderManager.class.getName()}, service, props);
     }
 
     /**

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 01/21: SLING-1007 : Initial work of a dynamic class loader loading classes through package admin. In addition dynamic class loader providers can be registered.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 046ba4fd01b89045e0b0c13bcdf2e87f8073b3e7
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Jul 6 19:53:28 2009 +0000

    SLING-1007 : Initial work of a dynamic class loader loading classes through package admin. In addition dynamic class loader providers can be registered.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/commons/classloader@791586 13f79535-47bb-0310-9956-ffa450edef68
---
 LICENSE                                            | 202 +++++++++++++++++++++
 NOTICE                                             |   9 +
 pom.xml                                            |  98 ++++++++++
 .../classloader/DynamicClassLoaderManager.java     |  34 ++++
 .../classloader/DynamicClassLoaderProvider.java    |  35 ++++
 .../sling/commons/classloader/impl/Activator.java  |  80 ++++++++
 .../classloader/impl/ClassLoaderFacade.java        |  96 ++++++++++
 .../impl/DynamicClassLoaderManagerImpl.java        | 136 ++++++++++++++
 .../classloader/impl/PackageAdminClassLoader.java  |  93 ++++++++++
 src/main/resources/META-INF/LICENSE                | 202 +++++++++++++++++++++
 src/main/resources/META-INF/NOTICE                 |   9 +
 11 files changed, 994 insertions(+)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..404f9a9
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,9 @@
+Apache Sling Commons Class Loader
+Copyright 2009 The Apache Software Foundation
+
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..87f1013
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>6</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.commons.classloader</artifactId>
+    <packaging>bundle</packaging>
+    <version>0.9.0-SNAPSHOT</version>
+
+    <name>Apache Sling Dynamic Class Loader Support</name>
+    <description>
+        This bundle provides support for dynamic class loading used for example by the scripting engines.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>
+                            org.apache.sling.commons.classloader.impl.Activator
+                        </Bundle-Activator>
+                        <Export-Package>
+                            org.apache.sling.commons.classloader;version=${pom.version}
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.sling.commons.classloader.impl
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <excludePackageNames>
+                        org.apache.sling.commons.classloader.impl
+                    </excludePackageNames>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java
new file mode 100644
index 0000000..ff23e78
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader;
+
+/**
+ * The dynamic class loader manager is a central
+ * service managing all dynamic class loaders.
+ * It provides a class loader that can be used by
+ * bundles requiring access to all publically available
+ * classes.
+ */
+public interface DynamicClassLoaderManager {
+
+    /**
+     * The dynamic class loader.
+     */
+    ClassLoader getDynamicClassLoader();
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java
new file mode 100644
index 0000000..04eaf8e
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader;
+
+/**
+ * A dynamic class loader provider allows to provide
+ * class loaders that will be used by the dynamic
+ * class loading mechanism. For instance a JCR class loader
+ * provider could provide some class loader loading classes
+ * from a content repository etc.
+ */
+public interface DynamicClassLoaderProvider {
+
+    /**
+     * Return the class loader used for dynamic class loading.
+     * @return The class loader.
+     */
+    ClassLoader getClassLoader();
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
new file mode 100644
index 0000000..a58d83e
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * This activator registers the dynamic class loader manager.
+ */
+public class Activator implements BundleActivator {
+
+    /** Package admin service name */
+    private static String PACKAGE_ADMIN_NAME = PackageAdmin.class.getName();
+
+    /** A service tracker for the package admin. */
+    private ServiceTracker packageAdminTracker;
+
+    /** The service registration for the dynamic class loader manager. */
+    private ServiceRegistration serviceReg;
+
+    /** The dynamic class loader service. */
+    private DynamicClassLoaderManagerImpl service;
+
+    /**
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) throws Exception {
+        this.packageAdminTracker = new ServiceTracker(context, PACKAGE_ADMIN_NAME, null);
+        this.packageAdminTracker.open();
+
+        // register service
+        final Hashtable<String, String> props = new Hashtable<String, String>();
+        props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Dynamic Class Loader Service");
+        props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
+        this.service = new DynamicClassLoaderManagerImpl(context,
+                (PackageAdmin)this.packageAdminTracker.getService());
+        this.serviceReg = context.registerService(new String[] {DynamicClassLoaderManagerImpl.class.getName()}, service, props);
+    }
+
+    /**
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) throws Exception {
+        if ( this.serviceReg != null ) {
+            this.serviceReg.unregister();
+            this.serviceReg = null;
+        }
+        if ( this.service != null ) {
+            this.service.deactivate();
+            this.service = null;
+        }
+        if ( this.packageAdminTracker != null ) {
+            this.packageAdminTracker.close();
+            this.packageAdminTracker = null;
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
new file mode 100644
index 0000000..1ef22a4
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+
+
+/**
+ * The <code>ClassLoaderFacade</code> is a facade
+ * for the dynamic class loading.
+ */
+public class ClassLoaderFacade extends ClassLoader {
+
+    private final DynamicClassLoaderManagerImpl manager;
+
+    public ClassLoaderFacade(final DynamicClassLoaderManagerImpl manager) {
+        this.manager = manager;
+    }
+
+    /**
+     * @see java.lang.ClassLoader#getResource(java.lang.String)
+     */
+    public URL getResource(String name) {
+        final ClassLoader[] loaders = manager.getDynamicClassLoaders();
+        for(final ClassLoader cl : loaders) {
+            final URL u = cl.getResource(name);
+            if ( u != null ) {
+                return u;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String)
+     */
+    public InputStream getResourceAsStream(String name) {
+        final ClassLoader[] loaders = manager.getDynamicClassLoaders();
+        for(final ClassLoader cl : loaders) {
+            final InputStream i = cl.getResourceAsStream(name);
+            if ( i != null ) {
+                return i;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see java.lang.ClassLoader#getResources(java.lang.String)
+     */
+    public Enumeration<URL> getResources(String name) throws IOException {
+        final ClassLoader[] loaders = manager.getDynamicClassLoaders();
+        for(final ClassLoader cl : loaders) {
+            final Enumeration<URL> e = cl.getResources(name);
+            if ( e != null && e.hasMoreElements() ) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see java.lang.ClassLoader#loadClass(java.lang.String)
+     */
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        final ClassLoader[] loaders = manager.getDynamicClassLoaders();
+        for(final ClassLoader cl : loaders) {
+            try {
+                final Class<?> c = cl.loadClass(name);
+                return c;
+            } catch (Exception cnfe) {
+                // we just ignore this and try the next class loader
+            }
+        }
+        throw new ClassNotFoundException("Class not found: " + name);
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
new file mode 100644
index 0000000..5257103
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.apache.sling.commons.classloader.DynamicClassLoaderProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * This is the default implementation of the dynamic class loader
+ * manager.
+ */
+public class DynamicClassLoaderManagerImpl
+    extends ServiceTracker
+    implements DynamicClassLoaderManager, ServiceTrackerCustomizer {
+
+    /** The package admin class loader. */
+    private final PackageAdminClassLoader pckAdminCL;
+
+    /** The dynamic class loader. */
+    private final ClassLoaderFacade facade;
+
+    /** The bundle context. */
+    private final BundleContext context;
+
+    private ClassLoader[] cache;
+
+    private boolean updateCache = false;
+
+    /**
+     * Create a new service instance
+     * @param ctx The bundle context.
+     * @param pckAdmin The package admin.
+     */
+    public DynamicClassLoaderManagerImpl(final BundleContext ctx,
+            final PackageAdmin pckAdmin) {
+        super(ctx, DynamicClassLoaderProvider.class.getName(), null);
+        this.context = ctx;
+        this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, this.getClass().getClassLoader());
+        this.cache = new ClassLoader[] {this.pckAdminCL};
+        this.open();
+        this.facade = new ClassLoaderFacade(this);
+    }
+
+    public Object addingService(ServiceReference reference) {
+        this.updateCache = true;
+        return this.context.getService(reference);
+    }
+
+    public void modifiedService(ServiceReference reference, Object service) {
+        // as the ranking property has changed we have to update the cache
+        this.updateCache = true;
+    }
+
+    public void removedService(ServiceReference reference, Object service) {
+        this.context.ungetService(reference);
+        this.updateCache = true;
+    }
+
+    private synchronized void updateCache() {
+        if ( this.updateCache ) {
+            final ServiceReference[] refs = this.getServiceReferences();
+            final ClassLoader[] loaders = new ClassLoader[1 + refs.length];
+            Arrays.sort(refs, ServiceReferenceComparator.INSTANCE);
+            loaders[0] = this.pckAdminCL;
+            int index = 1;
+            for(final ServiceReference ref : refs) {
+                loaders[index] = (ClassLoader) this.getService(ref);
+                index++;
+            }
+            // and now use new array
+            this.cache = loaders;
+            this.updateCache = false;
+        }
+    }
+
+    /**
+     * Deactivate this service.
+     */
+    public void deactivate() {
+        this.close();
+    }
+
+
+    /**
+     * @see org.apache.sling.commons.classloader.DynamicClassLoaderManager#getDynamicClassLoader()
+     */
+    public ClassLoader getDynamicClassLoader() {
+        return this.facade;
+    }
+
+    /**
+     * This list contains the current list of class loaders. The first class loader
+     * is always the package admin class loader, therefore this list is never null
+     * and has always a size greater than zero.
+     * @return The list of class loaders.
+     */
+    public ClassLoader[] getDynamicClassLoaders() {
+        if ( this.updateCache ) {
+            updateCache();
+        }
+        return this.cache;
+    }
+
+    /**
+     * Comparator for service references.
+     */
+    protected static final class ServiceReferenceComparator implements Comparator<ServiceReference> {
+        public static ServiceReferenceComparator INSTANCE = new ServiceReferenceComparator();
+
+        public int compare(ServiceReference o1, ServiceReference o2) {
+            return o1.compareTo(o2);
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
new file mode 100644
index 0000000..9cd07a5
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * The <code>PackageAdminClassLoader</code>
+ */
+class PackageAdminClassLoader extends ClassLoader {
+
+    private final PackageAdmin packageAdmin;
+
+    public PackageAdminClassLoader(final PackageAdmin pckAdmin, final ClassLoader parent) {
+        super(parent);
+        this.packageAdmin = pckAdmin;
+    }
+
+    private Bundle findBundleForClassOrResource(final String name) {
+        final int lastDot = name.lastIndexOf('.');
+        final String pckName = (lastDot == -1 ? "" : name.substring(0, lastDot));
+
+        final ExportedPackage exportedPackage = this.packageAdmin.getExportedPackage(pckName);
+        return (exportedPackage == null ? null : exportedPackage.getExportingBundle());
+    }
+
+    /**
+     * @see java.lang.ClassLoader#getResources(java.lang.String)
+     */
+    @SuppressWarnings("unchecked")
+    public Enumeration<URL> getResources(String name) throws IOException {
+        final Bundle bundle = this.findBundleForClassOrResource(name);
+        if ( bundle == null ) {
+            return super.getResources(name);
+        }
+        return bundle.getResources(name);
+    }
+
+    /**
+     * @see java.lang.ClassLoader#findResource(java.lang.String)
+     */
+    public URL findResource(String name) {
+        final Bundle bundle = this.findBundleForClassOrResource(name);
+        if ( bundle == null ) {
+            return super.findResource(name);
+        }
+        return bundle.getResource(name);
+    }
+
+    /**
+     * @see java.lang.ClassLoader#findClass(java.lang.String)
+     */
+    public Class<?> findClass(String name) throws ClassNotFoundException {
+        final Bundle bundle = this.findBundleForClassOrResource(name);
+        if ( bundle == null ) {
+            return super.findClass(name);
+        }
+        return bundle.loadClass(name);
+    }
+
+    /**
+     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+     */
+    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        final Bundle bundle = this.findBundleForClassOrResource(name);
+        if ( bundle == null ) {
+            return super.loadClass(name, resolve);
+        }
+        return bundle.loadClass(name);
+    }
+}
diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..404f9a9
--- /dev/null
+++ b/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,9 @@
+Apache Sling Commons Class Loader
+Copyright 2009 The Apache Software Foundation
+
+Apache Sling is based on source code originally developed 
+by Day Software (http://www.day.com/).
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 07/21: Fix resource handling (packages are separated by a slash not by a dot)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 2813fc7b60c291865bead116f4e00eef886ac204
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 12:04:06 2009 +0000

    Fix resource handling (packages are separated by a slash not by a dot)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794243 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/commons/classloader/impl/PackageAdminClassLoader.java  | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
index 9cd07a5..a6d1699 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -46,12 +46,17 @@ class PackageAdminClassLoader extends ClassLoader {
         return (exportedPackage == null ? null : exportedPackage.getExportingBundle());
     }
 
+    private String getPackageFromResource(final String resource) {
+        final int lastSlash = resource.lastIndexOf('/');
+        String pck = resource.substring(0, lastSlash + 1).replace('/', '.');
+        return pck + "Dummy";
+    }
     /**
      * @see java.lang.ClassLoader#getResources(java.lang.String)
      */
     @SuppressWarnings("unchecked")
     public Enumeration<URL> getResources(String name) throws IOException {
-        final Bundle bundle = this.findBundleForClassOrResource(name);
+        final Bundle bundle = this.findBundleForClassOrResource(getPackageFromResource(name));
         if ( bundle == null ) {
             return super.getResources(name);
         }
@@ -62,7 +67,7 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#findResource(java.lang.String)
      */
     public URL findResource(String name) {
-        final Bundle bundle = this.findBundleForClassOrResource(name);
+        final Bundle bundle = this.findBundleForClassOrResource(getPackageFromResource(name));
         if ( bundle == null ) {
             return super.findResource(name);
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 02/21: Add simple junit test for dynamic class loading through package admin.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 58366312eb8851b0659df8985905d09e00ef0137
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jul 14 11:35:44 2009 +0000

    Add simple junit test for dynamic class loading through package admin.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/commons/classloader@793858 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  9 +++
 .../commons/classloader/impl/ClassLoadingTest.java | 80 ++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/pom.xml b/pom.xml
index 87f1013..1071ee6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,5 +94,14 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jmock</groupId>
+            <artifactId>jmock-junit4</artifactId>
+        </dependency>
     </dependencies>
 </project>
diff --git a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
new file mode 100644
index 0000000..62f8862
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import junit.framework.Assert;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.Sequence;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceListener;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Simple test for the dynamic class loader.
+ */
+public class ClassLoadingTest {
+
+    protected Mockery context;
+
+    public ClassLoadingTest() {
+        this.context = new JUnit4Mockery();
+    }
+
+    /**
+     * This method tests the dynamic class loading through the package admin.
+     * The returned class changes from map to array list.
+     */
+    @Test public void testLoading() throws Exception {
+        final Sequence sequence = this.context.sequence("load-sequence");
+        final BundleContext bundleContext = this.context.mock(BundleContext.class);
+        final PackageAdmin packageAdmin = this.context.mock(PackageAdmin.class);
+        final ExportedPackage ep = this.context.mock(ExportedPackage.class);
+        final Bundle bundle = this.context.mock(Bundle.class);
+        this.context.checking(new Expectations() {{
+            allowing(bundleContext).createFilter(with(any(String.class)));
+            will(returnValue(null));
+            allowing(bundleContext).addServiceListener(with(any(ServiceListener.class)), with(any(String.class)));
+            allowing(bundleContext).removeServiceListener(with(any(ServiceListener.class)));
+            allowing(bundleContext).getServiceReferences(with(any(String.class)), with(any(String.class)));
+            will(returnValue(null));
+            allowing(packageAdmin).getExportedPackage("org.apache.sling.test");
+            will(returnValue(ep));
+            allowing(ep).getExportingBundle();
+            will(returnValue(bundle));
+            one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
+            will(returnValue(java.util.Map.class));
+            one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
+            will(returnValue(java.util.Map.class));
+            one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
+            will(returnValue(java.util.ArrayList.class));
+        }});
+        DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin);
+        final ClassLoader cl = manager.getDynamicClassLoader();
+        final Class c1 = cl.loadClass("org.apache.sling.test.A");
+        Assert.assertEquals("java.util.Map", c1.getName());
+        final Class c2 = cl.loadClass("org.apache.sling.test.A");
+        Assert.assertEquals("java.util.Map", c2.getName());
+        final Class c3 = cl.loadClass("org.apache.sling.test.A");
+        Assert.assertEquals("java.util.ArrayList", c3.getName());
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 18/21: svn:ignore

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 61594f53a410a0499be686e02cac020d5fc66c2b
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Thu Aug 27 09:39:59 2009 +0000

    svn:ignore
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@808340 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 10/21: forgot to commit test case

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit c5338c169dc4f974bcb32dfc0dcbd7cb59a7b38a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 15:06:39 2009 +0000

    forgot to commit test case
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794296 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/commons/classloader/impl/ClassLoadingTest.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
index 62f8862..e08be6e 100644
--- a/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
+++ b/src/test/java/org/apache/sling/commons/classloader/impl/ClassLoadingTest.java
@@ -68,7 +68,7 @@ public class ClassLoadingTest {
             one(bundle).loadClass("org.apache.sling.test.A"); inSequence(sequence);
             will(returnValue(java.util.ArrayList.class));
         }});
-        DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin);
+        DynamicClassLoaderManagerImpl manager = new DynamicClassLoaderManagerImpl(bundleContext, packageAdmin, null);
         final ClassLoader cl = manager.getDynamicClassLoader();
         final Class c1 = cl.loadClass("org.apache.sling.test.A");
         Assert.assertEquals("java.util.Map", c1.getName());

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 15/21: Remove duplicate interface

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit bf847ec44e0890eca28bd5b3ab158f6ea233c147
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 5 13:08:05 2009 +0000

    Remove duplicate interface
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@801205 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/commons/classloader/impl/Activator.java    | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
index 6cd29d7..f363c68 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -21,10 +21,9 @@ package org.apache.sling.commons.classloader.impl;
 import java.util.Hashtable;
 
 import org.apache.sling.commons.classloader.DynamicClassLoaderManager;
+import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
-import org.osgi.framework.BundleListener;
-import org.osgi.framework.BundleActivator;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.SynchronousBundleListener;
@@ -36,7 +35,7 @@ import org.osgi.util.tracker.ServiceTracker;
  * It listens for bundle events and reregisters the class loader manager
  * if a bundle event for a used bundle occurs.
  */
-public class Activator implements SynchronousBundleListener, BundleListener, BundleActivator {
+public class Activator implements SynchronousBundleListener, BundleActivator {
 
     /** Package admin service name */
     private static String PACKAGE_ADMIN_NAME = PackageAdmin.class.getName();

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 03/21: Move classloader to main bundle area - as discussed recently

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit ea90c3815ef438bebeceef565d9a1667de13732f
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Jul 14 11:36:14 2009 +0000

    Move classloader to main bundle area - as discussed recently
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@793859 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 05/21: Ignore target directory.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 3ffeb64b3774213f9d2ea5506c36e0405515ce14
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 08:31:23 2009 +0000

    Ignore target directory.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794179 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 06/21: Fix class cast.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit cc3b40d3c9c462863b645e74b8ec8fc4f91694e8
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 10:34:28 2009 +0000

    Fix class cast.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794219 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java  | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
index 5257103..8d344cc 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
@@ -86,7 +86,8 @@ public class DynamicClassLoaderManagerImpl
             loaders[0] = this.pckAdminCL;
             int index = 1;
             for(final ServiceReference ref : refs) {
-                loaders[index] = (ClassLoader) this.getService(ref);
+                final DynamicClassLoaderProvider provider = (DynamicClassLoaderProvider)this.getService(ref);
+                loaders[index] = provider.getClassLoader();
                 index++;
             }
             // and now use new array

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 20/21: [maven-release-plugin] prepare release org.apache.sling.commons.classloader-0.9.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 9fc087f5373ae9395a2b8f4e1458302d6ab0fc04
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Sep 29 13:12:59 2009 +0000

    [maven-release-plugin] prepare release org.apache.sling.commons.classloader-0.9.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@819927 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index e8c360a..84486fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
 
     <artifactId>org.apache.sling.commons.classloader</artifactId>
     <packaging>bundle</packaging>
-    <version>0.9.0-SNAPSHOT</version>
+    <version>0.9.0</version>
 
     <name>Apache Sling Dynamic Class Loader Support</name>
     <description>
@@ -37,9 +37,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.classloader-0.9.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.commons.classloader-0.9.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.commons.classloader-0.9.0</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 09/21: Fix AIOOB

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 54194d4efae17041f998dc81abca67ccf8c81d65
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 13:23:59 2009 +0000

    Fix AIOOB
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794264 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/commons/classloader/impl/PackageAdminClassLoader.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
index a703f7f..dc98f88 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -45,7 +45,7 @@ class PackageAdminClassLoader extends ClassLoader {
 
     private String getPackageFromResource(final String resource) {
         final int lastSlash = resource.lastIndexOf('/');
-        final String pckName = resource.substring(0, lastSlash).replace('/', '.');
+        final String pckName = (lastSlash == -1 ? "" : resource.substring(0, lastSlash).replace('/', '.'));
         return pckName;
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 08/21: Register classloader as a service factory to get access to the client bundle for class loading.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 97bcc33b7f60809a7b91085b86f46896861d987d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Jul 15 12:31:59 2009 +0000

    Register classloader as a service factory to get access to the client bundle for class loading.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794249 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/commons/classloader/impl/Activator.java  |  7 +--
 .../classloader/impl/BundleProxyClassLoader.java   | 71 ++++++++++++++++++++++
 .../impl/DynamicClassLoaderManagerFactory.java     | 66 ++++++++++++++++++++
 .../impl/DynamicClassLoaderManagerImpl.java        |  8 ++-
 .../classloader/impl/PackageAdminClassLoader.java  | 24 +++++---
 5 files changed, 159 insertions(+), 17 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
index 89a08a8..1ca885e 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
@@ -42,8 +42,8 @@ public class Activator implements BundleActivator {
     /** The service registration for the dynamic class loader manager. */
     private ServiceRegistration serviceReg;
 
-    /** The dynamic class loader service. */
-    private DynamicClassLoaderManagerImpl service;
+    /** The dynamic class loader service factory. */
+    private DynamicClassLoaderManagerFactory service;
 
     /**
      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
@@ -56,7 +56,7 @@ public class Activator implements BundleActivator {
         final Hashtable<String, String> props = new Hashtable<String, String>();
         props.put(Constants.SERVICE_DESCRIPTION, "Apache Sling Dynamic Class Loader Service");
         props.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
-        this.service = new DynamicClassLoaderManagerImpl(context,
+        this.service = new DynamicClassLoaderManagerFactory(context,
                 (PackageAdmin)this.packageAdminTracker.getService());
         this.serviceReg = context.registerService(new String[] {DynamicClassLoaderManager.class.getName()}, service, props);
     }
@@ -70,7 +70,6 @@ public class Activator implements BundleActivator {
             this.serviceReg = null;
         }
         if ( this.service != null ) {
-            this.service.deactivate();
             this.service = null;
         }
         if ( this.packageAdminTracker != null ) {
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
new file mode 100644
index 0000000..75cb21d
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * The <code>BundleProxyClassLoader</code> is a class loader
+ * delegating to a bundle.
+ */
+public class BundleProxyClassLoader extends ClassLoader {
+
+    /** The bundle. */
+    private final Bundle bundle;
+
+    public BundleProxyClassLoader(Bundle bundle) {
+        this.bundle = bundle;
+    }
+
+    // Note: Both ClassLoader.getResources(...) and bundle.getResources(...) consult
+    // the boot classloader. As a result, BundleProxyClassLoader.getResources(...)
+    // might return duplicate results from the boot classloader. Prior to Java 5
+    // Classloader.getResources was marked final. If your target environment requires
+    // at least Java 5 you can prevent the occurence of duplicate boot classloader
+    // resources by overriding ClassLoader.getResources(...) instead of
+    // ClassLoader.findResources(...).
+    @SuppressWarnings("unchecked")
+    public Enumeration<URL> findResources(String name) throws IOException {
+        return this.bundle.getResources(name);
+    }
+
+    public URL findResource(String name) {
+        return this.bundle.getResource(name);
+    }
+
+    public Class<?> findClass(String name) throws ClassNotFoundException {
+        return this.bundle.loadClass(name);
+    }
+
+    public URL getResource(String name) {
+        return this.findResource(name);
+    }
+
+    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+        Class<?> clazz = this.findClass(name);
+        if (resolve) {
+            super.resolveClass(clazz);
+        }
+        return clazz;
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
new file mode 100644
index 0000000..cad3a05
--- /dev/null
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.commons.classloader.impl;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * This is the service factory for the dynamic class loader manager.
+ */
+public class DynamicClassLoaderManagerFactory
+    implements ServiceFactory {
+
+    /** The package admin. */
+    private final PackageAdmin pckAdmin;
+
+    /** The bundle context. */
+    private final BundleContext context;
+
+    /**
+     * Create a new service instance
+     * @param ctx The bundle context.
+     * @param pckAdmin The package admin.
+     */
+    public DynamicClassLoaderManagerFactory(final BundleContext ctx,
+                                            final PackageAdmin pckAdmin) {
+        this.context = ctx;
+        this.pckAdmin = pckAdmin;
+    }
+
+    /**
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     */
+    public Object getService(final Bundle bundle,
+                             final ServiceRegistration registration) {
+        return new DynamicClassLoaderManagerImpl(this.context, this.pckAdmin, new BundleProxyClassLoader(bundle));
+    }
+
+    /**
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+     */
+    public void ungetService(final Bundle bundle,
+                             final ServiceRegistration registration,
+                             final Object service) {
+        if ( service != null ) {
+            ((DynamicClassLoaderManagerImpl)service).deactivate();
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
index 8d344cc..2d9cc1f 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
@@ -50,14 +50,16 @@ public class DynamicClassLoaderManagerImpl
 
     /**
      * Create a new service instance
-     * @param ctx The bundle context.
+     * @param ctx The bundle context of the class loader bundle
      * @param pckAdmin The package admin.
+     * @param parent The parent class loader.
      */
     public DynamicClassLoaderManagerImpl(final BundleContext ctx,
-            final PackageAdmin pckAdmin) {
+            final PackageAdmin pckAdmin,
+            final ClassLoader parent) {
         super(ctx, DynamicClassLoaderProvider.class.getName(), null);
         this.context = ctx;
-        this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, this.getClass().getClassLoader());
+        this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, parent);
         this.cache = new ClassLoader[] {this.pckAdminCL};
         this.open();
         this.facade = new ClassLoaderFacade(this);
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
index a6d1699..a703f7f 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
@@ -38,25 +38,29 @@ class PackageAdminClassLoader extends ClassLoader {
         this.packageAdmin = pckAdmin;
     }
 
-    private Bundle findBundleForClassOrResource(final String name) {
-        final int lastDot = name.lastIndexOf('.');
-        final String pckName = (lastDot == -1 ? "" : name.substring(0, lastDot));
-
+    private Bundle findBundleForPackage(final String pckName) {
         final ExportedPackage exportedPackage = this.packageAdmin.getExportedPackage(pckName);
         return (exportedPackage == null ? null : exportedPackage.getExportingBundle());
     }
 
     private String getPackageFromResource(final String resource) {
         final int lastSlash = resource.lastIndexOf('/');
-        String pck = resource.substring(0, lastSlash + 1).replace('/', '.');
-        return pck + "Dummy";
+        final String pckName = resource.substring(0, lastSlash).replace('/', '.');
+        return pckName;
+    }
+
+    private String getPackageFromClassName(final String name) {
+        final int lastDot = name.lastIndexOf('.');
+        final String pckName = (lastDot == -1 ? "" : name.substring(0, lastDot));
+        return pckName;
     }
+
     /**
      * @see java.lang.ClassLoader#getResources(java.lang.String)
      */
     @SuppressWarnings("unchecked")
     public Enumeration<URL> getResources(String name) throws IOException {
-        final Bundle bundle = this.findBundleForClassOrResource(getPackageFromResource(name));
+        final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
         if ( bundle == null ) {
             return super.getResources(name);
         }
@@ -67,7 +71,7 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#findResource(java.lang.String)
      */
     public URL findResource(String name) {
-        final Bundle bundle = this.findBundleForClassOrResource(getPackageFromResource(name));
+        final Bundle bundle = this.findBundleForPackage(getPackageFromResource(name));
         if ( bundle == null ) {
             return super.findResource(name);
         }
@@ -78,7 +82,7 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#findClass(java.lang.String)
      */
     public Class<?> findClass(String name) throws ClassNotFoundException {
-        final Bundle bundle = this.findBundleForClassOrResource(name);
+        final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
         if ( bundle == null ) {
             return super.findClass(name);
         }
@@ -89,7 +93,7 @@ class PackageAdminClassLoader extends ClassLoader {
      * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
      */
     protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        final Bundle bundle = this.findBundleForClassOrResource(name);
+        final Bundle bundle = this.findBundleForPackage(getPackageFromClassName(name));
         if ( bundle == null ) {
             return super.loadClass(name, resolve);
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 19/21: Use latest parent pom.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 8dd47bc782644d6bb19bb6413faa72ae074a24f2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Sep 29 13:01:59 2009 +0000

    Use latest parent pom.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@819913 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pom.xml b/pom.xml
index 1071ee6..e8c360a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>6</version>
+        <version>7</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 
@@ -83,11 +83,11 @@
     </reporting>
     <dependencies>
         <dependency>
-            <groupId>org.apache.felix</groupId>
+            <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.felix</groupId>
+            <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
         </dependency>
         <dependency>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-commons-classloader] 11/21: Provide parent class loader to dynamic class loader providers; check for null reference.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-0.9.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git

commit 8023ea15d1f7eab8a6291fe68bc9eb4cefd818cb
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Jul 16 05:31:50 2009 +0000

    Provide parent class loader to dynamic class loader providers; check for null reference.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@794537 13f79535-47bb-0310-9956-ffa450edef68
---
 .../classloader/DynamicClassLoaderProvider.java    |  7 ++++-
 .../classloader/impl/ClassLoaderFacade.java        | 36 +++++++++++++---------
 .../impl/DynamicClassLoaderManagerImpl.java        |  4 ++-
 3 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java
index 04eaf8e..cdac258 100644
--- a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java
+++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java
@@ -29,7 +29,12 @@ public interface DynamicClassLoaderProvider {
 
     /**
      * Return the class loader used for dynamic class loading.
+     * The returned class loader should use the provided parent class loader
+     * as one of its parent class loaders. This ensures that the returned
+     * class loader has access to all dynamically loaded classes that
+     * are not part of this class loader.
+     * @param parent The parent class loader for this dynamic class loader.
      * @return The class loader.
      */
-    ClassLoader getClassLoader();
+    ClassLoader getClassLoader(ClassLoader parent);
 }
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
index 1ef22a4..e852bd8 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/ClassLoaderFacade.java
@@ -42,9 +42,11 @@ public class ClassLoaderFacade extends ClassLoader {
     public URL getResource(String name) {
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
-            final URL u = cl.getResource(name);
-            if ( u != null ) {
-                return u;
+            if ( cl != null ) {
+                final URL u = cl.getResource(name);
+                if ( u != null ) {
+                    return u;
+                }
             }
         }
         return null;
@@ -56,9 +58,11 @@ public class ClassLoaderFacade extends ClassLoader {
     public InputStream getResourceAsStream(String name) {
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
-            final InputStream i = cl.getResourceAsStream(name);
-            if ( i != null ) {
-                return i;
+            if ( cl != null ) {
+                final InputStream i = cl.getResourceAsStream(name);
+                if ( i != null ) {
+                    return i;
+                }
             }
         }
         return null;
@@ -70,9 +74,11 @@ public class ClassLoaderFacade extends ClassLoader {
     public Enumeration<URL> getResources(String name) throws IOException {
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
-            final Enumeration<URL> e = cl.getResources(name);
-            if ( e != null && e.hasMoreElements() ) {
-                return e;
+            if ( cl != null ) {
+                final Enumeration<URL> e = cl.getResources(name);
+                if ( e != null && e.hasMoreElements() ) {
+                    return e;
+                }
             }
         }
         return null;
@@ -84,11 +90,13 @@ public class ClassLoaderFacade extends ClassLoader {
     public Class<?> loadClass(String name) throws ClassNotFoundException {
         final ClassLoader[] loaders = manager.getDynamicClassLoaders();
         for(final ClassLoader cl : loaders) {
-            try {
-                final Class<?> c = cl.loadClass(name);
-                return c;
-            } catch (Exception cnfe) {
-                // we just ignore this and try the next class loader
+            if ( cl != null ) {
+                try {
+                    final Class<?> c = cl.loadClass(name);
+                    return c;
+                } catch (Exception cnfe) {
+                    // we just ignore this and try the next class loader
+                }
             }
         }
         throw new ClassNotFoundException("Class not found: " + name);
diff --git a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
index 2d9cc1f..2e5c6e1 100644
--- a/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
+++ b/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
@@ -89,7 +89,9 @@ public class DynamicClassLoaderManagerImpl
             int index = 1;
             for(final ServiceReference ref : refs) {
                 final DynamicClassLoaderProvider provider = (DynamicClassLoaderProvider)this.getService(ref);
-                loaders[index] = provider.getClassLoader();
+                if ( provider != null ) {
+                    loaders[index] = provider.getClassLoader(this.pckAdminCL);
+                }
                 index++;
             }
             // and now use new array

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.