src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java

changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 384
8f2986ff0235
     1.1 --- a/src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java	Thu Apr 04 19:05:24 2013 -0700
     1.2 +++ b/src/share/jaxws_classes/javax/xml/soap/FactoryFinder.java	Tue Apr 09 14:51:13 2013 +0100
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -39,16 +39,12 @@
    1.11       *            or could not be instantiated
    1.12       */
    1.13      private static Object newInstance(String className,
    1.14 -                                      ClassLoader classLoader)
    1.15 +                                      ClassLoader classLoader,
    1.16 +                                      String defaultFactoryClass)
    1.17          throws SOAPException
    1.18      {
    1.19          try {
    1.20 -            Class spiClass;
    1.21 -            if (classLoader == null) {
    1.22 -                spiClass = Class.forName(className);
    1.23 -            } else {
    1.24 -                spiClass = classLoader.loadClass(className);
    1.25 -            }
    1.26 +            Class spiClass = safeLoadClass(className, classLoader, defaultFactoryClass);
    1.27              return spiClass.newInstance();
    1.28          } catch (ClassNotFoundException x) {
    1.29              throw new SOAPException(
    1.30 @@ -73,68 +69,10 @@
    1.31       *                              a system property
    1.32       * @exception SOAPException if there is a SOAP error
    1.33       */
    1.34 -    static Object find(String factId)
    1.35 +    static Object find(String factoryId)
    1.36          throws SOAPException
    1.37      {
    1.38 -        final ClassLoader classLoader;
    1.39 -        final String factoryId = factId;
    1.40 -        try {
    1.41 -            classLoader = Thread.currentThread().getContextClassLoader();
    1.42 -        } catch (Exception x) {
    1.43 -            throw new SOAPException(x.toString(), x);
    1.44 -        }
    1.45 -
    1.46 -        // Use the system property first
    1.47 -        try {
    1.48 -            String systemProp =
    1.49 -                System.getProperty( factoryId );
    1.50 -            if( systemProp!=null) {
    1.51 -                return newInstance(systemProp, classLoader);
    1.52 -            }
    1.53 -        } catch (SecurityException se) {
    1.54 -        }
    1.55 -
    1.56 -        // try to read from $java.home/lib/jaxm.properties
    1.57 -        try {
    1.58 -            String javah=System.getProperty( "java.home" );
    1.59 -            String configFile = javah + File.separator +
    1.60 -                "lib" + File.separator + "jaxm.properties";
    1.61 -            final File f=new File( configFile );
    1.62 -            if( f.exists()) {
    1.63 -                Properties props=new Properties();
    1.64 -                props.load( new FileInputStream(f));
    1.65 -                String factoryClassName = props.getProperty(factoryId);
    1.66 -                return newInstance(factoryClassName, classLoader);
    1.67 -            }
    1.68 -        } catch(Exception ex ) {
    1.69 -        }
    1.70 -
    1.71 -        String serviceId = "META-INF/services/" + factoryId;
    1.72 -        // try to find services in CLASSPATH
    1.73 -        try {
    1.74 -            InputStream is=null;
    1.75 -            if (classLoader == null) {
    1.76 -                is=ClassLoader.getSystemResourceAsStream(serviceId);
    1.77 -            } else {
    1.78 -                is=classLoader.getResourceAsStream(serviceId);
    1.79 -            }
    1.80 -
    1.81 -            if( is!=null ) {
    1.82 -                BufferedReader rd =
    1.83 -                    new BufferedReader(new InputStreamReader(is, "UTF-8"));
    1.84 -
    1.85 -                String factoryClassName = rd.readLine();
    1.86 -                rd.close();
    1.87 -
    1.88 -                if (factoryClassName != null &&
    1.89 -                    ! "".equals(factoryClassName)) {
    1.90 -                    return newInstance(factoryClassName, classLoader);
    1.91 -                }
    1.92 -            }
    1.93 -        } catch( Exception ex ) {
    1.94 -        }
    1.95 -
    1.96 -        return null;
    1.97 +        return find(factoryId, null, false);
    1.98      }
    1.99  
   1.100      /**
   1.101 @@ -160,11 +98,35 @@
   1.102      static Object find(String factoryId, String fallbackClassName)
   1.103          throws SOAPException
   1.104      {
   1.105 +        return find(factoryId, fallbackClassName, true);
   1.106 +    }
   1.107  
   1.108 -        Object obj = find(factoryId);
   1.109 -        if (obj != null)
   1.110 -            return obj;
   1.111 -
   1.112 +    /**
   1.113 +     * Finds the implementation <code>Class</code> object for the given
   1.114 +     * factory name, or if that fails, finds the <code>Class</code> object
   1.115 +     * for the given default class name, but only if <code>tryFallback</code>
   1.116 +     * is <code>true</code>.  The arguments supplied must be used in order
   1.117 +     * If using the first argument is successful, the second one will not
   1.118 +     * be used.  Note the default class name may be needed even if fallback
   1.119 +     * is not to be attempted, so certain error condiitons can be handled.
   1.120 +     * <P>
   1.121 +     * This method is package private so that this code can be shared.
   1.122 +     *
   1.123 +     * @return the <code>Class</code> object of the specified message factory;
   1.124 +     *         may not be <code>null</code>
   1.125 +     *
   1.126 +     * @param factoryId             the name of the factory to find, which is
   1.127 +     *                              a system property
   1.128 +     * @param defaultClassName      the implementation class name, which is
   1.129 +     *                              to be used only if nothing else
   1.130 +     *                              is found; <code>null</code> to indicate
   1.131 +     *                              that there is no default class name
   1.132 +     * @param tryFallback           whether to try the default class as a
   1.133 +     *                              fallback
   1.134 +     * @exception SOAPException if there is a SOAP error
   1.135 +     */
   1.136 +    static Object find(String factoryId, String defaultClassName,
   1.137 +            boolean tryFallback) throws SOAPException {
   1.138          ClassLoader classLoader;
   1.139          try {
   1.140              classLoader = Thread.currentThread().getContextClassLoader();
   1.141 @@ -172,11 +134,99 @@
   1.142              throw new SOAPException(x.toString(), x);
   1.143          }
   1.144  
   1.145 -        if (fallbackClassName == null) {
   1.146 +        // Use the system property first
   1.147 +        try {
   1.148 +            String systemProp =
   1.149 +                System.getProperty( factoryId );
   1.150 +            if( systemProp!=null) {
   1.151 +                return newInstance(systemProp, classLoader, defaultClassName);
   1.152 +            }
   1.153 +        } catch (SecurityException se) {
   1.154 +        }
   1.155 +
   1.156 +        // try to read from $java.home/lib/jaxm.properties
   1.157 +        try {
   1.158 +            String javah=System.getProperty( "java.home" );
   1.159 +            String configFile = javah + File.separator +
   1.160 +                "lib" + File.separator + "jaxm.properties";
   1.161 +            File f=new File( configFile );
   1.162 +            if( f.exists()) {
   1.163 +                Properties props=new Properties();
   1.164 +                props.load( new FileInputStream(f));
   1.165 +                String factoryClassName = props.getProperty(factoryId);
   1.166 +                return newInstance(factoryClassName, classLoader, defaultClassName);
   1.167 +            }
   1.168 +        } catch(Exception ex ) {
   1.169 +        }
   1.170 +
   1.171 +        String serviceId = "META-INF/services/" + factoryId;
   1.172 +        // try to find services in CLASSPATH
   1.173 +        try {
   1.174 +            InputStream is=null;
   1.175 +            if (classLoader == null) {
   1.176 +                is=ClassLoader.getSystemResourceAsStream(serviceId);
   1.177 +            } else {
   1.178 +                is=classLoader.getResourceAsStream(serviceId);
   1.179 +            }
   1.180 +
   1.181 +            if( is!=null ) {
   1.182 +                BufferedReader rd =
   1.183 +                    new BufferedReader(new InputStreamReader(is, "UTF-8"));
   1.184 +
   1.185 +                String factoryClassName = rd.readLine();
   1.186 +                rd.close();
   1.187 +
   1.188 +                if (factoryClassName != null &&
   1.189 +                    ! "".equals(factoryClassName)) {
   1.190 +                    return newInstance(factoryClassName, classLoader, defaultClassName);
   1.191 +                }
   1.192 +            }
   1.193 +        } catch( Exception ex ) {
   1.194 +        }
   1.195 +
   1.196 +        // If not found and fallback should not be tried, return a null result.
   1.197 +        if (!tryFallback)
   1.198 +            return null;
   1.199 +
   1.200 +        // We didn't find the class through the usual means so try the default
   1.201 +        // (built in) factory if specified.
   1.202 +        if (defaultClassName == null) {
   1.203              throw new SOAPException(
   1.204                  "Provider for " + factoryId + " cannot be found", null);
   1.205          }
   1.206 +        return newInstance(defaultClassName, classLoader, defaultClassName);
   1.207 +    }
   1.208  
   1.209 -        return newInstance(fallbackClassName, classLoader);
   1.210 +    /**
   1.211 +     * Loads the class, provided that the calling thread has an access to the
   1.212 +     * class being loaded. If this is the specified default factory class and it
   1.213 +     * is restricted by package.access we get a SecurityException and can do a
   1.214 +     * Class.forName() on it so it will be loaded by the bootstrap class loader.
   1.215 +     */
   1.216 +    private static Class safeLoadClass(String className,
   1.217 +            ClassLoader classLoader, String defaultFactoryClass)
   1.218 +            throws ClassNotFoundException {
   1.219 +        try {
   1.220 +            // make sure that the current thread has an access to the package of the given name.
   1.221 +            SecurityManager s = System.getSecurityManager();
   1.222 +            if (s != null) {
   1.223 +                int i = className.lastIndexOf('.');
   1.224 +                if (i != -1) {
   1.225 +                    s.checkPackageAccess(className.substring(0, i));
   1.226 +                }
   1.227 +            }
   1.228 +
   1.229 +            if (classLoader == null)
   1.230 +                return Class.forName(className);
   1.231 +            else
   1.232 +                return classLoader.loadClass(className);
   1.233 +        } catch (SecurityException se) {
   1.234 +            // The FactoryFinder is in the bootstrap class loader, so
   1.235 +            // the following should work, but we only attempt it
   1.236 +            // if it the the default class.
   1.237 +            if (className.equals(defaultFactoryClass))
   1.238 +                return Class.forName(className);
   1.239 +            throw se;
   1.240 +        }
   1.241      }
   1.242  }

mercurial