import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
/**
* 动态的编译Java源文件。它检查.class文件是否存在,.class文件是否比源文件陈旧。
*/
public class CompilingClassLoader extends ClassLoader {
private String path = "";
public CompilingClassLoader(String path) {
this.path = path;
}
/**
* 从磁盘读取指定文件,并返回字节数组
*/
private byte[] getBytes(String className) {
FileInputStream in = null;
byte[] raw = null;
try {
File file = new File(className);
in = new FileInputStream(file);
raw = new byte[(int) file.length()];
int r = in.read(raw);
if (r == file.length()) {
return raw;
}
} catch (IOException ex) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* 启动一个进程来编译java源文件
*/
private boolean compile(String javaFile) {
try {
Process p = Runtime.getRuntime().exec("javac " + javaFile);
p.waitFor(); // 等待编译结束
int res = p.exitValue(); // 检查返回码,看编译是否成功
return res == 0;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
return false;
}
/**
* 动态的编译Java源文件。它检查.class文件是否存在,.class文件是否比源文件陈旧。
*/
protected Class<?> findClass(String className)
throws ClassNotFoundException {
Class<?> cls = this.findLoadedClass(className);
if (cls == null) {
String fileName = className.replace('.', File.pathSeparatorChar);
String javaFileName = path + fileName + ".java";
String classFileName = path + fileName + ".class";
File javaFile = new File(javaFileName);
File classFile = new File(classFileName);
if (!classFile.exists() && javaFile.exists()
|| javaFile.lastModified() > classFile.lastModified()) {
if (!compile(javaFileName)) {
throw new ClassNotFoundException(className);
}
}
byte[] raw = getBytes(classFileName);
if (raw == null) {
throw new ClassNotFoundException(className);
}
cls = this.defineClass(className, raw, 0, raw.length);
}
return cls;
}
public static void main(String[] args) throws Exception{
CompilingClassLoader ccl = new CompilingClassLoader("e:/");
Class<?> c = ccl.findClass("Test");
Method method = c.getDeclaredMethod("test", new Class<?>[] {});
method.invoke(c.newInstance(), new Object[] {});
}
}
如果加载的类有内部类要做如下处理
Class<?> c1 = ccl.findClass("Test3$Test2");
Class<?> c2 = ccl.findClass("Test3$Test1");
分享到:
相关推荐
在Java编程语言中,类加载器(ClassLoader)是运行时环境...理解类加载机制并正确实现自定义加载器是提升Java应用开发能力的重要一步。在实际项目中,合理利用类加载器可以解决很多复杂问题,比如模块化、动态更新等。
3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4
- **安全沙箱**:每个加载器都有自己的命名空间,可以通过自定义加载器限制代码访问权限。 - **插件系统**:插件有自己的类加载器,使得插件可以独立于主程序加载和卸载。 在编写`MyClassLoader`时,需要注意的是,...
默认的类加载器包括Bootstrap ClassLoader(引导类加载器)、Extension ClassLoader(扩展类加载器)和AppClassLoade(应用程序类加载器),它们按照双亲委派模型工作。 自定义类加载器的创建通常涉及以下步骤: 1...
"Java基于自定义类加载器实现热部署过程解析" Java中基于自定义类加载器实现热部署是指在不重启应用的情况下,当类的定义即字节码文件修改后,能够替换该Class创建的对象。热部署是Java中的一个重要概念,它可以...
java类加载器学习二、自定义类加载器
Java 实现的自定义类加载器示例 Java 实现的自定义类加载器是 Java 语言中的一种机制,允许开发者自定义类加载器,以满足特定的需求。本文将详细介绍 Java 实现的自定义类加载器的原理和实现技巧。 ClassLoader 类...
这个"DevLoader.zip"文件可能包含与Tomcat自定义类加载器相关的资料,特别是名为"DevLoader"的类加载器,这可能是Tomcat为开发者提供的一种特殊加载器。 首先,我们来理解一下类加载器的基本概念。在Java中,类加载...
本篇将深入探讨自定义类加载器的实现、双亲委派模型以及如何指定父类加载器。 首先,我们来了解自定义类加载器的实现。在Java中,类加载的过程包括加载、验证、准备、解析和初始化。当JVM需要加载一个类时,它会...
3-7Tomcat中自定义类加载器的使用与源码实现(2).mp4
Java自定义类加载器代码示例 Java自定义类加载器代码示例是一种使用Java语言实现的类加载器示例,主要用于加载Java类文件。类加载器是Java虚拟机(JVM)中的一种机制,用于将Java类文件加载到JVM中,以便JVM可以...
3. Application ClassLoader:也称为系统类加载器,负责加载用户类路径`-cp`或`-classpath`指定的所有类。 当一个类被加载时,如果它的父类加载器无法加载该类,那么会将任务委派给子类加载器。这就是著名的"委托...
### Java自定义类加载器(Class Loader)详解 #### 一、引言 在Java语言中,类加载机制是其动态特性的核心之一。通过类加载器(Class Loader),Java程序能够在运行时根据需要加载所需的类,从而实现高度的灵活性...
自定义加载器需要重写`findClass()`或`loadClass()`方法。在`MyClassLoader2`示例中,它尝试从指定路径查找类的字节码文件,并通过`defineClass()`方法将字节码转换为Class对象。 ```java public Class<?> find...
JCL是可配置,动态和可扩展的自定义类加载器,可直接从Jar文件和其他来源加载Java类。 这样做的动机是创建隔离的类加载器,该类加载器可以轻松地与IoC框架(如Spring)和Web应用程序集成。 整个库,包括其代码库和...
Java语言中的自定义类加载器(Custom Class Loader)允许开发者扩展Java虚拟机(JVM)的类加载机制,以便从非标准位置加载类。在Java中,类的加载过程遵循“双亲委派模型”(Parent Delegation Model),即一个类...
这种设计遵循了**委托模式**,即自定义类加载器在尝试加载类之前会先询问其父加载器是否能加载该类,只有在父加载器无法加载时才会尝试自己加载。 #### 八、类的卸载与重载 1. **卸载**: Java类一旦被加载到JVM中...
- `findClass()`:从Java 1.2开始,自定义类加载器通常只需要重写此方法,当父类加载器找不到类时,此方法会被调用来查找类。 - `defineClass()`:这是一个final方法,用于将字节数组转换为Class对象,实现字节码...
2. 安全性问题:如果允许用户自定义类加载器任意加载代码,可能会破坏系统的安全策略,因为类加载器可以加载不受限制的代码。 3. 单例模式的实现:在多线程环境中,如果每个线程都有自己的类加载器,可能导致单例...