You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2009/07/15 14:31:59 UTC

svn commit: r794249 - /sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/

Author: cziegeler
Date: Wed Jul 15 12:31:59 2009
New Revision: 794249

URL: http://svn.apache.org/viewvc?rev=794249&view=rev
Log:
Register classloader as a service factory to get access to the client bundle for class loading.

Added:
    sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java   (with props)
    sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java   (with props)
Modified:
    sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
    sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
    sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java

Modified: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java?rev=794249&r1=794248&r2=794249&view=diff
==============================================================================
--- sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java (original)
+++ sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/Activator.java Wed Jul 15 12:31:59 2009
@@ -42,8 +42,8 @@
     /** 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 @@
         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 @@
             this.serviceReg = null;
         }
         if ( this.service != null ) {
-            this.service.deactivate();
             this.service = null;
         }
         if ( this.packageAdminTracker != null ) {

Added: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java?rev=794249&view=auto
==============================================================================
--- sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java (added)
+++ sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java Wed Jul 15 12:31:59 2009
@@ -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;
+    }
+}

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/BundleProxyClassLoader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java?rev=794249&view=auto
==============================================================================
--- sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java (added)
+++ sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java Wed Jul 15 12:31:59 2009
@@ -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();
+        }
+    }
+}

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java?rev=794249&r1=794248&r2=794249&view=diff
==============================================================================
--- sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java (original)
+++ sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/DynamicClassLoaderManagerImpl.java Wed Jul 15 12:31:59 2009
@@ -50,14 +50,16 @@
 
     /**
      * 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);

Modified: sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java?rev=794249&r1=794248&r2=794249&view=diff
==============================================================================
--- sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java (original)
+++ sling/trunk/bundles/commons/classloader/src/main/java/org/apache/sling/commons/classloader/impl/PackageAdminClassLoader.java Wed Jul 15 12:31:59 2009
@@ -38,25 +38,29 @@
         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 @@
      * @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 @@
      * @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 @@
      * @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);
         }