转:http://tiantian911.iteye.com/blog/273164
关键的classloader类:
- package com.hitachi.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;
- public class MyClassLoader extends ClassLoader {
- private static String myClasspath = new String("");
- private static Hashtable<String, Class<?>> loadClassHashTable = new Hashtable<String, Class<?>>();
- private static Hashtable<String, Long> loadClassTime = new Hashtable<String, Long>();
- 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;
- };
- }
相关推荐
自定义Classloader允许开发者根据特定需求定制类的加载逻辑,例如加密类文件、隔离不同版本的库或者动态加载代码。本文将深入探讨自定义Classloader的使用。 一、Classloader的工作原理 Java的类加载机制遵循双亲...
让Java支持热加载是个不错的想法。如何做到的呢? 1. 定义好接口和实现类 2. 让代理类通过反射的方式调用实现类,对外暴露的是代理类。 3. 自定义URLClassLoader。检查实现类.class文件的...Java自定义classloader;
当我们需要从外部jar包动态加载类时,自定义ClassLoader就显得尤为关键。这篇博文"定义ClassLoader调用外部jar包"探讨了如何创建一个自定义的ClassLoader,以便能够灵活地加载不在应用主类路径(ClassPath)中的jar...
这里我们将详细讨论ClassLoader的运行机制,特别是自定义ClassLoader的设计与实现。 ClassLoader的基本职责是根据类名动态加载对应的类文件。在Java中,类加载过程遵循双亲委派模型(Parent Delegation Model)。这...
标题和描述中提到的解决方案是通过自定义`ClassLoader`来处理`serialVersionUID`不一致的问题。以下是几种常见方法的优缺点以及自定义`ClassLoader`的详细解释: 1. **修改序列化byte数据**: 这种方法直接修改已...
在Android开发中,自定义ClassLoader是一项关键技能,尤其在实现热修复和插件化技术时。本文主要探讨了Android中自定义ClassLoader导致的性能问题,特别是冷启动速度的影响。问题的核心在于,通过插入自定义的...
自定义 ClassLoader 加载任何类时的类名。 ":myCommand" 命令位于默认 REPL 命令之上。 scala > val hello = " hello " MyClassLoader loads classOf < root>.$line3 <<中略>> MyClassLoader loads classOf ...
自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热部署等。本案例将深入探讨如何创建一个自定义的ClassLoader,利用Java反射和注解技术...
下面我们将详细讨论ClassLoader的基本概念、工作流程以及如何自定义ClassLoader。 1. **ClassLoader的基本概念** - 类加载器是Java中的一个核心组件,它负责将类的.class文件加载到JVM中,并转换为可执行的Java...
创建自定义类加载器需要继承ClassLoader类,并重写findClass()方法。在这个方法里,你可以编写代码来从指定的位置(例如,网络、文件系统或内存)读取类的字节码,并通过defineClass()方法将其转换为Class对象。 在...
在某些特定场景下,比如动态加载代码、插件系统或者安全隔离等,我们需要自定义ClassLoader来实现特定的加载逻辑。例如,我们可能希望加载网络上的类,或者从数据库中读取类的字节码。 以...
为了更好地理解和利用Java的这一特性,本篇将详细介绍Java ClassLoader的作用及其工作原理,并通过构建一个示例ClassLoader来帮助读者深入理解如何自定义ClassLoader,从而扩展JVM的功能。 #### 二、ClassLoader...
了解和掌握ClassLoader的工作原理以及如何自定义ClassLoader对于深入理解Java应用程序的运行机制非常有帮助。以下是对ClassLoader API的使用和自定义的详细说明。 首先,我们来看ClassLoader的基本概念。在Java中,...
但有时我们可能需要打破这种模型,比如实现类的版本控制或插件系统,这时可以通过自定义ClassLoader来实现。 5. 类加载器的关系图 Java中的ClassLoader形成了一个树状结构,Bootstrap ClassLoader位于顶端,其他类...
自定义ClassLoader是一种常见的需求,例如在插件系统、热部署等场景。自定义加载器通常需要重写`loadClass(String className)`方法,通过URL读取类的字节流并转换为Class对象。在这个过程中,我们需要注意类的缓存,...
自定义ClassLoader需要继承`java.lang.ClassLoader`类,并重写`findClass()`或`loadClass()`方法。通过这两个方法,你可以控制类的加载来源和方式。 在实际开发中,理解ClassLoader机制可以帮助解决一些问题,例如...
自定义ClassLoader是Java平台的一大特色,开发人员可以根据需要创建自己的类加载器,例如实现模块化、热部署或者加密解密类等高级功能。自定义ClassLoader通常需要重写findClass()或loadClass()方法,以控制类的加载...
在Java中,用户可以通过自定义ClassLoader来实现特定的加载逻辑,比如从数据库或网络中加载类。这使得Java可以支持许多高级功能,例如插件系统、热部署和模块化系统(如Java 9的Jigsaw项目)。 `JAVA2深度历险.jpg`...
1. 自定义需求:在某些场景下,如动态加载插件、加密类文件等,开发者可能需要自定义ClassLoader。自定义ClassLoader需要继承java.lang.ClassLoader并重写findClass()方法。 2. 实现步骤:创建类加载器实例,读取类...