📄 antclassloader.java
字号:
* @return a stream to the named resource, or <code>null</code> if * the resource cannot be found. */ private InputStream loadBaseResource(String name) { if (parent == null) { return getSystemResourceAsStream(name); } else { return parent.getResourceAsStream(name); } } /** * Returns an inputstream to a given resource in the given file which may * either be a directory or a zip file. * * @param file the file (directory or jar) in which to search for the * resource. Must not be <code>null</code>. * @param resourceName 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 in the given file. */ private InputStream getResourceStream(File file, String resourceName) { try { if (!file.exists()) { return null; } if (file.isDirectory()) { File resource = new File(file, resourceName); if (resource.exists()) { return new FileInputStream(resource); } } else { // is the zip file in the cache ZipFile zipFile = (ZipFile) zipFiles.get(file); if (zipFile == null) { zipFile = new ZipFile(file); zipFiles.put(file, zipFile); } ZipEntry entry = zipFile.getEntry(resourceName); if (entry != null) { return zipFile.getInputStream(entry); } } } catch (Exception e) { log("Ignoring Exception " + e.getClass().getName() + ": " + e.getMessage() + " reading resource " + resourceName + " from " + file, Project.MSG_VERBOSE); } return null; } /** * Tests whether or not the parent classloader should be checked for * a resource before this one. If the resource matches both the * "use parent classloader first" and the "use this classloader first" * lists, the latter takes priority. * * @param resourceName The name of the resource to check. * Must not be <code>null</code>. * * @return whether or not the parent classloader should be checked for a * resource before this one is. */ private boolean isParentFirst(String resourceName) { // default to the global setting and then see // if this class belongs to a package which has been // designated to use a specific loader first // (this one or the parent one) // XXX - shouldn't this always return false in isolated mode? boolean useParentFirst = parentFirst; for (Enumeration e = systemPackages.elements(); e.hasMoreElements();) { String packageName = (String) e.nextElement(); if (resourceName.startsWith(packageName)) { useParentFirst = true; break; } } for (Enumeration e = loaderPackages.elements(); e.hasMoreElements();) { String packageName = (String) e.nextElement(); if (resourceName.startsWith(packageName)) { useParentFirst = false; break; } } return useParentFirst; } /** * Used for isolated resource seaching. * @return the root classloader of AntClassLoader. */ private ClassLoader getRootLoader() { ClassLoader ret = getClass().getClassLoader(); while (ret != null && ret.getParent() != null) { ret = ret.getParent(); } return ret; } /** * Finds the resource with the given name. A resource is * some data (images, audio, text, etc) that can be accessed by class * code in a way that is independent of the location of the code. * * @param name The name of the resource for which a stream is required. * Must not be <code>null</code>. * * @return a URL for reading the resource, or <code>null</code> if the * resource could not be found or the caller doesn't have * adequate privileges to get the resource. */ public URL getResource(String name) { // we need to search the components of the path to see if // we can find the class we want. URL url = null; if (isParentFirst(name)) { url = (parent == null) ? super.getResource(name) : parent.getResource(name); } if (url != null) { log("Resource " + name + " loaded from parent loader", Project.MSG_DEBUG); } else { // try and load from this loader if the parent either didn't find // it or wasn't consulted. Enumeration e = pathComponents.elements(); while (e.hasMoreElements() && url == null) { File pathComponent = (File) e.nextElement(); url = getResourceURL(pathComponent, name); if (url != null) { log("Resource " + name + " loaded from ant loader", Project.MSG_DEBUG); } } } if (url == null && !isParentFirst(name)) { // this loader was first but it didn't find it - try the parent if (ignoreBase) { url = (getRootLoader() == null) ? null : getRootLoader().getResource(name); } else { url = (parent == null) ? super.getResource(name) : parent.getResource(name); } if (url != null) { log("Resource " + name + " loaded from parent loader", Project.MSG_DEBUG); } } if (url == null) { log("Couldn't load Resource " + name, Project.MSG_DEBUG); } return url; } /** * Returns an enumeration of URLs representing all the resources with the * given name by searching the class loader's classpath. * * @param name The resource name to search for. * Must not be <code>null</code>. * @return an enumeration of URLs for the resources * @exception IOException if I/O errors occurs (can't happen) */ protected Enumeration/*<URL>*/ findResources(String name) throws IOException { Enumeration/*<URL>*/ mine = new ResourceEnumeration(name); Enumeration/*<URL>*/ base; if (parent != null && parent != getParent()) { // Delegate to the parent: base = parent.getResources(name); // Note: could cause overlaps in case ClassLoader.this.parent has matches. } else { // ClassLoader.this.parent is already delegated to from // ClassLoader.getResources, no need: base = new CollectionUtils.EmptyEnumeration(); } if (isParentFirst(name)) { // Normal case. return CollectionUtils.append(base, mine); } else if (ignoreBase) { return getRootLoader() == null ? mine : CollectionUtils.append( mine, getRootLoader().getResources(name)); } else { // Inverted. return CollectionUtils.append(mine, base); } } /** * Returns the URL of a given resource in the given file which may * either be a directory or a zip file. * * @param file The file (directory or jar) in which to search for * the resource. Must not be <code>null</code>. * @param resourceName 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 in the given file object. */ protected URL getResourceURL(File file, String resourceName) { try { if (!file.exists()) { return null; } if (file.isDirectory()) { File resource = new File(file, resourceName); if (resource.exists()) { try { return FILE_UTILS.getFileURL(resource); } catch (MalformedURLException ex) { return null; } } } else { ZipFile zipFile = (ZipFile) zipFiles.get(file); if (zipFile == null) { zipFile = new ZipFile(file); zipFiles.put(file, zipFile); } ZipEntry entry = zipFile.getEntry(resourceName); if (entry != null) { try { return new URL("jar:" + FILE_UTILS.getFileURL(file) + "!/" + entry); } catch (MalformedURLException ex) { return null; } } } } catch (Exception e) { e.printStackTrace(); } return null; } /** * Loads a class with this class loader. * * This class attempts to load the class in an order determined by whether * or not the class matches the system/loader package lists, with the * loader package list taking priority. If the classloader is in isolated * mode, failure to load the class in this loader will result in a * ClassNotFoundException. * * @param classname The name of the class to be loaded. * Must not be <code>null</code>. * @param resolve <code>true</code> if all classes upon which this class * depends are to be loaded. * * @return the required Class object * * @exception ClassNotFoundException if the requested class does not exist * on the system classpath (when not in isolated mode) or this loader's * classpath. */ protected synchronized Class loadClass(String classname, boolean resolve) throws ClassNotFoundException { // 'sync' is needed - otherwise 2 threads can load the same class // twice, resulting in LinkageError: duplicated class definition. // findLoadedClass avoids that, but without sync it won't work. Class theClass = findLoadedClass(classname); if (theClass != null) { return theClass; } if (isParentFirst(classname)) { try { theClass = findBaseClass(classname); log("Class " + classname + " loaded from parent loader " + "(parentFirst)", Project.MSG_DEBUG); } catch (ClassNotFoundException cnfe) { theClass = findClass(classname); log("Class " + classname + " loaded from ant loader " + "(parentFirst)", Project.MSG_DEBUG); } } else { try { theClass = findClass(classname); log("Class " + classname + " loaded from ant loader", Project.MSG_DEBUG); } catch (ClassNotFoundException cnfe) { if (ignoreBase) { throw cnfe; } theClass = findBaseClass(classname); log("Class " + classname + " loaded from parent loader", Project.MSG_DEBUG); } } if (resolve) { resolveClass(theClass); } return theClass; } /** * Converts the class dot notation to a filesystem equivalent for * searching purposes. * * @param classname The class name in dot format (eg java.lang.Integer). * Must not be <code>null</code>. * * @return the classname in filesystem format (eg java/lang/Integer.class) */ private String getClassFilename(String classname) { return classname.replace('.', '/') + ".class"; } /** * Define a class given its bytes * * @param container the container from which the class data has been read * may be a directory or a jar/zip file. * * @param classData the bytecode data for the class * @param classname the name of the class * * @return the Class instance created from the given data * * @throws IOException if the class data cannot be read. */ protected Class defineClassFromData(File container, byte[] classData, String classname) throws IOException { definePackage(container, classname); // XXX should instead make a new ProtectionDomain with a CodeSource // corresponding to container.toURI().toURL() and the same // PermissionCollection as Project.class.protectionDomain had return defineClass(classname, classData, 0, classData.length, Project.class.getProtectionDomain()); } /** * Define the package information associated with a class. * * @param container the file containing the class definition. * @param className the class name of for which the package information * is to be determined. * * @exception IOException if the package information cannot be read from the * container. */ protected void definePackage(File container, String className) throws IOException { int classIndex = className.lastIndexOf('.'); if (classIndex == -1) { return; } String packageName = className.substring(0, classIndex); if (getPackage(packageName) != null) { // already defined return; } // define the package now Manifest manifest = getJarManifest(container); if (manifest == null) { definePackage(packageName, null, null, null, null, null, null, null); } else { definePackage(container, packageName, manifest);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -