java class loading 研究技术---整理后的代码

引用
以下是整理好的代码,欢迎指正!

/**//*
 * @MyClassLoader.java    07/04/17
 *
 * Copyright Zhao Jiucheng. All rights reserved.
 */
package com.neusoft.classloader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

/** *//**
 * A class loader is an object that is responsible for loading classes. Given
 * the binary name of a class, a class loader should attempt to locate or
 * generate data that constitutes a definition for the class. A typical strategy
 * is to transform the name into a file name and then read a "class file" of
 * that name from a file system.
 * 
 * @version 1.0, 07/04/17
 * @author Zhao Jiucheng
 * 
 */
public class MyClassLoader extends ClassLoader {

    // a classpath for search
    private static String myClasspath = new String("");

    // hashtable that memory the loaded classes
    private static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>();

    // hashtable that memory the time of loading a class
    private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>();

    // the null constructor
    public MyClassLoader() {

    }

    /** *//**
     * create a classloader and specify a classpath.
     * 
     * @param myClasspath
     *            the specified classpath name.
     */
    public MyClassLoader(String myClasspath) {
        if (!myClasspath.endsWith("\\")) {
            myClasspath = myClasspath + "\\";
        }
        MyClassLoader.myClasspath = myClasspath;
    }

    /** *//**
     * set the classpath
     * 
     * @param myClasspath
     *            the specified classpath name
     */
    public void SetmyClasspath(String myClasspath) {
        if (!myClasspath.endsWith("\\")) {
            myClasspath = myClasspath + "\\";
        }
        MyClassLoader.myClasspath = myClasspath;
    }

    /** *//**
     * Loads the class with the specified binary name. This method searches for
     * classes in the same manner as the loadClass(String, boolean) method.
     * Invoking this method is equivalent to invoking {loadClass(name,false)}.
     * 
     * @param className
     *            The binary name of the class.
     * 
     * @return The resulting <tt>Class</tt> object.
     * 
     * @throws ClassNotFoundException
     *             If the class was not found.
     */
    @SuppressWarnings("unchecked")
    public Class loadClass(String className) throws ClassNotFoundException {
        return loadClass(className, false);
    }

    /** *//**
     * Loads the class with the specified binary name. The default
     * implementation of this method searches for classes in the following
     * order:
     * 
     * Invoke {findLoadedClass(String)} to check if the class has already been
     * loaded.
     * 
     * Invoke {findSystemClass(String)} to load the system class.
     * 
     * Invoke the {findClass(String)} method to find the class.
     * 
     * If the class was found using the above steps, and the resolve flag is
     * true, this method will then invoke the {resolveClass(Class)} method on
     * the resulting Class object.
     * 
     * @param name
     *            The binary name of the class.
     * 
     * @param resolve
     *            If true then resolve the class.
     * 
     * @return The resulting Class object.
     * 
     * @throws ClassNotFoundException
     *             If the class could not be found.
     */
    @SuppressWarnings("unchecked")
    protected Class loadClass(String name, boolean resolve)
            throws ClassNotFoundException {

        try {
            Class foundClass = findLoadedClass(name);

            // check if the class has already been loaded.
            if (foundClass != null) {
                System.out.println("Complete to load the class: " + name);
                return foundClass;
            }

            // if the class is systemClass, load the system class by system
            if (name.startsWith("java.")) {
                foundClass = findSystemClass(name);
                loadClassHashTable.put(name, foundClass);
                System.out.println("System is loading the class: " + name);
                return foundClass;
            }

            // invoke the findClass() method to load the class
            try {
                foundClass = findClass(name);
            } catch (Exception fnfe) {
            }

            if (resolve && (foundClass != null)) {
                resolveClass(foundClass);
            }
            return foundClass;
        } catch (Exception e) {
            throw new ClassNotFoundException(e.toString());
        }
    }

    /** *//**
     * Finds the class with the specified binary name.The default implementation
     * throws a ClassNotFoundException.
     * 
     * @param className
     *            The binary name of the class.
     * 
     * @return The resulting Class object.
     * 
     * @throws ClassNotFoundException
     *             If the class could not be found.
     */
    @SuppressWarnings("unchecked")
    public Class findClass(String className) {

        byte[] classData = null;
        try {
            classData = loadClassData(className);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if( classData == null){
            return null;
        }

        System.out.println("MyClassLoader is loading : " + className + "");
        Class c = defineClass(className, classData, 0, classData.length);
        MyClassLoader.loadClassHashTable.put(className, c);
        System.out.println("Complete to load the class :" + className);
        return c;
    }

    /** *//**
     * Loads the classData with the specified binary name. This method searches
     * for classes in the specified classpath as
     * searchFile(myClasspath,className) method.
     * 
     * @param name
     *            The binary name of the class
     * 
     * @return The resulting the classData of the class object by byte[]
     * 
     * @throws IOException
     *             if have some failed or interrupted I/O operations.
     */
    private byte[] loadClassData(String className) throws IOException {

        String filePath = searchFile(myClasspath, className + ".class");

        if (!(filePath == null || filePath == "")) {

            System.out.println("It have found the file : " + className
                    + ".  Begin to read the data and load the class。");
            FileInputStream inFile = new FileInputStream(filePath);
            byte[] classData = new byte[inFile.available()];
            inFile.read(classData);
            inFile.close();
            loadClassTime.put(className, new File(filePath).lastModified());
            return classData;
        } else {

            filePath = searchFile(myClasspath, className + ".java");
            if (!(filePath == null || filePath == "")) {
                System.out.println("It have found the file : " + filePath
                        + ".  Begin to translate");
                Runtime.getRuntime().exec("javac " + filePath);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Translate it over : " + filePath);
                return loadClassData(className);
            } else {
                System.out
                        .println("Haven't found the file, and fail to read the classData!");
                return null;
            }
        }
    }

    /** *//**
     * Loads the class with the specified binary name.The default implementation
     * throws a ClassNotFoundException.
     * 
     * @param classData
     *            The data of the class.
     * @param className
     *            The binary name of the class.
     * 
     * @return The resulting Class object.
     * 
     * @throws ClassNotFoundException
     *             If the class could not be found.
     */
    public Class loadClass(byte[] classData, String className)
            throws ClassNotFoundException {

        System.out.println("MyClassLoader is loading : " + className + "");
        Class c = defineClass(className, classData, 0, classData.length);
        loadClassHashTable.put(className, c);
        System.out.println("Complete to load the class :" + className);

        return c;
    }

    /** *//**
     * Loads the class with the specified binary name.The default implementation
     * throws a ClassNotFoundException.
     * 
     * @param className
     *            The binary name of the class.
     * @param jarName
     *            The binary name of the jar that search the class from it.
     * 
     * @return The resulting Class object.
     * 
     * @throws ClassNotFoundException
     *             If the class could not be found.
     */
    protected Class loadClass(String className, String jarName)
            throws ClassNotFoundException {

        String jarPath = searchFile(myClasspath, jarName + ".jar");
        JarInputStream in = null;

        if (!(jarPath == null || jarPath == "")) {

            try {
                in = new JarInputStream(new FileInputStream(jarPath));
                JarEntry entry;
                while ((entry = in.getNextJarEntry()) != null) {
                    String outFileName = entry.getName().substring(
                            entry.getName().lastIndexOf("/") + 1,
                            entry.getName().length());
                    if (outFileName.equals(className + ".class")) {
                        if (entry.getSize() == -1) {
                            System.err.println("error : can't read the file!");
                            return null;
                        }
                        byte[] classData = new byte[(int) entry.getSize()];
                        System.out
                                .println("It have found the file : "
                                        + className
                                        + ".  Begin to read the data and load the class。");
                        in.read(classData);
                        return loadClass(classData, className);
                    }
                }
                System.out.println("Haven't found the file " + className
                        + " in " + jarName + ".jar.");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            System.out.println("Haven't found the jarFile: " + jarName
                    + ".jar.");
            return null;
        }
        return null;
    }

    /** *//**
     * Reloads the class with the specified binary name. Needn't have to restart
     * JVM then reload the class.
     * 
     * @param className
     *            The binary name of the class need to reload .
     * 
     * @return The resulting Class object.
     * 
     * @throws ClassNotFoundException
     *             If the class was not found.
     */
    public Class reload(String fileName) {

        String filePath = searchFile(myClasspath, fileName + ".class");
        Long a = new File(filePath).lastModified();

        if (!a.equals(loadClassTime.get(fileName))) {
            loadClassHashTable.remove(fileName);
            loadClassTime.remove(fileName);
            try {
                MyClassLoader mc2 = new MyClassLoader(myClasspath);
                mc2.loadClass(fileName);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        } else {
            System.out
                    .println("The class is the newest version , needn't reloading.");
        }
        return null;
    }

    /** *//**
     * search the file with the specified binary name. Needn't have to restart
     * JVM then reload the class.
     * 
     * @param classpath
     *            the specified path where we search.
     * @param fileName
     *            The binary name of the file that want to search.
     * 
     * @return The resulting file path.
     */
    public String searchFile(String classpath, String fileName) {

        String cut = fileName.substring(fileName.lastIndexOf('.'), fileName
                .length());
        String path = fileName.substring(0, fileName.lastIndexOf('.')).replace(
                '.', '/')
                + cut;

        File f = new File(classpath + path);
        if (f.isFile()) {
            return f.getPath();
        } else {
            String objects[] = new File(classpath).list();
            for (int i = 0; i < objects.length; i++) {
                if (new File(classpath + File.separator + objects[i])
                        .isDirectory()) {
                    String s = searchFile(classpath + objects[i]
                            + File.separator, fileName);
                    if (s == null || s == "") {
                        continue;
                    } else {
                        return s;
                    }
                }
            }
        }
        return null;
    };

    public static void main(String[] args) {
        MyClassLoader c1 = new MyClassLoader(
                "E:/javawork/teacher's classloader/bin");
        //MyClassLoader c2 = new MyClassLoader(
        //        "E:/javawork/teacher's classloader");
        try {
            while (true) {
                c1.loadClass("com.neusoft.test.A");
                //c2.loadClass("com.neusoft.test.B");
                try {
                    Thread.sleep(300000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


MyThread.java
/**//*
 * @MyThread.java    2007/04/17
 *
 * Copyright Zhao Jiucheng. All rights reserved.
 * 
 */
package com.neusoft.classloader;

import java.io.File;


/** *//**
 * Create a Thread to watch the specify directory,if new classes haved
 * appended,load them.
 * 
 * @author Zhao Jiucheng
 * @version 1.0, 2007/04/17
 */

public class MyThread extends Thread {

    // for get the classpath
    private String filePath;

    // instantiation a ClassLoader
    private MyClassLoader mcl;

    /** *//**
     * Constructs a new MyThread for the given path.
     * 
     * @param path
     * @return null
     */
    public MyThread(String path) {
        this.filePath = path;
        mcl = new MyClassLoader(path);
    }

    /** *//**
     * Watch pecify directory to search for appended classes time after time.
     * 
     * @param filepath
     * 
     * @return null
     * @exception ClassNotFoundException
     *                if the class could not be found.
     */
    public void search(String filePath) {
        File dir = new File(filePath);
        String[] fileList = dir.list();
        for (int i = 0; i < fileList.length; i++) {

            if (new File(filePath + File.separator + fileList[i]).isDirectory()) {

                search(filePath + fileList[i]);
            } else if (new File(filePath + File.separator + fileList[i])
                    .isFile()) {

                if (fileList[i].endsWith(".class")) {
                    try {

                        mcl.loadClass(fileList[i].substring(0, fileList[i]
                                .length() - 6));
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /** *//**
     * If this thread was constructed using a separate runnable run object, then
     * that runnable object's run method is called;
     * 
     * @return null
     * @exception InterruptedException
     *                if the thread has been interrupted.
     */

    public void run() {
        int i = 1;
        while (true) {
            search(filePath);
            System.out.println("searching " + i++ + "s");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (i == 20) {
                System.out.println("search over!");
                break;
            }
        }
    }

    public static void main(String[] args) {
        MyThread t = new MyThread("D:\\soft\\aa");
        t.start();
    }
}

MyURLClassLoader.java
/**//*
 * @MyURLClassLoader.java    2007/04/17
 *
 * Copyright Zhao Jiucheng. All rights reserved.
 * 
 */
package com.neusoft.classloader;

import java.net.*;


/** *//**
 * This class loader is used to load classes and resources from a search path
 * 
 * @author Zhao Jiucheng
 * @version 1.0, 2007/04/17
 */
public class MyURLClassLoader extends URLClassLoader {
    /** *//**
     * Constructs a new URLClassLoader for the given URLs.
     * 
     * @param url
     */
    public MyURLClassLoader(URL[] url) {
        super(url);
    }

    /** *//**
     * Finds the class with the specified binary name.
     * 
     * @param name
     *            The binary name of the class
     * @return The resulting Class object
     * 
     * @throws ClassNotFoundException
     *             If the class could not be found
     */
    @SuppressWarnings("unchecked")
    public Class findClass(final String name) {
        try {
            return super.findClass(name);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        URL url = null;
        try {
            url = new URL("http://192.168.44.19:8088/Webtest/");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        MyURLClassLoader urlClassLoader1 = new MyURLClassLoader(
                new URL[] { url });
        Class c1 = urlClassLoader1.findClass("Tree");
        System.out.println(c1);

    }

}

http://www.blogjava.net/realsmy/archive/2007/04/18/111582.html

你可能感兴趣的:(java,thread,C++,c,C#)