`
canofy
  • 浏览: 829686 次
  • 性别: 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. }  
分享到:
评论

相关推荐

    自定义classloader的使用

    自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨自定义Classloader的使用。 一、Classloader的工作原理 Java的类加载机制遵循双亲...

    Java实现热加载完整代码;Java动态加载class;Java覆盖已加载的class;Java自定义classloader

    让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的...Java自定义classloader;

    定义ClassLoader调用外部jar包

    当我们需要从外部jar包动态加载类时,自定义ClassLoader就显得尤为关键。这篇博文"定义ClassLoader调用外部jar包"探讨了如何创建一个自定义的ClassLoader,以便能够灵活地加载不在应用主类路径(ClassPath)中的jar...

    ClassLoader运行机制 自己写的

    这里我们将详细讨论ClassLoader的运行机制,特别是自定义ClassLoader的设计与实现。 ClassLoader的基本职责是根据类名动态加载对应的类文件。在Java中,类加载过程遵循双亲委派模型(Parent Delegation Model)。这...

    使用自定义ClassLoader解决反序列化serialVesionUID不一致问题 _ 回忆飘如雪1

    标题和描述中提到的解决方案是通过自定义`ClassLoader`来处理`serialVersionUID`不一致的问题。以下是几种常见方法的优缺点以及自定义`ClassLoader`的详细解释: 1. **修改序列化byte数据**: 这种方法直接修改已...

    关于Android中自定义ClassLoader耗时问题的追查

    在Android开发中,自定义ClassLoader是一项关键技能,尤其在实现热修复和插件化技术时。本文主要探讨了Android中自定义ClassLoader导致的性能问题,特别是冷启动速度的影响。问题的核心在于,通过插入自定义的...

    MyCLRepl:自定义 Scala REPL 示例以添加自定义 ClassLoader 和自定义 REPL 命令

    自定义 ClassLoader 加载任何类时的类名。 ":myCommand" 命令位于默认 REPL 命令之上。 scala &gt; val hello = " hello " MyClassLoader loads classOf &lt; root&gt;.$line3 &lt;&lt;中略&gt;&gt; MyClassLoader loads classOf ...

    ClassLoader 案例

    自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热部署等。本案例将深入探讨如何创建一个自定义的ClassLoader,利用Java反射和注解技术...

    ClassLoader小例子

    下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载器是Java中的一个核心组件,它负责将类的.class文件加载到JVM中,并转换为可执行的Java...

    classloader

    创建自定义类加载器需要继承ClassLoader类,并重写findClass()方法。在这个方法里,你可以编写代码来从指定的位置(例如,网络、文件系统或内存)读取类的字节码,并通过defineClass()方法将其转换为Class对象。 在...

    Java ClassLoader定制实例

    在某些特定场景下,比如动态加载代码、插件系统或者安全隔离等,我们需要自定义ClassLoader来实现特定的加载逻辑。例如,我们可能希望加载网络上的类,或者从数据库中读取类的字节码。 以...

    Understanding the Java ClassLoader

    为了更好地理解和利用Java的这一特性,本篇将详细介绍Java ClassLoader的作用及其工作原理,并通过构建一个示例ClassLoader来帮助读者深入理解如何自定义ClassLoader,从而扩展JVM的功能。 #### 二、ClassLoader...

    ClassLoader类加载器

    了解和掌握ClassLoader的工作原理以及如何自定义ClassLoader对于深入理解Java应用程序的运行机制非常有帮助。以下是对ClassLoader API的使用和自定义的详细说明。 首先,我们来看ClassLoader的基本概念。在Java中,...

    ClassLoader类加载机制和原理详解

    但有时我们可能需要打破这种模型,比如实现类的版本控制或插件系统,这时可以通过自定义ClassLoader来实现。 5. 类加载器的关系图 Java中的ClassLoader形成了一个树状结构,Bootstrap ClassLoader位于顶端,其他类...

    ClassLoader的 一些测试

    自定义ClassLoader是一种常见的需求,例如在插件系统、热部署等场景。自定义加载器通常需要重写`loadClass(String className)`方法,通过URL读取类的字节流并转换为Class对象。在这个过程中,我们需要注意类的缓存,...

    理解Java ClassLoader机制

    自定义ClassLoader需要继承`java.lang.ClassLoader`类,并重写`findClass()`或`loadClass()`方法。通过这两个方法,你可以控制类的加载来源和方式。 在实际开发中,理解ClassLoader机制可以帮助解决一些问题,例如...

    ClassLoader 详解.doc

    自定义ClassLoader是Java平台的一大特色,开发人员可以根据需要创建自己的类加载器,例如实现模块化、热部署或者加密解密类等高级功能。自定义ClassLoader通常需要重写findClass()或loadClass()方法,以控制类的加载...

    java classloader

    在Java中,用户可以通过自定义ClassLoader来实现特定的加载逻辑,比如从数据库或网络中加载类。这使得Java可以支持许多高级功能,例如插件系统、热部署和模块化系统(如Java 9的Jigsaw项目)。 `JAVA2深度历险.jpg`...

    浅析ClassLoader

    1. 自定义需求:在某些场景下,如动态加载插件、加密类文件等,开发者可能需要自定义ClassLoader。自定义ClassLoader需要继承java.lang.ClassLoader并重写findClass()方法。 2. 实现步骤:创建类加载器实例,读取类...

Global site tag (gtag.js) - Google Analytics