This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to annotated tag org.apache.sling.commons.classloader-1.3.0 in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-classloader.git
commit f9dee0c7cc8937a46b55a7b73bd775f14a91964e Author: Carsten Ziegeler <[email protected]> AuthorDate: Fri Mar 23 14:53:38 2012 +0000 SLING-2447 : ClassLoaderWriter should provide class loader for loading written classes/resources git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/classloader@1304391 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 2 +- .../commons/classloader/ClassLoaderWriter.java | 45 ++++++-- .../classloader/DynamicClassLoaderManager.java | 6 +- .../classloader/DynamicClassLoaderProvider.java | 5 + .../impl/DynamicClassLoaderManagerImpl.java | 119 ++++++--------------- 5 files changed, 78 insertions(+), 99 deletions(-) diff --git a/pom.xml b/pom.xml index d147154..25f1499 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ org.apache.sling.commons.classloader.impl.Activator </Bundle-Activator> <Export-Package> - org.apache.sling.commons.classloader;version=1.2.0 + org.apache.sling.commons.classloader;version=1.3.0 </Export-Package> <Private-Package> org.apache.sling.commons.classloader.impl 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 82e6634..a1c885b 100644 --- a/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java +++ b/src/main/java/org/apache/sling/commons/classloader/ClassLoaderWriter.java @@ -23,10 +23,13 @@ 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. + * A class loader writer is a service allowing to dynamically generate + * classes and resources. + * It provides methods for writing, removing, and moving resources. + * In addition it provides a dynamic class loader which can be used + * to dynamically load generated classes. + * For example a class loader writer could write generated class files + * into the repository or the temporary file system. */ public interface ClassLoaderWriter { @@ -34,7 +37,8 @@ public interface ClassLoaderWriter { * 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. + * @param path The path of the class/resource. The path should be + * absolute like /com/my/domain/HelloWorld.class * @return The output stream. */ OutputStream getOutputStream(String path); @@ -42,7 +46,8 @@ public interface ClassLoaderWriter { /** * Get the input stream for a class or resource handled * by the underlying class loader. - * @param path The path of the class/resource. + * @param path The path of the class/resource. The path should be + * absolute like /com/my/domain/HelloWorld.class * @return The input stream for the resource/class. * @throws IOException If the resource/class does not exist. */ @@ -50,7 +55,8 @@ public interface ClassLoaderWriter { /** * Return the last modified for the class or resource. - * @param path The path of the class/resource. + * @param path The path of the class/resource. The path should be + * absolute like /com/my/domain/HelloWorld.class * @return The last modified information or <code>-1</code> if * the information can't be detected. */ @@ -58,17 +64,38 @@ public interface ClassLoaderWriter { /** * Delete the class/resource - * @param path The path of the class/resource. + * @param path The path of the class/resource. The path should be + * absolute like /com/my/domain/HelloWorld.class * @return <code>true</code> if the resource exists and could be deleted, * <code>false</code> otherwise. */ boolean delete(String path); /** - * Rename a class/resource. + * Rename a class/resource. The paths should be + * absolute like /com/my/domain/HelloWorld.class * @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); + + /** + * Get a dynamic class loader. + * The returned class loader can be used to load classes and resources generated + * through this class loader writer. The parent of this class loader is + * a class loader from the {@link DynamicClassLoaderManager}. + * The class loader returned by this method should not be cached, as it might + * get stale (e.g. used classes are removed etc.). Therefore each time a newly + * generated class is loaded, the class loader should be fetched again using + * this method. + * The implementation might cache the class loader and return the same loader + * on subsequent calls for as long as possible. + * Clients of the class loader can use the {@link DynamicClassLoader#isLive()} + * method to check if the fetched instance can still be used. + * + * @return A dynamic class loader implementing {@link DynamicClassLoader} + * @since 1.3 + */ + ClassLoader getClassLoader(); } 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 ac41034..af87cf5 100644 --- a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java +++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderManager.java @@ -26,9 +26,7 @@ package org.apache.sling.commons.classloader; * 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. + * service to load classes and resources. * * Keep in mind, that the class loader might get invalid. * This happens for example, if the class loader loaded @@ -37,7 +35,7 @@ package org.apache.sling.commons.classloader; * * In these cases, the dynamic class loader manager service * is unregistered and reregistered again, so you should - * reget your classloader and invalidate loaded objects + * discard your classloader and invalidate loaded objects * whenever this happens. */ public interface DynamicClassLoaderManager { 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 bf7985e..b761d17 100644 --- a/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java +++ b/src/main/java/org/apache/sling/commons/classloader/DynamicClassLoaderProvider.java @@ -24,7 +24,12 @@ package org.apache.sling.commons.classloader; * class loading mechanism. For instance a JCR class loader * provider could provide some class loader loading classes * from a content repository etc. + * + * @deprecated The dynamic class loader provider is not supported + * anymore and any service implementing this is not + * considered for dynamic class loading anymore! */ +@Deprecated public interface DynamicClassLoaderProvider { /** 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 b03514c..4467c3f 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 @@ -16,41 +16,36 @@ */ 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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This is the default implementation of the dynamic class loader * manager. */ public class DynamicClassLoaderManagerImpl - extends ServiceTracker implements DynamicClassLoaderManager { - /** The package admin class loader. */ - private final PackageAdminClassLoader pckAdminCL; + /** Logger. */ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** The class loaders */ + private final ClassLoader[] loaders; /** The dynamic class loader. */ private final ClassLoaderFacade facade; - /** The cached chain of class loaders. */ - private ClassLoader[] cache; - - /** The cached chain of dynamic class loader providers. */ - private DynamicClassLoaderProvider[] providerCache; - /** Is this still active? */ private volatile boolean active = true; - /** Tracking count */ - private volatile int trackingCount = -1; + private final ServiceTracker deprecatedProviderTracker; /** * Create a new service instance @@ -62,69 +57,39 @@ public class DynamicClassLoaderManagerImpl final PackageAdmin pckAdmin, final ClassLoader parent, final DynamicClassLoaderManagerFactory factory) { - super(ctx, DynamicClassLoaderProvider.class.getName(), null); - this.pckAdminCL = new PackageAdminClassLoader(pckAdmin, parent, factory); - this.cache = new ClassLoader[] {this.pckAdminCL}; - this.providerCache = new DynamicClassLoaderProvider[0]; - this.open(); - this.facade = new ClassLoaderFacade(this); - } + this.deprecatedProviderTracker = new ServiceTracker(ctx, DynamicClassLoaderProvider.class.getName(), + new ServiceTrackerCustomizer() { - private synchronized void updateCache() { - if ( this.trackingCount < this.getTrackingCount() ) { - final ServiceReference[] refs = this.getServiceReferences(); - final ClassLoader[] loaders; - final DynamicClassLoaderProvider[] providers; - if ( refs == null || refs.length == 0 ) { - loaders = new ClassLoader[] {this.pckAdminCL}; - providers = new DynamicClassLoaderProvider[0]; - } else { - loaders = new ClassLoader[1 + refs.length]; - providers = new DynamicClassLoaderProvider[refs.length]; - Arrays.sort(refs, ServiceReferenceComparator.INSTANCE); - int index = 0; - for(final ServiceReference ref : refs) { - final DynamicClassLoaderProvider provider = (DynamicClassLoaderProvider)this.getService(ref); - if ( provider != null ) { - loaders[index] = provider.getClassLoader(this.pckAdminCL); - providers[index] = provider; + public void removedService(final ServiceReference serviceRef, + final Object paramObject) { + ctx.ungetService(serviceRef); } - index++; - } - loaders[index] = this.pckAdminCL; - } - // release old class loaders - this.releaseProviders(); - // and now use new array - this.cache = loaders; - this.providerCache = providers; - this.trackingCount = this.getTrackingCount(); - } - } + public void modifiedService(final ServiceReference serviceRef, + final Object paramObject) { + // nothing to do + } - /** - * Free used class loader providers - */ - private void releaseProviders() { - if ( this.providerCache != null ) { - for(int i=0; i<this.providerCache.length; i++) { - if ( this.cache[i] != null ) { - this.providerCache[i].release(this.cache[i]); - } - } - } + public Object addingService(final ServiceReference serviceRef) { + final Object obj = ctx.getService(serviceRef); + if ( obj != null ) { + logger.warn("Dynamic class loader does not support deprecated dynamic class loader providers: {} : {}", + serviceRef, obj); + } + return obj; + } + }); + this.deprecatedProviderTracker.open(); + this.loaders = new ClassLoader[] {new PackageAdminClassLoader(pckAdmin, parent, factory)}; + this.facade = new ClassLoaderFacade(this); } /** * Deactivate this service. */ public void deactivate() { - this.releaseProviders(); + this.deprecatedProviderTracker.close(); this.active = false; - this.close(); - this.providerCache = null; - this.cache = null; } /** @@ -142,26 +107,10 @@ public class DynamicClassLoaderManagerImpl } /** - * 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. + * Return the dynamic class loaders to use + * Currently this is just the package admin class loader. */ public ClassLoader[] getDynamicClassLoaders() { - if ( this.trackingCount < this.getTrackingCount() ) { - 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); - } + return this.loaders; } } -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
