jaxws/src/java.xml.bind/share/classes/javax/xml/bind/ServiceLoaderUtil.java
changeset 31109 a542f8dcbbf8
parent 29839 6d5d546e953b
equal deleted inserted replaced
31008:5b500c93ce48 31109:a542f8dcbbf8
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package javax.xml.bind;
    26 package javax.xml.bind;
    27 
    27 
    28 import java.io.File;
    28 import java.lang.reflect.InvocationTargetException;
    29 import java.io.FileInputStream;
       
    30 import java.io.IOException;
       
    31 import java.lang.reflect.Method;
    29 import java.lang.reflect.Method;
    32 import java.security.AccessController;
       
    33 import java.security.PrivilegedAction;
       
    34 import java.util.Iterator;
    30 import java.util.Iterator;
    35 import java.util.Properties;
       
    36 import java.util.ServiceLoader;
    31 import java.util.ServiceLoader;
    37 import java.util.logging.Level;
    32 import java.util.logging.Level;
    38 import java.util.logging.Logger;
    33 import java.util.logging.Logger;
    39 
    34 
    40 /**
    35 /**
    47 class ServiceLoaderUtil {
    42 class ServiceLoaderUtil {
    48 
    43 
    49     private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "com.sun.org.glassfish.hk2.osgiresourcelocator.ServiceLoader";
    44     private static final String OSGI_SERVICE_LOADER_CLASS_NAME = "com.sun.org.glassfish.hk2.osgiresourcelocator.ServiceLoader";
    50     private static final String OSGI_SERVICE_LOADER_METHOD_NAME = "lookupProviderClasses";
    45     private static final String OSGI_SERVICE_LOADER_METHOD_NAME = "lookupProviderClasses";
    51 
    46 
    52     static <P> P firstByServiceLoader(Class<P> spiClass, Logger logger) {
    47     static <P, T extends Exception> P firstByServiceLoader(Class<P> spiClass,
       
    48                                                            Logger logger,
       
    49                                                            ExceptionHandler<T> handler) throws T {
    53         // service discovery
    50         // service discovery
    54         ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass);
    51         try {
    55         for (P impl : serviceLoader) {
    52             ServiceLoader<P> serviceLoader = ServiceLoader.load(spiClass);
    56             logger.fine("ServiceProvider loading Facility used; returning object [" + impl.getClass().getName() + "]");
    53 
    57             return impl;
    54             for (P impl : serviceLoader) {
       
    55                 logger.fine("ServiceProvider loading Facility used; returning object [" +
       
    56                         impl.getClass().getName() + "]");
       
    57 
       
    58                 return impl;
       
    59             }
       
    60         } catch (Throwable t) {
       
    61             throw handler.createException(t, "Error while searching for service [" + spiClass.getName() + "]");
    58         }
    62         }
    59         return null;
    63         return null;
    60     }
    64     }
    61 
    65 
    62     static boolean isOsgi(Logger logger) {
    66     static Object lookupUsingOSGiServiceLoader(String factoryId, Logger logger) {
    63         try {
       
    64             Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
       
    65             return true;
       
    66         } catch (ClassNotFoundException ignored) {
       
    67             logger.log(Level.FINE, "OSGi classes not found, OSGi not available.", ignored);
       
    68         }
       
    69         return false;
       
    70     }
       
    71 
    67 
    72     static Object lookupUsingOSGiServiceLoader(String factoryId, Logger logger) {
       
    73         try {
    68         try {
    74             // Use reflection to avoid having any dependendcy on ServiceLoader class
    69             // Use reflection to avoid having any dependendcy on ServiceLoader class
    75             Class serviceClass = Class.forName(factoryId);
    70             Class serviceClass = Class.forName(factoryId);
    76             Class target = Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
    71             Class target = Class.forName(OSGI_SERVICE_LOADER_CLASS_NAME);
    77             Method m = target.getMethod(OSGI_SERVICE_LOADER_METHOD_NAME, Class.class);
    72             Method m = target.getMethod(OSGI_SERVICE_LOADER_METHOD_NAME, Class.class);
    78             Iterator iter = ((Iterable) m.invoke(null, serviceClass)).iterator();
    73             Iterator iter = ((Iterable) m.invoke(null, serviceClass)).iterator();
    79             if (iter.hasNext()) {
    74             if (iter.hasNext()) {
    80                 Object next = iter.next();
    75                 Object next = iter.next();
    81                 logger.fine("Found implementation using OSGi facility; returning object [" + next.getClass().getName() + "].");
    76                 logger.fine("Found implementation using OSGi facility; returning object [" +
       
    77                         next.getClass().getName() + "].");
    82                 return next;
    78                 return next;
    83             } else {
    79             } else {
    84                 return null;
    80                 return null;
    85             }
    81             }
    86         } catch (Exception ignored) {
    82         } catch (IllegalAccessException |
       
    83                 InvocationTargetException |
       
    84                 ClassNotFoundException |
       
    85                 NoSuchMethodException ignored) {
       
    86 
    87             logger.log(Level.FINE, "Unable to find from OSGi: [" + factoryId + "]", ignored);
    87             logger.log(Level.FINE, "Unable to find from OSGi: [" + factoryId + "]", ignored);
    88             return null;
    88             return null;
    89         }
    89         }
    90     }
       
    91 
       
    92     static String propertyFileLookup(final String configFullPath, final String factoryId) throws IOException {
       
    93         File f = new File(configFullPath);
       
    94         String factoryClassName = null;
       
    95         if (f.exists()) {
       
    96             Properties props = new Properties();
       
    97             FileInputStream stream = null;
       
    98             try {
       
    99                 stream = new FileInputStream(f);
       
   100                 props.load(stream);
       
   101                 factoryClassName = props.getProperty(factoryId);
       
   102             } finally {
       
   103                 if (stream != null) {
       
   104                     try {
       
   105                         stream.close();
       
   106                     } catch (IOException ignored) {
       
   107                     }
       
   108                 }
       
   109             }
       
   110         }
       
   111         return factoryClassName;
       
   112     }
    90     }
   113 
    91 
   114     static void checkPackageAccess(String className) {
    92     static void checkPackageAccess(String className) {
   115         // make sure that the current thread has an access to the package of the given name.
    93         // make sure that the current thread has an access to the package of the given name.
   116         SecurityManager s = System.getSecurityManager();
    94         SecurityManager s = System.getSecurityManager();
   128         } else {
   106         } else {
   129             return classLoader.loadClass(className);
   107             return classLoader.loadClass(className);
   130         }
   108         }
   131     }
   109     }
   132 
   110 
   133     /**
   111     // Returns instance of required class. It checks package access (security)
   134      * Returns instance of required class. It checks package access (security) unless it is defaultClassname. It means if you
   112     // unless it is defaultClassname. It means if you are trying to instantiate
   135      * are trying to instantiate default implementation (fallback), pass the class name to both first and second parameter.
   113     // default implementation (fallback), pass the class name to both first and second parameter.
   136      *
   114     static <T extends Exception> Object newInstance(String className,
   137      * @param className          class to be instantiated
   115                                                     String defaultImplClassName,
   138      * @param isDefaultClassname says whether default implementation class
   116                                                     final ExceptionHandler<T> handler) throws T {
   139      * @param handler            exception handler - necessary for wrapping exceptions and logging
       
   140      * @param <T>                Type of exception being thrown (necessary to distinguish between Runtime and checked exceptions)
       
   141      * @return instantiated object or throws Runtime/checked exception, depending on ExceptionHandler's type
       
   142      * @throws T
       
   143      */
       
   144     static <T extends Exception> Object newInstance(String className, String defaultImplClassName, final ExceptionHandler<T> handler) throws T {
       
   145         try {
   117         try {
   146             return safeLoadClass(className, defaultImplClassName, contextClassLoader(handler)).newInstance();
   118             return safeLoadClass(className, defaultImplClassName, contextClassLoader(handler)).newInstance();
   147         } catch (ClassNotFoundException x) {
   119         } catch (ClassNotFoundException x) {
   148             throw handler.createException(x, "Provider " + className + " not found");
   120             throw handler.createException(x, "Provider " + className + " not found");
   149         } catch (Exception x) {
   121         } catch (Exception x) {
   150             throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x);
   122             throw handler.createException(x, "Provider " + className + " could not be instantiated: " + x);
   151         }
   123         }
   152     }
   124     }
   153 
   125 
   154     static Class safeLoadClass(String className, String defaultImplClassName, ClassLoader classLoader) throws ClassNotFoundException {
   126     static Class safeLoadClass(String className,
       
   127                                String defaultImplClassName,
       
   128                                ClassLoader classLoader) throws ClassNotFoundException {
       
   129 
   155         try {
   130         try {
   156             checkPackageAccess(className);
   131             checkPackageAccess(className);
   157         } catch (SecurityException se) {
   132         } catch (SecurityException se) {
   158             // anyone can access the platform default factory class without permission
   133             // anyone can access the platform default factory class without permission
   159             if (defaultImplClassName != null && defaultImplClassName.equals(className)) {
   134             if (defaultImplClassName != null && defaultImplClassName.equals(className)) {
   161             }
   136             }
   162             // not platform default implementation ...
   137             // not platform default implementation ...
   163             throw se;
   138             throw se;
   164         }
   139         }
   165         return nullSafeLoadClass(className, classLoader);
   140         return nullSafeLoadClass(className, classLoader);
   166     }
       
   167 
       
   168     static String getJavaHomeLibConfigPath(String filename) {
       
   169         String javah = AccessController.doPrivileged(new PrivilegedAction<String>() {
       
   170             @Override
       
   171             public String run() {
       
   172                 return System.getProperty("java.home");
       
   173             }
       
   174         });
       
   175         return javah + File.separator + "lib" + File.separator + filename;
       
   176     }
   141     }
   177 
   142 
   178     static ClassLoader contextClassLoader(ExceptionHandler exceptionHandler) throws Exception {
   143     static ClassLoader contextClassLoader(ExceptionHandler exceptionHandler) throws Exception {
   179         try {
   144         try {
   180             return Thread.currentThread().getContextClassLoader();
   145             return Thread.currentThread().getContextClassLoader();