⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adaptiveclassloader.java

📁 这是一个法律事务所系统源码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1997-1999 The Java Apache Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the Java Apache  *    Project for use in the Apache JServ servlet engine project *    <http://java.apache.org/>." * * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and  *    "Java Apache Project" must not be used to endorse or promote products  *    derived from this software without prior written permission. * * 5. Products derived from this software may not be called "Apache JServ" *    nor may "Apache" nor "Apache JServ" appear in their names without  *    prior written permission of the Java Apache Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the Java Apache  *    Project for use in the Apache JServ servlet engine project *    <http://java.apache.org/>." *     * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many * individuals on behalf of the Java Apache Group. For more information * on the Java Apache Project and the Apache JServ Servlet Engine project, * please see <http://java.apache.org/>. * */package org.apache.tomcat.loader;//package org.apache.java.lang;import java.io.*;import java.lang.*;import java.net.*;import java.text.*;import java.util.*;import java.util.zip.*;import java.security.*;/** * A class loader that loads classes from directories and/or zip-format * file such as JAR file. It tracks the modification time of the classes * it loads to permit reloading through re-instantiation. * <P> * When the classloader reports its creator that one of the classes it * has loaded has changed on disk, it should discard the classloader * and create a new instance using <CODE>reinstantiate</CODE>. * The classes are then reloaded into the new classloader as required. * * <P>The classloader can also load resources, which are a means * for packaging application data such as images within a jar file * or directory. * * <P>The classloader always first tries to load classes and resources * from the system, and uses it's own path if that fails. This is also * done if an empty repository is passed at construction. * * <P><B>How autoreload works:</B></P> * * <P>The Java VM considers two classes the same if they have the same * fully-qualified name <B>and</B> if they were loaded from the same * <CODE>ClassLoader</CODE>. * * <P>There is no way for a classloader to 'undefine' a class once it * has been loaded.  However, the servlet engine can discard a * classloader and the classes it contains, causing the * * <P>The <CODE>JServServletManager</CODE> creates a new instance of * the classloader each time it detects that any of the loaded classes * have changed. * * <P>Before terminating, all servlets are destroyed. * * <P>According to the Java Language Specification (JLS), classes may * be garbage-collected when there are no longer any instances of that * class and the <CODE>java.lang.Class</CODE> object is finalizable. * It is intended that this be the case when a <CODE>JServClassLoader</CODE> * is discarded. * * <P>Many VM releases did not implement class garbage collection * properly.  In such a VM, the memory usage will continue to grow if * autoreloading is enable.  Running the VM with * <CODE>-verbosegc</CODE> (or the corresponding option for * non-Javasoft VMs) may give some debugging information. * * <P>It is important that the <CODE>destroy</CODE> method be * implemented properly, as servlets may be destroyed and * reinitialized several times in the life of a VM. * * @author Francis J. Lacoste * @author Martin Pool * @author Jim Heintz * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> * @version $Revision: 1.9.2.2 $ $Date: 2000/11/16 22:04:42 $ * @see java.lang.ClassLoader */public class AdaptiveClassLoader extends ClassLoader {    private static final int debug=0;        /**     * Instance of the SecurityManager installed.     */    static protected SecurityManager sm;    /**     * Generation counter, incremented for each classloader as they are     * created.     */    static private int generationCounter = 0;    /**     * Generation number of the classloader, used to distinguish between     * different instances.     */    private int generation;    /**     * Cache of the loaded classes. This contains ClassCacheEntry keyed     * by class names.     */    protected Hashtable cache;    /**     * The classpath which this classloader searches for class definitions.     * Each element of the vector should be either a directory, a .zip     * file, or a .jar file.     * <p>     * It may be empty when only system classes are controlled.     */    protected Vector repository;    /**     * A parent class loader for delegation of finding a class definition.     * JDK 1.2 contains parent class loaders as part of java.lang.ClassLoader, the parent     * being passed to a constructor, and retreived with getParent() method. For JDK 1.1     * compatibility, we'll duplicate the 1.2 private member var.     */    protected ClassLoader parent;        /**     * Private class used to maintain information about the classes that     * we loaded.     */    private static class ClassCacheEntry {        /**         * The actual loaded class         */        Class loadedClass;        /**         * The file from which this class was loaded; or null if         * it was loaded from the system.         */        File origin;        /**         * The time at which the class was loaded from the origin         * file, in ms since the epoch.         */        long lastModified;        /**         * Check whether this class was loaded from the system.         */        public boolean isSystemClass() {            return origin == null;        }    }        //------------------------------------------------------- Constructors    /**     * Creates a new class loader that will load classes from specified     * class repositories, delegating first to the passed parent for definitions.     *     * @param classRepository An set of File classes indicating     *        directories and/or zip/jar files. It may be empty when     *        only system classes are loaded.     * @param theParent A containing class loader for initial delegation of class     *        definition serach.     * @throw java.lang.IllegalArgumentException if the objects contained     *        in the vector are not a file instance or the file is not     *        a valid directory or a zip/jar file.     */    public AdaptiveClassLoader() {	// Create the cache of loaded classes	cache = new Hashtable();    }    public void setRepository( Vector classRepository ) 	throws IllegalArgumentException    {	// Verify that all the repository are valid.	Enumeration e = classRepository.elements();	while(e.hasMoreElements()) {	    ClassRepository cp = (ClassRepository) e.nextElement();	    File file;            String[] files;            int i;            // Check to see if element is a File instance.            try {                file = cp.getFile();            } catch (ClassCastException objectIsNotFile) {                throw new IllegalArgumentException("Object " + cp                    + "is not a valid \"File\" instance");            }	    //	    org.apache.java.io.XXX            files=SimpleFileFilter.fileOrFiles(file);            if (files!=null)            {                for (i=0;i<files.length;i++)                {                    file=new File(files[i]);                    // Check to see if we have proper access.                    if (!file.exists()) {                        throw new IllegalArgumentException("Repository "                        + file.getAbsolutePath() + " doesn't exist!");                    } else if (!file.canRead()) {                        throw new IllegalArgumentException(                        "Do not have read access for file "                        + file.getAbsolutePath());                    }                    // Check that it is a directory or zip/jar file                    if (!(file.isDirectory() || isZipOrJarArchive(file))) {                        throw new IllegalArgumentException(                           file.getAbsolutePath()                           + " is not a directory or zip/jar file"                           + " or if it's a zip/jar file then it is corrupted.");                    }                }            }        }        // Store the class repository for use        this.repository = classRepository;        // Increment and store generation counter        this.generation = generationCounter++;    }    public void setParent( ClassLoader p ) {	parent=p;    }    void log( String s ) {	System.out.println("AdaptiveClassLoader: " + s );    }        //------------------------------------------------------- Methods    /**     * Test if a file is a ZIP or JAR archive.     *     * @param file the file to be tested.     * @return true if the file is a ZIP/JAR archive, false otherwise.     */    private boolean isZipOrJarArchive(File file) {        boolean isArchive = true;        ZipFile zipFile = null;        try {            zipFile = new ZipFile(file);        } catch (ZipException zipCurrupted) {            isArchive = false;        } catch (IOException anyIOError) {            isArchive = false;        } finally {            if (zipFile != null) {                try {                    zipFile.close();                } catch (IOException ignored) {}            }        }        return isArchive;    }    /**     * Check to see if a given class should be reloaded because of a     * modification to the original class.     *     * @param className The name of the class to check for modification.     */    public synchronized boolean shouldReload(String classname) {	return checkExpired( classname );    }    protected boolean checkExpired(String classname ) {	ClassCacheEntry entry = (ClassCacheEntry) cache.get(classname);        if (entry == null) {            // class wasn't even loaded            return false;        } else if (entry.isSystemClass()) {            // System classes cannot be reloaded            return false;        } else {            return (entry.origin.lastModified() != entry.lastModified);                }    }    /**     * Check whether the classloader should be reinstantiated.     * <P>     * The classloader must be replaced if there is any class whose        * origin file has changed since it was last loaded.     */    public synchronized boolean shouldReload() {        // Check whether any class has changed        Enumeration e = cache.elements();        while (e.hasMoreElements()) {            ClassCacheEntry entry = (ClassCacheEntry) e.nextElement();	    if( entry.loadedClass==null )		continue;	    if( debug>5 )		log( "cache entry: " + entry.loadedClass.getName());	    if (entry.isSystemClass()) continue;	                // XXX: Because we want the classloader to be an accurate            // reflection of the contents of the repository, we also            // reload if a class origin file is now missing.  This            // probably makes things a bit more fragile, but is OK in            // a servlet development situation. <mbp@pharos.com.au>            long msOrigin = entry.origin.lastModified();            if (msOrigin == 0) {                // class no longer exists                return true;            }            if (msOrigin != entry.lastModified) {                // class is modified                return true;            }        }        // No changes, no need to reload        return false;    }    /**     * Re-instantiate this class loader.     * <p>     * This method creates a new instance     * of the class loader that will load classes form the same path     * as this one.     */    public AdaptiveClassLoader reinstantiate() {        AdaptiveClassLoader cl=new AdaptiveClassLoader();	cl.setParent(parent); 	cl.setRepository(repository);	return cl;    }    //------------------------------------ Implementation of Classloader    /*     * XXX: The javadoc for java.lang.ClassLoader says that the     * ClassLoader should cache classes so that it can handle repeated     * requests for the same class.  On the other hand, the JLS seems     * to imply that each classloader is only asked to load each class     * once.  Is this a contradiction?     *     * Perhaps the second call only applies to classes which have been     * garbage-collected?     */    /**     * Resolves the specified name to a Class. The method loadClass()     * is called by the virtual machine.  As an abstract method,     * loadClass() must be defined in a subclass of ClassLoader.     *     * @param      name the name of the desired Class.     * @param      resolve true if the Class needs to be resolved;     *             false if the virtual machine just wants to determine     *             whether the class exists or not     * @return     the resulting Class.     * @exception  ClassNotFoundException  if the class loader cannot     *             find a the requested class.     */    protected synchronized Class loadClass(String name, boolean resolve)        throws ClassNotFoundException    {        if( debug>0) log( "loadClass() " + name);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -