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 <[email protected]> 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 "[email protected]" <[email protected]>.
