--- old/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java 2015-01-29 16:25:17.817677107 +0300 +++ new/src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/Options.java 2015-01-29 16:25:17.753677109 +0300 @@ -32,18 +32,18 @@ import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.StringWriter; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.List; +import java.util.ServiceLoader; import java.util.Set; import com.sun.codemodel.internal.CodeWriter; @@ -354,9 +354,7 @@ */ public List getAllPlugins() { if(allPlugins==null) { - allPlugins = new ArrayList(); - ClassLoader ucl = getUserClassLoader(SecureLoader.getClassClassLoader(getClass())); - allPlugins.addAll(Arrays.asList(findServices(Plugin.class,ucl))); + allPlugins = findServices(Plugin.class); } return allPlugins; @@ -924,118 +922,44 @@ /** * If a plugin failed to load, report. */ - private static String pluginLoadFailure; + private String pluginLoadFailure; /** * Looks for all "META-INF/services/[className]" files and * create one instance for each class name found inside this file. */ - private static T[] findServices( Class clazz, ClassLoader classLoader ) { - // if true, print debug output - final boolean debug = com.sun.tools.internal.xjc.util.Util.getSystemProperty(Options.class,"findServices")!=null; - - // if we are running on Mustang or Dolphin, use ServiceLoader - // so that we can take advantage of JSR-277 module system. + private List findServices( Class clazz) { + final List result = new ArrayList(); + final boolean debug = getDebugPropertyValue(); try { - Class serviceLoader = Class.forName("java.util.ServiceLoader"); - if(debug) - System.out.println("Using java.util.ServiceLoader"); - Iterable itr = (Iterable)serviceLoader.getMethod("load",Class.class,ClassLoader.class).invoke(null,clazz,classLoader); - List r = new ArrayList(); - for (T t : itr) - r.add(t); - return r.toArray((T[])Array.newInstance(clazz,r.size())); - } catch (ClassNotFoundException e) { - // fall through - } catch (IllegalAccessException e) { - Error x = new IllegalAccessError(); - x.initCause(e); - throw x; - } catch (InvocationTargetException e) { - Throwable x = e.getTargetException(); - if (x instanceof RuntimeException) - throw (RuntimeException) x; - if (x instanceof Error) - throw (Error) x; - throw new Error(x); - } catch (NoSuchMethodException e) { - Error x = new NoSuchMethodError(); - x.initCause(e); - throw x; - } - - String serviceId = "META-INF/services/" + clazz.getName(); - - // used to avoid creating the same instance twice - Set classNames = new HashSet(); - - if(debug) { - System.out.println("Looking for "+serviceId+" for add-ons"); - } - - // try to find services in CLASSPATH - try { - Enumeration e = classLoader.getResources(serviceId); - if(e==null) return (T[])Array.newInstance(clazz,0); - - ArrayList a = new ArrayList(); - while(e.hasMoreElements()) { - URL url = e.nextElement(); - BufferedReader reader=null; - - if(debug) { - System.out.println("Checking "+url+" for an add-on"); - } - - try { - reader = new BufferedReader(new InputStreamReader(url.openStream())); - String impl; - while((impl = reader.readLine())!=null ) { - // try to instanciate the object - impl = impl.trim(); - if(classNames.add(impl)) { - Class implClass = classLoader.loadClass(impl); - if(!clazz.isAssignableFrom(implClass)) { - pluginLoadFailure = impl+" is not a subclass of "+clazz+". Skipping"; - if(debug) - System.out.println(pluginLoadFailure); - continue; - } - if(debug) { - System.out.println("Attempting to instanciate "+impl); - } - a.add(clazz.cast(implClass.newInstance())); - } - } - reader.close(); - } catch( Exception ex ) { - // let it go. - StringWriter w = new StringWriter(); - ex.printStackTrace(new PrintWriter(w)); - pluginLoadFailure = w.toString(); - if(debug) { - System.out.println(pluginLoadFailure); - } - if( reader!=null ) { - try { - reader.close(); - } catch( IOException ex2 ) { - // ignore - } - } - } - } - - return a.toArray((T[])Array.newInstance(clazz,a.size())); + // TCCL allows user plugins to be loaded even if xjc is in jdk + // We have to use our SecureLoader to obtain it because we are trying to avoid SecurityException + final ClassLoader tccl = SecureLoader.getContextClassLoader(); + final ServiceLoader sl = ServiceLoader.load(clazz, tccl); + for (T t : sl) + result.add(t); } catch( Throwable e ) { // ignore any error StringWriter w = new StringWriter(); e.printStackTrace(new PrintWriter(w)); pluginLoadFailure = w.toString(); - if(debug) { + if(debug) System.out.println(pluginLoadFailure); - } - return (T[])Array.newInstance(clazz,0); + } + return result; + } + + private static boolean getDebugPropertyValue() { + final String debugPropertyName = Options.class.getName() + ".findServices"; + if (System.getSecurityManager() != null) { + return AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return Boolean.getBoolean(debugPropertyName); + } + }); + } else { + return Boolean.getBoolean(debugPropertyName); } }