📄 objectfactory.java
字号:
} } // debugPrintln(String) /** * 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 /** * Create an instance of a class using the specified ClassLoader */ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { // assert(className != null); try{ Class providerClass = findProviderClass(className, cl, doFallback); Object instance = providerClass.newInstance(); if (DEBUG) debugPrintln("created new instance of " + providerClass + " using ClassLoader: " + cl); return instance; } catch (ClassNotFoundException x) { throw new ConfigurationError( "Provider " + className + " not found", x); } catch (Exception x) { throw new ConfigurationError( "Provider " + className + " could not be instantiated: " + x, x); } } /** * Find a Class using the specified ClassLoader */ static Class findProviderClass(String className, ClassLoader cl, boolean doFallback) throws ClassNotFoundException, ConfigurationError { //throw security exception if the calling thread is not allowed to access the package //restrict the access to package as speicified in java.security policy SecurityManager security = System.getSecurityManager(); if (security != null) { final int lastDot = className.lastIndexOf("."); String packageName = className; if (lastDot != -1) packageName = className.substring(0, lastDot); security.checkPackageAccess(packageName); } Class providerClass; if (cl == null) { // XXX Use the bootstrap ClassLoader. There is no way to // load a class using the bootstrap ClassLoader that works // in both JDK 1.1 and Java 2. However, this should still // work b/c the following should be true: // // (cl == null) iff current ClassLoader == null // // Thus Class.forName(String) will use the current // ClassLoader which will be the bootstrap ClassLoader. providerClass = Class.forName(className); } else { try { providerClass = cl.loadClass(className); } catch (ClassNotFoundException x) { if (doFallback) { // Fall back to current classloader ClassLoader current = ObjectFactory.class.getClassLoader(); if (current == null) { providerClass = Class.forName(className); } else if (cl != current) { cl = current; providerClass = cl.loadClass(className); } else { throw x; } } else { throw x; } } } return providerClass; } /* * 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; } // // Classes // /** * A configuration error. */ static final class ConfigurationError extends Error { /** Serialization version. */ static final long serialVersionUID = 8521878292694272124L; // // Data // /** Exception. */ private Exception exception; // // Constructors // /** * Construct a new instance with the specified detail string and * exception. */ ConfigurationError(String msg, Exception x) { super(msg); this.exception = x; } // <init>(String,Exception) // // methods // /** Returns the exception associated to this error. */ Exception getException() { return exception; } // getException():Exception } // class ConfigurationError} // class ObjectFactory
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -