以下是整理后的代碼部分,歡迎批評(píng)指正。

          MyClassLoader.java
          /*
           * @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);

              }


          }




          歡迎來訪!^.^!
          本BLOG僅用于個(gè)人學(xué)習(xí)交流!
          目的在于記錄個(gè)人成長(zhǎng).
          所有文字均屬于個(gè)人理解.
          如有錯(cuò)誤,望多多指教!不勝感激!

          Feedback

          # re: JAVA CLASS LOADING技術(shù)研究---整理后的代碼  回復(fù)  更多評(píng)論   

          2007-04-18 14:39 by lx
          和java原有classloader比好像沒有太大improvement ...對(duì)于了解class loader原理還是有幫助的

          # re: JAVA CLASS LOADING技術(shù)研究---整理后的代碼  回復(fù)  更多評(píng)論   

          2007-04-19 15:42 by wanglin
          除了委托加載,ms還有上下文加載。

          后者資料甚少,sun官方也沒有提供詳細(xì)的介紹,而且雖然現(xiàn)在java技術(shù)中已經(jīng)在使用他,但是還是有問題。。。。。。。。

          # re: JAVA CLASS LOADING技術(shù)研究---整理后的代碼  回復(fù)  更多評(píng)論   

          2007-04-19 16:40 by 久城
          恩,謝謝,個(gè)人感覺問題還挺大。比如Java中暫時(shí)還沒有提供區(qū)分版本的機(jī)制,如果使用了比較復(fù)雜的類裝載器體系結(jié)構(gòu),在出現(xiàn)了某個(gè)包或者類的多個(gè)版本時(shí),就有可能出現(xiàn)問題了。

          # re: JAVA CLASS LOADING技術(shù)研究---整理后的代碼  回復(fù)  更多評(píng)論   

          2007-04-19 22:10 by 匿名
          版本區(qū)分的問題,通過類加載器可以部分的解決(不同的classload下的包是不會(huì)沖突的),在深入java虛擬機(jī)那本書中,作者提到classload相當(dāng)于提供了一個(gè)名字空間。 如果你說的版本區(qū)分是同一個(gè)classload下的的確會(huì)有問題。 我說的上下文加載比較啰唆。你可以搜索一下

          Copyright © 久城

          主站蜘蛛池模板: 天气| 来宾市| 溧水县| 县级市| 青川县| 建平县| 卫辉市| 丹棱县| 阜新市| 浑源县| 长海县| 兴和县| 东宁县| 木里| 荃湾区| 嵊州市| 乌鲁木齐县| 望谟县| 北流市| 沈阳市| 镇原县| 东乌珠穆沁旗| 德安县| 广河县| 文水县| 乐清市| 夹江县| 积石山| 鄂尔多斯市| 云霄县| 平江县| 略阳县| 安国市| 怀安县| 兴和县| 丹凤县| 彰化市| 邯郸市| 长岭县| 恩施市| 江西省|