http://www.iteye.com/topic/826661
tomcat6.0.30 classloader机制
tomcat相比于jboss4.05概念上简介了很多,不过tomcat 6版本相比于tomcat 5有一些变化,少了一些shared lib库的概念。
Bootstrap
|
System
|
Common
/ \
Webapp1 Webapp2 ...
一个树状结构,相信大家差不多都知道tomcat默认是以child first装载class,优先载入web中的class类,找不到才会去装载公用类。
总结和对比一下(jboss,tomcat,jetty)容器的classloader机制
在J2EE的项目中,容器给我们提供的热部署功能使得我们不用重启动容器而修改我们的代码。比如使用Weblogic,我们可以在Weblogic-
application.xml中配置是否支持热部署Servlet。查阅Weblogc
文档,其实在Weblogic中,EJB组件也是可以热部署的,但如何要热部署EJB组件,Weblogc要求必须自定义ClassLoder。
JVM规范中没有指定JVM支持动态加载修改过的类。类的加载,卸载对于程序员是透明的。如果我们要实现类的动态加载我们就要理解JVM本身类的加载与卸载的原理,实现热部署。对于JVM加载类方面的资料在网上很多的,在这里我做简单概述:
(1)JVM加载时通过ClassLoader加载的。
(2)JVM有3层继承关系的ClassLoder 分别是:
-----BootStrap类加载器 加载JRE/lib
-----------------ExtClassLoader
加载 JRE
/lib/ext
----------AppClassLoader 加载ClassPath/
(3)为了安全性,JVM加载采用了双亲委派机制,如何理解呢,就是当需要加载一个类时,当前的ClassLoader先请求父ClassLoader,依次
类推,直到父类的ClassLoader无法加载时,才通过当前的ClassLoser加载,这就保证了像String这样的类型必须使用JRE里面的, 使得
JRE lib 下类不会被修改。同时避免了ClassCaseException。
(4)在JVM中,一个实例是通过本身的类名+加载它的ClassLoader识别的,也就是说 不同的ClassLoader 加载同一个类在JVM是不同的。
(5)同一个ClassLoader是不允许多次加载一个类的,否则会报java.lang.LinkageError。attempted duplicate class definition for
name XXX,在下面的例子中会指出。
既然JVM不支持热部署,那么要实现热部署,就必须自定义ClassLoader,当类被修改过后,加载该类。下面通过代码说明:
package
classloader;
/**
*
@author
vma
*/
// 自定义一个类加载器
public
class
DynamicClassLoader
extends
ClassLoader {
public
Class
<?>
findClass(
byte
[] b)
throws
ClassNotFoundException {
return
defineClass(
null
, b,
0
, b.length);
}
package
classloader;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.IOException;
/**
*
@author
vma
*/
public
class
ManageClassLoader {
DynamicClassLoader dc
=
null
;
Long lastModified
=
0l
;
Class c
=
null
;
//加载类, 如果类文件修改过加载,如果没有修改,返回当前的
public
Class loadClass(String name)
throws
ClassNotFoundException, IOException{
if
(isClassModified(name)){
dc
=
new
DynamicClassLoader();
return
c
=
dc.findClass(getBytes(name));
}
return
c;
}
//判断是否被修改过
private
boolean
isClassModified(String filename) {
boolean
returnValue
=
false
;
File file
=
new
File(filename);
if
(file.lastModified()
>
lastModified) {
returnValue
=
true
;
}
return
returnValue;
}
// 从本地读取文件
private
byte
[] getBytes(String filename)
throws
IOException {
File file
=
new
File(filename);
long
len
=
file.length();
lastModified
=
file.lastModified();
byte
raw[]
=
new
byte
[(
int
) len];
FileInputStream fin
=
new
FileInputStream(file);
int
r
=
fin.read(raw);
if
(r
!=
len) {
throw
new
IOException(
"
Can't read all,
"
+
r
+
"
!=
"
+
len);
}
fin.close();
return
raw;
}
}
测试类;Main 每隔 5s 加载一次
package
classloader;
import
java.io.IOException;
import
java.lang.reflect.InvocationTargetException;
import
java.lang.reflect.Method;
/**
*
*
@author
vma
*/
public
class
Main {
/**
*
@param
args the command line arguments
*/
public
static
void
main(String[] args)
throws
ClassNotFoundException, IOException, NoSuchMethodException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, InstantiationException, InterruptedException
{
String path
=
"
D://deploy//JDBC//ClassLoader//build//classes//classloader//LocalClass.class
"
;
ManageClassLoader mc
=
new
ManageClassLoader();
while
(
true
){
Class c
=
mc.loadClass(path);
Object o
=
c.newInstance();
Method m
=
c.getMethod(
"
getName
"
);
m.invoke(o);
System.out.println(c.getClassLoader());
Thread.sleep(
5000
);
}
}
被加载的类
/**
*
*
@author
vma
*/
public
class
LocalClass {
public
void
getName() {
System.out.println(
"
hahaha
"
);
}
}
运行时,每隔5s 输出:
hahaha
classloader.DynamicClassLoader@61de33
当我们修改
System.out.println(
"
hahaha
"
); --->
System.out.println(
"
changed
"
);
编译LocalClass后
输出变为:
changed
classloader.DynamicClassLoader@173a10f
在
loadClass
中, 我们必须重新初始化一个ClassLoader,负责就会违背
同一个ClassLoader是不允许多次加载一个类的。
public
Class loadClass(String name)
throws
ClassNotFoundException, IOException{
if
(isClassModified(name)){
dc
=
new
DynamicClassLoader();
return
c
=
dc.findClass(getBytes(name));
}
return
c;
}
当然,容器的实现机制肯定及其完善,不可能周期性的加载,可能回通过监听机制,动态加载修改过的类。但它的实现机制肯定也是重新
实例化一个ClassLoder,加载需要加载的类。
分享到:
相关推荐
理解Java ClassLoader机制
ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的ClassLoader运行机制 自己写的
内容简介: ClassLoader体系结构 类装载器在JVM中并不是唯一的,JVM自带了三个装载器,用户也可以根据自己的需求自定义新的装载器,这些装载器的体系结构可以看作是树状结构,如图1所示:
ClassLoader类加载机制和原理详解
JVM内存模型,类加载模式工作机制详细,内存屏障,类从被加载到虚拟机内存中开始,直到卸载出内存为止,它的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三...
Java 虚拟机中ClassLoader 相关简介 双亲委托机制 Android 中ClassLoader 简介
由osgi引出的classLoader的大总结(整理理解ClassLoader)
【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!
主要介绍了Java Classloader机制用法代码解析,涉及JDK默认ClassLoader,双亲委托模型,自定义ClassLoader等相关内容,具有一定借鉴价值,需要的朋友可以参考下
用于验证理解Android中Classloader加载类机制的程序demo,从中可以对比DexClassLoader和PathClassLoader的区别联系。
类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。
该电子书详细介绍了java虚拟机类加载机制,对于深入理解jvm工作原理有很好的帮助作用,对于初学java,有一定工作经验的小伙伴来说是一本提高自身java素养,夯实自己java基本技能的“葵花宝典”。
自定义classloader的使用
ClassLoader原理,ClassLoader原理 ClassLoader原理
ClassLoader一个经常出现又让很多人望而却步的词,本文将试图以最浅显易懂的方式来讲解 ClassLoader,希望能对不了解该机制的朋友起到一点点作用
Java ClassLoader定制实例
破解java加密的ClassLoader.java,在classloader植入破解代码
主要介绍了Java中的Classloader的运行机制,包括从JVM方面讲解类加载器的委托机制等,需要的朋友可以参考下
1. ClassLoader(类加载机制) 3. findLoadedClass (查找JVM已经加载过的类) 4. defineClass (定义一个Java
java classloader classpath 张孝祥