From b7da79a0b6e34776a336d09290ba82e7db1ef137 Mon Sep 17 00:00:00 2001 From: Andrey Marinchuk Date: Wed, 6 Apr 2022 14:33:38 +0300 Subject: [PATCH 1/2] Fix for #543 --- .../core/internal/JDKServiceLoader.java | 62 +++++++++++++++++-- .../core/registry/AbstractRegistry.java | 3 +- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java index d95137ef9..cdabad111 100644 --- a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java +++ b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java @@ -25,6 +25,8 @@ package fr.opensagres.xdocreport.core.internal; import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,13 +39,13 @@ *
  • java.util.ServiceLoader if XDocReport works on Java6. For example : *

    * Iterator discoveries = - ServiceLoader.load( registryType, getClass().getClassLoader() ).iterator(); + ServiceLoader.load( registryType, this ).iterator(); *

    *
  • *
  • javax.imageio.spi.ServiceRegistry if XDocReport works on Java5. For example : *

    * Iterator discoveries = - ServiceRegistry.lookupProviders( registryType, getClass().getClassLoader() ); + ServiceRegistry.lookupProviders( registryType, this ); *

    *
  • * @@ -90,11 +92,11 @@ public abstract class JDKServiceLoader } } - public static Iterator lookupProviders( Class providerClass, ClassLoader loader ) + public static Iterator lookupProviders( Class providerClass, Object classLoaderObject ) { try { - return JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, loader ); + return JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, lookupClassLoader( classLoaderObject ) ); } catch ( Exception e ) { @@ -105,6 +107,34 @@ public static Iterator lookupProviders( Class providerClass, ClassLoad protected abstract Iterator lookupProvidersFromJDK( Class providerClass, ClassLoader loader ) throws Exception; + private static ClassLoader lookupClassLoader( Object classLoaderObject ) { + if ( System.getSecurityManager() != null ) + { + return AccessController.doPrivileged( new LookupClassLoaderAction( classLoaderObject ) ); + } + else + { + return lookupClassLoaderInternal( classLoaderObject ); + } + } + + private static ClassLoader lookupClassLoaderInternal( Object classLoaderObject ) + { + // Use thread context class loader by default + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + // If not found, use specified object class loader + if ( classLoader == null && classLoaderObject != null ) + { + classLoader = classLoaderObject.getClass().getClassLoader(); + } + // If not found, use current class class loader + if (classLoader == null) + { + classLoader = JDKServiceLoader.class.getClassLoader(); + } + return classLoader; + } + private static class JDK5ServiceLoader extends JDKServiceLoader { @@ -151,4 +181,28 @@ protected Iterator lookupProvidersFromJDK( Class providerClass, ClassL } } + + private static class LookupClassLoaderAction + implements PrivilegedAction + { + private Object classLoaderObject; + + LookupClassLoaderAction(Object object) + { + classLoaderObject = object; + } + + @Override + public ClassLoader run() + { + try + { + return lookupClassLoaderInternal(classLoaderObject); + } + catch ( Exception e ) + { + return null; + } + } + } } diff --git a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/registry/AbstractRegistry.java b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/registry/AbstractRegistry.java index f3cf4de26..b509eb0c2 100644 --- a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/registry/AbstractRegistry.java +++ b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/registry/AbstractRegistry.java @@ -61,8 +61,7 @@ protected void initializeIfNeeded() onStartInitialization(); // getClass().getClassLoader() to work under OSGi context - Iterator discoveries = - JDKServiceLoader.lookupProviders( registryType, getClass().getClassLoader() ); + Iterator discoveries = JDKServiceLoader.lookupProviders( registryType, this ); if ( LOGGER.isLoggable( Level.FINE ) ) { LOGGER.fine( "discoveries found ? " + discoveries.hasNext() ); From 06ebae29c0ad21f9d4829f7be2819b471497f808 Mon Sep 17 00:00:00 2001 From: Andrey Marinchuk Date: Wed, 6 Apr 2022 16:50:03 +0300 Subject: [PATCH 2/2] Fix for #543: load classes from two classloaders --- .../core/internal/JDKServiceLoader.java | 83 ++++++++++++++++--- 1 file changed, 70 insertions(+), 13 deletions(-) diff --git a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java index cdabad111..54d5d7886 100644 --- a/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java +++ b/core/fr.opensagres.xdocreport.core/src/main/java/fr/opensagres/xdocreport/core/internal/JDKServiceLoader.java @@ -96,7 +96,13 @@ public static Iterator lookupProviders( Class providerClass, Object cl { try { - return JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, lookupClassLoader( classLoaderObject ) ); + ClassLoader[] classLoaders = lookupClassLoader( classLoaderObject ); + Iterator providers = JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, classLoaders[0] ); + if ( classLoaders.length > 1 ) + { + providers = new IteratorPair<>(providers, JDK_SERVICE_LOADER.lookupProvidersFromJDK( providerClass, classLoaders[1] ) ); + } + return providers; } catch ( Exception e ) { @@ -107,7 +113,7 @@ public static Iterator lookupProviders( Class providerClass, Object cl protected abstract Iterator lookupProvidersFromJDK( Class providerClass, ClassLoader loader ) throws Exception; - private static ClassLoader lookupClassLoader( Object classLoaderObject ) { + private static ClassLoader[] lookupClassLoader( Object classLoaderObject ) { if ( System.getSecurityManager() != null ) { return AccessController.doPrivileged( new LookupClassLoaderAction( classLoaderObject ) ); @@ -118,21 +124,28 @@ private static ClassLoader lookupClassLoader( Object classLoaderObject ) { } } - private static ClassLoader lookupClassLoaderInternal( Object classLoaderObject ) + private static ClassLoader[] lookupClassLoaderInternal( Object classLoaderObject ) { // Use thread context class loader by default - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader classClassLoader; // If not found, use specified object class loader - if ( classLoader == null && classLoaderObject != null ) + if ( classLoaderObject != null ) + { + classClassLoader = classLoaderObject.getClass().getClassLoader(); + } + else + { + classClassLoader = JDKServiceLoader.class.getClassLoader(); + } + if ( contextClassLoader == null || contextClassLoader.equals( classClassLoader ) ) { - classLoader = classLoaderObject.getClass().getClassLoader(); + return new ClassLoader[] { classClassLoader }; } - // If not found, use current class class loader - if (classLoader == null) + else { - classLoader = JDKServiceLoader.class.getClassLoader(); + return new ClassLoader[] { contextClassLoader, classClassLoader }; } - return classLoader; } private static class JDK5ServiceLoader @@ -183,17 +196,17 @@ protected Iterator lookupProvidersFromJDK( Class providerClass, ClassL } private static class LookupClassLoaderAction - implements PrivilegedAction + implements PrivilegedAction { private Object classLoaderObject; - LookupClassLoaderAction(Object object) + LookupClassLoaderAction( Object object ) { classLoaderObject = object; } @Override - public ClassLoader run() + public ClassLoader[] run() { try { @@ -205,4 +218,48 @@ public ClassLoader run() } } } + + private static class IteratorPair + implements Iterator + { + private Iterator iterator; + private Iterator secondIterator; + + IteratorPair( Iterator firstIterator, Iterator secondIterator ) + { + iterator = firstIterator; + this.secondIterator = secondIterator; + } + + @Override + public boolean hasNext() + { + boolean result = iterator.hasNext(); + if ( !result && secondIterator != null ) + { + iterator = secondIterator; + secondIterator = null; + result = iterator.hasNext(); + } + return result; + } + + @Override + public T next() + { + if ( secondIterator != null && !iterator.hasNext() ) + { + iterator = secondIterator; + secondIterator = null; + } + return iterator.next(); + } + + @Override + public void remove() + { + throw new UnsupportedOperationException(); + } + + } }