Ejemplo n.º 1
0
  /** Figure out which ClassLoader to use. For JDK 1.2 and later use the context ClassLoader. */
  static ClassLoader findClassLoader() throws ConfigurationError {
    SecuritySupport ss = SecuritySupport.getInstance();

    // Figure out which ClassLoader to use for loading the provider
    // class.  If there is a Context ClassLoader then use it.
    ClassLoader context = ss.getContextClassLoader();
    ClassLoader system = ss.getSystemClassLoader();

    ClassLoader chain = system;
    while (true) {
      if (context == chain) {
        // Assert: we are on JDK 1.1 or we have no Context ClassLoader
        // or any Context ClassLoader in chain of system classloader
        // (including extension ClassLoader) so extend to widest
        // ClassLoader (always look in system ClassLoader if Xerces
        // is in boot/extension/system classpath and in current
        // ClassLoader otherwise); normal classloaders delegate
        // back to system ClassLoader first so this widening doesn't
        // change the fact that context ClassLoader will be consulted
        ClassLoader current = ObjectFactory.class.getClassLoader();

        chain = system;
        while (true) {
          if (current == chain) {
            // Assert: Current ClassLoader in chain of
            // boot/extension/system ClassLoaders
            return system;
          }
          if (chain == null) {
            break;
          }
          chain = ss.getParentClassLoader(chain);
        }

        // Assert: Current ClassLoader not in chain of
        // boot/extension/system ClassLoaders
        return current;
      }

      if (chain == null) {
        // boot ClassLoader reached
        break;
      }

      // Check for any extension ClassLoaders in chain up to
      // boot ClassLoader
      chain = ss.getParentClassLoader(chain);
    }
    ;

    // Assert: Context ClassLoader not in chain of
    // boot/extension/system ClassLoaders
    return context;
  } // findClassLoader():ClassLoader
Ejemplo n.º 2
0
  /*
   * Try to find provider using Jar Service Provider Mechanism
   *
   * @return instance of provider class if found or null
   */
  private static Object findJarServiceProvider(String factoryId) throws ConfigurationError {
    SecuritySupport ss = SecuritySupport.getInstance();
    String serviceId = "META-INF/services/" + factoryId;
    InputStream is = null;

    // First try the Context ClassLoader
    ClassLoader cl = findClassLoader();

    is = ss.getResourceAsStream(cl, serviceId);

    // If no provider found then try the current ClassLoader
    if (is == null) {
      ClassLoader current = ObjectFactory.class.getClassLoader();
      if (cl != current) {
        cl = current;
        is = ss.getResourceAsStream(cl, serviceId);
      }
    }

    if (is == null) {
      // No provider found
      return null;
    }

    if (DEBUG) debugPrintln("found jar resource=" + serviceId + " using ClassLoader: " + cl);

    // Read the service provider name in UTF-8 as specified in
    // the jar spec.  Unfortunately this fails in Microsoft
    // VJ++, which does not implement the UTF-8
    // encoding. Theoretically, we should simply let it fail in
    // that case, since the JVM is obviously broken if it
    // doesn't support such a basic standard.  But since there
    // are still some users attempting to use VJ++ for
    // development, we have dropped in a fallback which makes a
    // second attempt using the platform's default encoding. In
    // VJ++ this is apparently ASCII, which is a subset of
    // UTF-8... and since the strings we'll be reading here are
    // also primarily limited to the 7-bit ASCII range (at
    // least, in English versions), this should work well
    // enough to keep us on the air until we're ready to
    // officially decommit from VJ++. [Edited comment from
    // jkesselm]
    BufferedReader rd;
    try {
      rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
    } catch (java.io.UnsupportedEncodingException e) {
      rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
    }

    String factoryClassName = null;
    try {
      // XXX Does not handle all possible input as specified by the
      // Jar Service Provider specification
      factoryClassName = rd.readLine();
    } catch (IOException x) {
      // No provider found
      return null;
    } finally {
      try {
        // try to close the reader.
        rd.close();
      }
      // Ignore the exception.
      catch (IOException exc) {
      }
    }

    if (factoryClassName != null && !"".equals(factoryClassName)) {
      if (DEBUG) debugPrintln("found in resource, value=" + factoryClassName);

      // Note: here we do not want to fall back to the current
      // ClassLoader because we want to avoid the case where the
      // resource file was found using one ClassLoader and the
      // provider class was instantiated using a different one.
      return newInstance(factoryClassName, cl, false);
    }

    // No provider found
    return null;
  }
Ejemplo n.º 3
0
  /**
   * Finds the implementation Class object in the specified order. The specified order is the
   * following:
   *
   * <ol>
   *   <li>query the system property using <code>System.getProperty</code>
   *   <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
   *   <li>read <code>META-INF/services/<i>factoryId</i></code> file
   *   <li>use fallback classname
   * </ol>
   *
   * @return Class object of factory, never null
   * @param factoryId Name of the factory to find, same as a property name
   * @param propertiesFilename The filename in the $java.home/lib directory of the properties file.
   *     If none specified, ${java.home}/lib/xerces.properties will be used.
   * @param fallbackClassName Implementation class name, if nothing else is found. Use null to mean
   *     no fallback.
   * @exception ObjectFactory.ConfigurationError
   */
  static Object createObject(String factoryId, String propertiesFilename, String fallbackClassName)
      throws ConfigurationError {
    if (DEBUG) debugPrintln("debug is on");

    SecuritySupport ss = SecuritySupport.getInstance();
    ClassLoader cl = findClassLoader();

    // Use the system property first
    try {
      String systemProp = ss.getSystemProperty(factoryId);
      if (systemProp != null) {
        if (DEBUG) debugPrintln("found system property, value=" + systemProp);
        return newInstance(systemProp, cl, true);
      }
    } catch (SecurityException se) {
      // Ignore and continue w/ next location
    }

    // JAXP specific change
    // always use fallback class to avoid the expense of constantly
    // "stat"ing a non-existent "xerces.properties" and jar SPI entry
    // see CR 6400863: Expensive creating of SAX parser in Mustang
    if (true) {
      if (fallbackClassName == null) {
        throw new ConfigurationError("Provider for " + factoryId + " cannot be found", null);
      }

      if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
      return newInstance(fallbackClassName, cl, true);
    }

    // Try to read from propertiesFilename, or $java.home/lib/xerces.properties
    String factoryClassName = null;
    // no properties file name specified; use $JAVA_HOME/lib/xerces.properties:
    if (propertiesFilename == null) {
      File propertiesFile = null;
      boolean propertiesFileExists = false;
      try {
        String javah = ss.getSystemProperty("java.home");
        propertiesFilename =
            javah + File.separator + "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
        propertiesFile = new File(propertiesFilename);
        propertiesFileExists = ss.getFileExists(propertiesFile);
      } catch (SecurityException e) {
        // try again...
        fLastModified = -1;
        fXercesProperties = null;
      }

      synchronized (ObjectFactory.class) {
        boolean loadProperties = false;
        FileInputStream fis = null;
        try {
          // file existed last time
          if (fLastModified >= 0) {
            if (propertiesFileExists
                && (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
              loadProperties = true;
            } else {
              // file has stopped existing...
              if (!propertiesFileExists) {
                fLastModified = -1;
                fXercesProperties = null;
              } // else, file wasn't modified!
            }
          } else {
            // file has started to exist:
            if (propertiesFileExists) {
              loadProperties = true;
              fLastModified = ss.getLastModified(propertiesFile);
            } // else, nothing's changed
          }
          if (loadProperties) {
            // must never have attempted to read xerces.properties before (or it's outdeated)
            fXercesProperties = new Properties();
            fis = ss.getFileInputStream(propertiesFile);
            fXercesProperties.load(fis);
          }
        } catch (Exception x) {
          fXercesProperties = null;
          fLastModified = -1;
          // assert(x instanceof FileNotFoundException
          //        || x instanceof SecurityException)
          // In both cases, ignore and continue w/ next location
        } finally {
          // try to close the input stream if one was opened.
          if (fis != null) {
            try {
              fis.close();
            }
            // Ignore the exception.
            catch (IOException exc) {
            }
          }
        }
      }
      if (fXercesProperties != null) {
        factoryClassName = fXercesProperties.getProperty(factoryId);
      }
    } else {
      FileInputStream fis = null;
      try {
        fis = ss.getFileInputStream(new File(propertiesFilename));
        Properties props = new Properties();
        props.load(fis);
        factoryClassName = props.getProperty(factoryId);
      } catch (Exception x) {
        // assert(x instanceof FileNotFoundException
        //        || x instanceof SecurityException)
        // In both cases, ignore and continue w/ next location
      } finally {
        // try to close the input stream if one was opened.
        if (fis != null) {
          try {
            fis.close();
          }
          // Ignore the exception.
          catch (IOException exc) {
          }
        }
      }
    }
    if (factoryClassName != null) {
      if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
      return newInstance(factoryClassName, cl, true);
    }

    // Try Jar Service Provider Mechanism
    Object provider = findJarServiceProvider(factoryId);
    if (provider != null) {
      return provider;
    }

    if (fallbackClassName == null) {
      throw new ConfigurationError("Provider for " + factoryId + " cannot be found", null);
    }

    if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
    return newInstance(fallbackClassName, cl, true);
  } // createObject(String,String,String):Object