📄 antclassloader.java
字号:
/** * Logs a message through the project object if one has been provided. * * @param message The message to log. * Should not be <code>null</code>. * * @param priority The logging priority of the message. */ protected void log(String message, int priority) { if (project != null) { project.log(message, priority); } // else { // System.out.println(message); // } } /** * Sets the current thread's context loader to this classloader, storing * the current loader value for later resetting. */ public void setThreadContextLoader() { if (isContextLoaderSaved) { throw new BuildException("Context loader has not been reset"); } if (LoaderUtils.isContextLoaderAvailable()) { savedContextLoader = LoaderUtils.getContextClassLoader(); ClassLoader loader = this; if (project != null && "only".equals(project.getProperty("build.sysclasspath"))) { loader = this.getClass().getClassLoader(); } LoaderUtils.setContextClassLoader(loader); isContextLoaderSaved = true; } } /** * Resets the current thread's context loader to its original value. */ public void resetThreadContextLoader() { if (LoaderUtils.isContextLoaderAvailable() && isContextLoaderSaved) { LoaderUtils.setContextClassLoader(savedContextLoader); savedContextLoader = null; isContextLoaderSaved = false; } } /** * Adds an element to the classpath to be searched. * * @param pathElement The path element to add. Must not be * <code>null</code>. * * @exception BuildException if the given path element cannot be resolved * against the project. */ public void addPathElement(String pathElement) throws BuildException { File pathComponent = project != null ? project.resolveFile(pathElement) : new File(pathElement); try { addPathFile(pathComponent); } catch (IOException e) { throw new BuildException(e); } } /** * Add a path component. * This simply adds the file, unlike addPathElement * it does not open jar files and load files from * their CLASSPATH entry in the manifest file. * @param file the jar file or directory to add. */ public void addPathComponent(File file) { if (pathComponents.contains(file)) { return; } pathComponents.addElement(file); } /** * Add a file to the path. * Reads the manifest, if available, and adds any additional class path jars * specified in the manifest. * * @param pathComponent the file which is to be added to the path for * this class loader * * @throws IOException if data needed from the file cannot be read. */ protected void addPathFile(File pathComponent) throws IOException { pathComponents.addElement(pathComponent); if (pathComponent.isDirectory()) { return; } String absPathPlusTimeAndLength = pathComponent.getAbsolutePath() + pathComponent.lastModified() + "-" + pathComponent.length(); String classpath = (String) pathMap.get(absPathPlusTimeAndLength); if (classpath == null) { ZipFile jarFile = null; InputStream manifestStream = null; try { jarFile = new ZipFile(pathComponent); manifestStream = jarFile.getInputStream(new ZipEntry("META-INF/MANIFEST.MF")); if (manifestStream == null) { return; } Reader manifestReader = new InputStreamReader(manifestStream, "UTF-8"); org.apache.tools.ant.taskdefs.Manifest manifest = new org.apache.tools.ant.taskdefs.Manifest(manifestReader); classpath = manifest.getMainSection().getAttributeValue("Class-Path"); } catch (org.apache.tools.ant.taskdefs.ManifestException e) { // ignore } finally { FileUtils.close(manifestStream); if (jarFile != null) { jarFile.close(); } } if (classpath == null) { classpath = ""; } pathMap.put(absPathPlusTimeAndLength, classpath); } if (!"".equals(classpath)) { URL baseURL = FILE_UTILS.getFileURL(pathComponent); StringTokenizer st = new StringTokenizer(classpath); while (st.hasMoreTokens()) { String classpathElement = st.nextToken(); URL libraryURL = new URL(baseURL, classpathElement); if (!libraryURL.getProtocol().equals("file")) { log("Skipping jar library " + classpathElement + " since only relative URLs are supported by this" + " loader", Project.MSG_VERBOSE); continue; } String decodedPath = Locator.decodeUri(libraryURL.getFile()); File libraryFile = new File(decodedPath); if (libraryFile.exists() && !isInPath(libraryFile)) { addPathFile(libraryFile); } } } } /** * Returns the classpath this classloader will consult. * * @return the classpath used for this classloader, with elements * separated by the path separator for the system. */ public String getClasspath() { StringBuffer sb = new StringBuffer(); boolean firstPass = true; Enumeration componentEnum = pathComponents.elements(); while (componentEnum.hasMoreElements()) { if (!firstPass) { sb.append(System.getProperty("path.separator")); } else { firstPass = false; } sb.append(((File) componentEnum.nextElement()).getAbsolutePath()); } return sb.toString(); } /** * Sets whether this classloader should run in isolated mode. In * isolated mode, classes not found on the given classpath will * not be referred to the parent class loader but will cause a * ClassNotFoundException. * * @param isolated Whether or not this classloader should run in * isolated mode. */ public synchronized void setIsolated(boolean isolated) { ignoreBase = isolated; } /** * Forces initialization of a class in a JDK 1.1 compatible, albeit hacky * way. * * @param theClass The class to initialize. * Must not be <code>null</code>. * * @deprecated since 1.6.x. * Use Class.forName with initialize=true instead. */ public static void initializeClass(Class theClass) { // ***HACK*** We ask the VM to create an instance // by voluntarily providing illegal arguments to force // the VM to run the class' static initializer, while // at the same time not running a valid constructor. final Constructor[] cons = theClass.getDeclaredConstructors(); //At least one constructor is guaranteed to be there, but check anyway. if (cons != null) { if (cons.length > 0 && cons[0] != null) { final String[] strs = new String[NUMBER_OF_STRINGS]; try { cons[0].newInstance((Object[]) strs); // Expecting an exception to be thrown by this call: // IllegalArgumentException: wrong number of Arguments } catch (Exception e) { // Ignore - we are interested only in the side // effect - that of getting the static initializers // invoked. As we do not want to call a valid // constructor to get this side effect, an // attempt is made to call a hopefully // invalid constructor - come on, nobody // would have a constructor that takes in // 256 String arguments ;-) // (In fact, they can't - according to JVM spec // section 4.10, the number of method parameters is limited // to 255 by the definition of a method descriptor. // Constructors count as methods here.) } } } } /** * Adds a package root to the list of packages which must be loaded on the * parent loader. * * All subpackages are also included. * * @param packageRoot The root of all packages to be included. * Should not be <code>null</code>. */ public void addSystemPackageRoot(String packageRoot) { systemPackages.addElement(packageRoot + (packageRoot.endsWith(".") ? "" : ".")); } /** * Adds a package root to the list of packages which must be loaded using * this loader. * * All subpackages are also included. * * @param packageRoot The root of all packages to be included. * Should not be <code>null</code>. */ public void addLoaderPackageRoot(String packageRoot) { loaderPackages.addElement(packageRoot + (packageRoot.endsWith(".") ? "" : ".")); } /** * Loads a class through this class loader even if that class is available * on the parent classpath. * * This ensures that any classes which are loaded by the returned class * will use this classloader. * * @param classname The name of the class to be loaded. * Must not be <code>null</code>. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on this loader's classpath. */ public Class forceLoadClass(String classname) throws ClassNotFoundException { log("force loading " + classname, Project.MSG_DEBUG); Class theClass = findLoadedClass(classname); if (theClass == null) { theClass = findClass(classname); } return theClass; } /** * Loads a class through this class loader but defer to the parent class * loader. * * This ensures that instances of the returned class will be compatible * with instances which have already been loaded on the parent * loader. * * @param classname The name of the class to be loaded. * Must not be <code>null</code>. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on this loader's classpath. */ public Class forceLoadSystemClass(String classname) throws ClassNotFoundException { log("force system loading " + classname, Project.MSG_DEBUG); Class theClass = findLoadedClass(classname); if (theClass == null) { theClass = findBaseClass(classname); } return theClass; } /** * Returns a stream to read the requested resource name. * * @param name The name of the resource for which a stream is required. * Must not be <code>null</code>. * * @return a stream to the required resource or <code>null</code> if the * resource cannot be found on the loader's classpath. */ public InputStream getResourceAsStream(String name) { InputStream resourceStream = null; if (isParentFirst(name)) { resourceStream = loadBaseResource(name); if (resourceStream != null) { log("ResourceStream for " + name + " loaded from parent loader", Project.MSG_DEBUG); } else { resourceStream = loadResource(name); if (resourceStream != null) { log("ResourceStream for " + name + " loaded from ant loader", Project.MSG_DEBUG); } } } else { resourceStream = loadResource(name); if (resourceStream != null) { log("ResourceStream for " + name + " loaded from ant loader", Project.MSG_DEBUG); } else { resourceStream = loadBaseResource(name); if (resourceStream != null) { log("ResourceStream for " + name + " loaded from parent loader", Project.MSG_DEBUG); } } } if (resourceStream == null) { log("Couldn't load ResourceStream for " + name, Project.MSG_DEBUG); } return resourceStream; } /** * Returns a stream to read the requested resource name from this loader. * * @param name The name of the resource for which a stream is required. * Must not be <code>null</code>. * * @return a stream to the required resource or <code>null</code> if * the resource cannot be found on the loader's classpath. */ private InputStream loadResource(String name) { // we need to search the components of the path to see if we can // find the class we want. InputStream stream = null; Enumeration e = pathComponents.elements(); while (e.hasMoreElements() && stream == null) { File pathComponent = (File) e.nextElement(); stream = getResourceStream(pathComponent, name); } return stream; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -