`
canofy
  • 浏览: 821277 次
  • 性别: Icon_minigender_1
  • 来自: 北京、四川
社区版块
存档分类
最新评论

自定义classloader

    博客分类:
  • j2EE
阅读更多

转:http://tiantian911.iteye.com/blog/273164

关键的classloader类: 

Java代码  收藏代码
  1. package com.hitachi.classloader;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileInputStream;  
  5. import java.io.IOException;  
  6. import java.util.Hashtable;  
  7. import java.util.jar.JarEntry;  
  8. import java.util.jar.JarInputStream;  
  9.   
  10. public class MyClassLoader extends ClassLoader {  
  11.   
  12.     private static String myClasspath = new String("");  
  13.     private static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>();  
  14.     private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>();  
  15.   
  16.     public MyClassLoader() {  
  17.   
  18.     }  
  19.   
  20.     /** */  
  21.     /** 
  22.      * create a classloader and specify a classpath. 
  23.      *  
  24.      * @param myClasspath 
  25.      *            the specified classpath name. 
  26.      */  
  27.     public MyClassLoader(String myClasspath) {  
  28.         if (!myClasspath.endsWith("\\")) {  
  29.             myClasspath = myClasspath + "\\";  
  30.         }  
  31.         MyClassLoader.myClasspath = myClasspath;  
  32.     }  
  33.   
  34.     /** */  
  35.     /** 
  36.      * set the classpath 
  37.      *  
  38.      * @param myClasspath 
  39.      *            the specified classpath name 
  40.      */  
  41.     public void SetmyClasspath(String myClasspath) {  
  42.         if (!myClasspath.endsWith("\\")) {  
  43.             myClasspath = myClasspath + "\\";  
  44.         }  
  45.         MyClassLoader.myClasspath = myClasspath;  
  46.     }  
  47.   
  48.     /** */  
  49.     /** 
  50.      * Loads the class with the specified binary name. This method searches for 
  51.      * classes in the same manner as the loadClass(String, boolean) method. 
  52.      * Invoking this method is equivalent to invoking {loadClass(name,false)}. 
  53.      *  
  54.      * @param className 
  55.      *            The binary name of the class. 
  56.      *  
  57.      * @return The resulting <tt>Class</tt> object. 
  58.      *  
  59.      * @throws ClassNotFoundException 
  60.      *             If the class was not found. 
  61.      */  
  62.     @SuppressWarnings("unchecked")  
  63.     public Class loadClass(String className) throws ClassNotFoundException {  
  64.         return loadClass(className, false);  
  65.     }  
  66.   
  67.     /** */  
  68.     /** 
  69.      * Loads the class with the specified binary name. The default 
  70.      * implementation of this method searches for classes in the following 
  71.      * order: 
  72.      *  
  73.      * Invoke {findLoadedClass(String)} to check if the class has already been 
  74.      * loaded. 
  75.      *  
  76.      * Invoke {findSystemClass(String)} to load the system class. 
  77.      *  
  78.      * Invoke the {findClass(String)} method to find the class. 
  79.      *  
  80.      * If the class was found using the above steps, and the resolve flag is 
  81.      * true, this method will then invoke the {resolveClass(Class)} method on 
  82.      * the resulting Class object. 
  83.      *  
  84.      * @param name 
  85.      *            The binary name of the class. 
  86.      *  
  87.      * @param resolve 
  88.      *            If true then resolve the class. 
  89.      *  
  90.      * @return The resulting Class object. 
  91.      *  
  92.      * @throws ClassNotFoundException 
  93.      *             If the class could not be found. 
  94.      */  
  95.     @SuppressWarnings("unchecked")  
  96.     protected Class loadClass(String name, boolean resolve)  
  97.             throws ClassNotFoundException {  
  98.   
  99.         try {  
  100.             Class foundClass = findLoadedClass(name);  
  101.   
  102.             // check if the class has already been loaded.  
  103.             if (foundClass != null) {  
  104.                 System.out.println("Complete to load the class: " + name);  
  105.                 return foundClass;  
  106.             }  
  107.   
  108.             // if the class is systemClass, load the system class by system  
  109.             if (name.startsWith("java.")) {  
  110.                 foundClass = findSystemClass(name);  
  111.                 loadClassHashTable.put(name, foundClass);  
  112.                 System.out.println("System is loading the class: " + name);  
  113.                 return foundClass;  
  114.             }  
  115.   
  116.             // invoke the findClass() method to load the class  
  117.             try {  
  118.                 foundClass = findClass(name);  
  119.             } catch (Exception fnfe) {  
  120.             }  
  121.   
  122.             if (resolve && (foundClass != null)) {  
  123.                 resolveClass(foundClass);  
  124.             }  
  125.             return foundClass;  
  126.         } catch (Exception e) {  
  127.             throw new ClassNotFoundException(e.toString());  
  128.         }  
  129.     }  
  130.   
  131.     /** */  
  132.     /** 
  133.      * Finds the class with the specified binary name.The default implementation 
  134.      * throws a ClassNotFoundException. 
  135.      *  
  136.      * @param className 
  137.      *            The binary name of the class. 
  138.      *  
  139.      * @return The resulting Class object. 
  140.      *  
  141.      * @throws ClassNotFoundException 
  142.      *             If the class could not be found. 
  143.      */  
  144.     @SuppressWarnings("unchecked")  
  145.     public Class findClass(String className) {  
  146.   
  147.         byte[] classData = null;  
  148.         try {  
  149.             classData = loadClassData(className);  
  150.         } catch (IOException e) {  
  151.             e.printStackTrace();  
  152.         }  
  153.         if (classData == null) {  
  154.             return null;  
  155.         }  
  156.   
  157.         System.out.println("MyClassLoader is loading : " + className + "");  
  158.         Class c = defineClass(className, classData, 0, classData.length);  
  159.         MyClassLoader.loadClassHashTable.put(className, c);  
  160.         System.out.println("Complete to load the class :" + className);  
  161.         return c;  
  162.     }  
  163.   
  164.     /** */  
  165.     /** 
  166.      * Loads the classData with the specified binary name. This method searches 
  167.      * for classes in the specified classpath as 
  168.      * searchFile(myClasspath,className) method. 
  169.      *  
  170.      * @param name 
  171.      *            The binary name of the class 
  172.      *  
  173.      * @return The resulting the classData of the class object by byte[] 
  174.      *  
  175.      * @throws IOException 
  176.      *             if have some failed or interrupted I/O operations. 
  177.      */  
  178.     private byte[] loadClassData(String className) throws IOException {  
  179.   
  180.         String filePath = searchFile(myClasspath, className + ".class");  
  181.   
  182.         if (!(filePath == null || filePath == "")) {  
  183.   
  184.             System.out.println("It have found the file : " + className  
  185.                     + ".  Begin to read the data and load the class。");  
  186.             FileInputStream inFile = new FileInputStream(filePath);  
  187.             byte[] classData = new byte[inFile.available()];  
  188.             inFile.read(classData);  
  189.             inFile.close();  
  190.             loadClassTime.put(className, new File(filePath).lastModified());  
  191.             return classData;  
  192.         } else {  
  193.   
  194.             filePath = searchFile(myClasspath, className + ".java");  
  195.             if (!(filePath == null || filePath == "")) {  
  196.                 System.out.println("It have found the file : " + filePath  
  197.                         + ".  Begin to translate");  
  198.                 Runtime.getRuntime().exec("javac " + filePath);  
  199.                 try {  
  200.                     Thread.sleep(1000);  
  201.                 } catch (InterruptedException e) {  
  202.                     e.printStackTrace();  
  203.                 }  
  204.                 System.out.println("Translate it over : " + filePath);  
  205.                 return loadClassData(className);  
  206.             } else {  
  207.                 System.out  
  208.                         .println("Haven't found the file, and fail to read the classData!");  
  209.                 return null;  
  210.             }  
  211.         }  
  212.     }  
  213.   
  214.     /** */  
  215.     /** 
  216.      * Loads the class with the specified binary name.The default implementation 
  217.      * throws a ClassNotFoundException. 
  218.      *  
  219.      * @param classData 
  220.      *            The data of the class. 
  221.      * @param className 
  222.      *            The binary name of the class. 
  223.      *  
  224.      * @return The resulting Class object. 
  225.      *  
  226.      * @throws ClassNotFoundException 
  227.      *             If the class could not be found. 
  228.      */  
  229.     public Class loadClass(byte[] classData, String className)  
  230.             throws ClassNotFoundException {  
  231.   
  232.         System.out.println("MyClassLoader is loading : " + className + "");  
  233.         Class c = defineClass(className, classData, 0, classData.length);  
  234.         loadClassHashTable.put(className, c);  
  235.         System.out.println("Complete to load the class :" + className);  
  236.   
  237.         return c;  
  238.     }  
  239.   
  240.     /** */  
  241.     /** 
  242.      * Loads the class with the specified binary name.The default implementation 
  243.      * throws a ClassNotFoundException. 
  244.      *  
  245.      * @param className 
  246.      *            The binary name of the class. 
  247.      * @param jarName 
  248.      *            The binary name of the jar that search the class from it. 
  249.      *  
  250.      * @return The resulting Class object. 
  251.      *  
  252.      * @throws ClassNotFoundException 
  253.      *             If the class could not be found. 
  254.      */  
  255.     protected Class loadClass(String className, String jarName)  
  256.             throws ClassNotFoundException {  
  257.   
  258.         String jarPath = searchFile(myClasspath, jarName + ".jar");  
  259.         JarInputStream in = null;  
  260.   
  261.         if (!(jarPath == null || jarPath == "")) {  
  262.   
  263.             try {  
  264.                 in = new JarInputStream(new FileInputStream(jarPath));  
  265.                 JarEntry entry;  
  266.                 while ((entry = in.getNextJarEntry()) != null) {  
  267.                     String outFileName = entry.getName().substring(  
  268.                             entry.getName().lastIndexOf("/") + 1,  
  269.                             entry.getName().length());  
  270.                     if (outFileName.equals(className + ".class")) {  
  271.                         if (entry.getSize() == -1) {  
  272.                             System.err.println("error : can't read the file!");  
  273.                             return null;  
  274.                         }  
  275.                         byte[] classData = new byte[(int) entry.getSize()];  
  276.                         System.out  
  277.                                 .println("It have found the file : "  
  278.                                         + className  
  279.                                         + ".  Begin to read the data and load the class。");  
  280.                         in.read(classData);  
  281.                         return loadClass(classData, className);  
  282.                     }  
  283.                 }  
  284.                 System.out.println("Haven't found the file " + className  
  285.                         + " in " + jarName + ".jar.");  
  286.             } catch (IOException e) {  
  287.                 e.printStackTrace();  
  288.             } finally {  
  289.                 try {  
  290.                     in.close();  
  291.                 } catch (IOException e) {  
  292.                     e.printStackTrace();  
  293.                 }  
  294.             }  
  295.         } else {  
  296.             System.out.println("Haven't found the jarFile: " + jarName  
  297.                     + ".jar.");  
  298.             return null;  
  299.         }  
  300.         return null;  
  301.     }  
  302.   
  303.     /** */  
  304.     /** 
  305.      * Reloads the class with the specified binary name. Needn't have to restart 
  306.      * JVM then reload the class. 
  307.      *  
  308.      * @param className 
  309.      *            The binary name of the class need to reload . 
  310.      *  
  311.      * @return The resulting Class object. 
  312.      *  
  313.      * @throws ClassNotFoundException 
  314.      *             If the class was not found. 
  315.      */  
  316.     public Class reload(String fileName) {  
  317.   
  318.         String filePath = searchFile(myClasspath, fileName + ".class");  
  319.         Long a = new File(filePath).lastModified();  
  320.   
  321.         if (!a.equals(loadClassTime.get(fileName))) {  
  322.             loadClassHashTable.remove(fileName);  
  323.             loadClassTime.remove(fileName);  
  324.             try {  
  325.                 MyClassLoader mc2 = new MyClassLoader(myClasspath);  
  326.                 mc2.loadClass(fileName);  
  327.             } catch (ClassNotFoundException e) {  
  328.                 e.printStackTrace();  
  329.             }  
  330.         } else {  
  331.             System.out  
  332.                     .println("The class is the newest version , needn't reloading.");  
  333.         }  
  334.         return null;  
  335.     }  
  336.   
  337.     /** */  
  338.     /** 
  339.      * search the file with the specified binary name. Needn't have to restart 
  340.      * JVM then reload the class. 
  341.      *  
  342.      * @param classpath 
  343.      *            the specified path where we search. 
  344.      * @param fileName 
  345.      *            The binary name of the file that want to search. 
  346.      *  
  347.      * @return The resulting file path. 
  348.      */  
  349.     public String searchFile(String classpath, String fileName) {  
  350.   
  351.         String cut = fileName.substring(fileName.lastIndexOf('.'), fileName  
  352.                 .length());  
  353.         String path = fileName.substring(0, fileName.lastIndexOf('.')).replace(  
  354.                 '.''/')  
  355.                 + cut;  
  356.   
  357.         File f = new File(classpath + path);  
  358.         if (f.isFile()) {  
  359.             return f.getPath();  
  360.         } else {  
  361.             String objects[] = new File(classpath).list();  
  362.             for (int i = 0; i < objects.length; i++) {  
  363.                 if (new File(classpath + File.separator + objects[i])  
  364.                         .isDirectory()) {  
  365.                     String s = searchFile(classpath + objects[i]  
  366.                             + File.separator, fileName);  
  367.                     if (s == null || s == "") {  
  368.                         continue;  
  369.                     } else {  
  370.                         return s;  
  371.                     }  
  372.                 }  
  373.             }  
  374.         }  
  375.         return null;  
  376.     };  
  377.   
  378. }  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics