- 浏览: 154111 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
eclipseakwolf:
很棒的文章
Shiro User Manual-Authentication -
xugangqiang:
very good
Java Concurrent Programming (1) -
jlcon:
是不是AbstractShiroTest还需要继承EasyMo ...
Shiro User Manual-Testing -
jlcon:
createNiceMock这个EasyMockSupport ...
Shiro User Manual-Testing -
Technoboy:
53873039oycg 写道楼主:问下,你的那个dao接口的 ...
Shiro Example
1. ClassLoader
类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。
2. ClassLoader Hierarchy
JVM在加载类时,使用的是双亲委托模式(delegation model),也就是说除了Bootstrap ClassLoader之外,每个ClassLoader都有一个Parent ClassLoader。ClassLoader是按需进行加载class文件。当ClassLoader试图加载一个类时,首先检查本地缓冲,查看类是否已被加载,如果类没有被加载,尝试委托给父ClassLoader进行加载,如果父ClassLoader加载失败,才会由该ClassLoader进行加载,从而避免了重复加载的问题。一下为类装载器层次图:
Bootstrap ClassLoader:负责加载java_home/lib目录下的核心类或- Xbootclasspath指定目录下的类。
Extension ClassLoader:负责加载java_home/lib/ext目录下的扩展类或 -Djava.ext.dirs 指定目录下的类。
System ClassLoader:负责加载-classpath/-Djava.class.path所指的目录下的类。
如果类App1在本地缓冲中没有class文件(没有被加载),那么它会自底向上依次查找是否已经加载了类,如果已经加载,则直接返回该类实例的引用。如果BootstrapClassLoader也未成功加载该类,那么会抛出异常,然后自顶向下依次尝试加载,如果到App1 ClassLoader还没有加载成功,那么会抛出ClassNotFoundException异常给调用者。
我们看到,当前系统类装载器为AppClassLoader,AppClassLoader的父类装载器是ExtClassLoader,ExtClassLoader的父装载器为null,表示为BootstrapClassLoader。BootstrapClassLoader由JVM采用本地代码实现,因此没有对应的Java类,所以ExtClassLoader的getParent()返回null。
ClassLoader的职责之一是保护系统名字空间。以下为ClassLoader类部分代码:
那么,当我们定义如下类Foo,虽然能够通过编译,但是会报java.lang.SecurityException: Prohibited package name: java.lang异常,因为我们试图将Foo类写入到java.lang包下。
3. 定制ClassLoader
Java自带的ClassLoader类的定义为:
启动类加载器是JVM通过调用ClassLoader.loadClass()方法。
loadClass(String name, boolean resolve)方法中的resolve如果为true,表示分析这个Class对象,包括检查Class Loader是否已经初始化等。loadClass(String name) 在加载类之后不会对该类进行初始化,直到第一次使用该类时,才会对该类进行初始化。
那么,我们在定制ClassLoader的时候,通常只需要覆写findClass(String name)方法。在findClass(String name)方法内,我们可以通过文件、网络(URL)等形式获取字节码。以下为获取字节码的方法:
在取得字节码后,需要调用defineClass()方法将字节数组转换成Class对象,该方法签名如下:
对于相同的类,JVM最多会载入一次。如果同一个class文件被不同的ClassLoader载入(定义),那么载入后的两个类是完全不同的。
以上程序需要保证Foo.class文件不在classpath路径下。从而使AppClassLoader无法加载Foo.class。
输出结果:
4. Web应用的ClassLoader
绝大多数的EJB容器,Servlet容器等都会提供定制的ClassLoader,来实现特定的功能。但是通常情况下,所有的servlet和filter使用一个ClassLoader。每个jsp都使用一个独立的ClassLoader。
5. 隐式(implicit)和显示(explicit)的加载
隐式加载:我们使用new关键字实例化一个类,就是隐身的加载了类。
显示加载分为两种:
java.lang.Class的forName()方法;
java.lang.ClassLoader的loadClass()方法。
Class.forName()方法有两个重载的版本:
可以看出,forName(String className)默认以true和ClassLoader.getCallerClassLoader()调用了三参数的重载方法。ClassLoader.getCallerClassLoader()表示以caller class loader加载类,并会初始化类(即静态变量会被初始化,静态初始化块中的代码也会被执行)。如果以false和ClassLoader.getCallerClassLoader()调用三参数的重载方法,表示加载后的类不会被初始化。
ClassLoader.loadClass()方法在类加载后,也同样不会初始化类。
6. 两个异常(exception)
NoClassDefFoundError: 当java源文件已编译成.class文件,但是ClassLoader在运行期间搜寻路径load某个类时,没有找到.class文件则抛出这个异常。
ClassNotFoundException: 试图通过一个String变量来创建一个Class类时不成功则抛出这个异常
哈哈,word2007英文版
同行!
请你好好的了解一下,在到我这里发帖!不要随便说话,很不厚道,懂吗?你更要好好的看看,你贴的地址是讲什么的!
BootstrapClassLoader是最顶层的啊。它加载不成功,应该交给他的下一层尝试加载啊?为什么要抛异常呢?
抛出ClassNotFoundException异常
BootstrapClassLoader是最顶层的啊。它加载不成功,应该交给他的下一层尝试加载啊?为什么要抛异常呢?
类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取 Java 字节代码,并转换成 java.lang.Class 类的一个实例。
2. ClassLoader Hierarchy
JVM在加载类时,使用的是双亲委托模式(delegation model),也就是说除了Bootstrap ClassLoader之外,每个ClassLoader都有一个Parent ClassLoader。ClassLoader是按需进行加载class文件。当ClassLoader试图加载一个类时,首先检查本地缓冲,查看类是否已被加载,如果类没有被加载,尝试委托给父ClassLoader进行加载,如果父ClassLoader加载失败,才会由该ClassLoader进行加载,从而避免了重复加载的问题。一下为类装载器层次图:
Bootstrap ClassLoader:负责加载java_home/lib目录下的核心类或- Xbootclasspath指定目录下的类。
Extension ClassLoader:负责加载java_home/lib/ext目录下的扩展类或 -Djava.ext.dirs 指定目录下的类。
System ClassLoader:负责加载-classpath/-Djava.class.path所指的目录下的类。
如果类App1在本地缓冲中没有class文件(没有被加载),那么它会自底向上依次查找是否已经加载了类,如果已经加载,则直接返回该类实例的引用。如果BootstrapClassLoader也未成功加载该类,那么会抛出异常,然后自顶向下依次尝试加载,如果到App1 ClassLoader还没有加载成功,那么会抛出ClassNotFoundException异常给调用者。
public static void main(String[] args) { ClassLoader cl = ClassLoader.getSystemClassLoader(); while(cl != null){ System.out.println(cl); System.out.println("parent class loader: " + cl.getParent()); cl = cl.getParent(); } }
sun.misc.Launcher$AppClassLoader@19821f parent class loader: sun.misc.Launcher$ExtClassLoader@addbf1 sun.misc.Launcher$ExtClassLoader@addbf1 parent class loader: null
我们看到,当前系统类装载器为AppClassLoader,AppClassLoader的父类装载器是ExtClassLoader,ExtClassLoader的父装载器为null,表示为BootstrapClassLoader。BootstrapClassLoader由JVM采用本地代码实现,因此没有对应的Java类,所以ExtClassLoader的getParent()返回null。
ClassLoader的职责之一是保护系统名字空间。以下为ClassLoader类部分代码:
private ProtectionDomain preDefineClass(String name, ProtectionDomain protectionDomain) { if (!checkName(name)) throw new NoClassDefFoundError("IllegalName: " + name); if ((name != null) && name.startsWith("java.")) { throw new SecurityException("Prohibited package name: " + name.substring(0, name.lastIndexOf('.'))); } if (protectionDomain == null) { protectionDomain = getDefaultDomain(); } if (name != null) checkCerts(name, protectionDomain.getCodeSource()); return protectionDomain; }
那么,当我们定义如下类Foo,虽然能够通过编译,但是会报java.lang.SecurityException: Prohibited package name: java.lang异常,因为我们试图将Foo类写入到java.lang包下。
package java.lang; public class Foo { public static void main(String args[]) throws Exception { Foo f = new Foo(); System.out.println(f.toString()); } }
3. 定制ClassLoader
Java自带的ClassLoader类的定义为:
public abstract class ClassLoader{ }
启动类加载器是JVM通过调用ClassLoader.loadClass()方法。
public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { // First, check if the class has already been loaded Class c = findLoadedClass(name); if (c == null) { try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClass0(name); } } catch (ClassNotFoundException e) { // If still not found, then invoke findClass in order // to find the class. c = findClass(name); } } if (resolve) { resolveClass(c); } return c; } protected Class<?> findClass(String name) throws ClassNotFoundException { throw new ClassNotFoundException(name); }
loadClass(String name, boolean resolve)方法中的resolve如果为true,表示分析这个Class对象,包括检查Class Loader是否已经初始化等。loadClass(String name) 在加载类之后不会对该类进行初始化,直到第一次使用该类时,才会对该类进行初始化。
那么,我们在定制ClassLoader的时候,通常只需要覆写findClass(String name)方法。在findClass(String name)方法内,我们可以通过文件、网络(URL)等形式获取字节码。以下为获取字节码的方法:
public InputStream getResourceAsStream(String name); public URL getResource(String name); public InputStream getResourceAsStream(String name); public Enumeration<URL> getResources(String name) throws IOException;
在取得字节码后,需要调用defineClass()方法将字节数组转换成Class对象,该方法签名如下:
protected final Class<?> defineClass(String name, byte[] b, int off, int len, ProtectionDomain protectionDomain) throws ClassFormatError
对于相同的类,JVM最多会载入一次。如果同一个class文件被不同的ClassLoader载入(定义),那么载入后的两个类是完全不同的。
public class Foo{ // private static final AtomicInteger COUNTER = new AtomicInteger(0); public Foo() { System.out.println("counter: " + COUNTER.incrementAndGet()); } public static void main(String args[]) throws Exception { URL urls[] = new URL[]{new URL("file:/c:/")}; URLClassLoader ucl1 = new URLClassLoader(urls); URLClassLoader ucl2 = new URLClassLoader(urls); Class<?> c1 = ucl1.loadClass("Foo"); Class<?> c2 = ucl2.loadClass("Foo"); System.out.println(c1 == c2); c1.newInstance(); c2.newInstance(); } }
以上程序需要保证Foo.class文件不在classpath路径下。从而使AppClassLoader无法加载Foo.class。
输出结果:
false counter: 1 counter: 1
4. Web应用的ClassLoader
绝大多数的EJB容器,Servlet容器等都会提供定制的ClassLoader,来实现特定的功能。但是通常情况下,所有的servlet和filter使用一个ClassLoader。每个jsp都使用一个独立的ClassLoader。
5. 隐式(implicit)和显示(explicit)的加载
隐式加载:我们使用new关键字实例化一个类,就是隐身的加载了类。
显示加载分为两种:
java.lang.Class的forName()方法;
java.lang.ClassLoader的loadClass()方法。
Class.forName()方法有两个重载的版本:
public static Class<?> forName(String className) throws ClassNotFoundException { return forName0(className, true, ClassLoader.getCallerClassLoader()); } public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException
可以看出,forName(String className)默认以true和ClassLoader.getCallerClassLoader()调用了三参数的重载方法。ClassLoader.getCallerClassLoader()表示以caller class loader加载类,并会初始化类(即静态变量会被初始化,静态初始化块中的代码也会被执行)。如果以false和ClassLoader.getCallerClassLoader()调用三参数的重载方法,表示加载后的类不会被初始化。
ClassLoader.loadClass()方法在类加载后,也同样不会初始化类。
6. 两个异常(exception)
NoClassDefFoundError: 当java源文件已编译成.class文件,但是ClassLoader在运行期间搜寻路径load某个类时,没有找到.class文件则抛出这个异常。
ClassNotFoundException: 试图通过一个String变量来创建一个Class类时不成功则抛出这个异常
评论
17 楼
smallhand
2011-06-14
如果父ClassLoader加载失败,什么情况下会加载失败呢?已经加载的情况下?
16 楼
fhqyam
2011-06-13
新手学习了。。
15 楼
Technoboy
2011-06-12
lantian_123 写道
请问博主的画图工具用的什么啊?先谢谢你的分享精神
哈哈,word2007英文版
14 楼
lantian_123
2011-06-12
请问博主的画图工具用的什么啊?先谢谢你的分享精神
13 楼
Technoboy
2011-04-22
cobb.chan 写道
正在学习CLASSLOADER,此文章拜读了...感谢LZ分享精神。继续在JAVA道路上前行
同行!
12 楼
Technoboy
2011-04-20
whking2003 写道
Java的classloader机制已经不再是原始的向上代理了。像这种针对一个特定问题的帖子,起码应该多看点资料,随便看到一点点原型,就来发帖是不厚道的。
http://www.ibm.com/developerworks/cn/opensource/os-lo-ecl-classloader/
以上是一个DW上的文章,仅供参考。classloader机制在web环境和OGSI环境中,分别都会有对应的问题。尤其是对Log4j的影响,都是值得花一些时间去了解的。
http://www.ibm.com/developerworks/cn/opensource/os-lo-ecl-classloader/
以上是一个DW上的文章,仅供参考。classloader机制在web环境和OGSI环境中,分别都会有对应的问题。尤其是对Log4j的影响,都是值得花一些时间去了解的。
请你好好的了解一下,在到我这里发帖!不要随便说话,很不厚道,懂吗?你更要好好的看看,你贴的地址是讲什么的!
11 楼
whking2003
2011-04-20
Java的classloader机制已经不再是原始的向上代理了。像这种针对一个特定问题的帖子,起码应该多看点资料,随便看到一点点原型,就来发帖是不厚道的。
http://www.ibm.com/developerworks/cn/opensource/os-lo-ecl-classloader/
以上是一个DW上的文章,仅供参考。classloader机制在web环境和OGSI环境中,分别都会有对应的问题。尤其是对Log4j的影响,都是值得花一些时间去了解的。
http://www.ibm.com/developerworks/cn/opensource/os-lo-ecl-classloader/
以上是一个DW上的文章,仅供参考。classloader机制在web环境和OGSI环境中,分别都会有对应的问题。尤其是对Log4j的影响,都是值得花一些时间去了解的。
10 楼
Technoboy
2011-04-19
chinpom 写道
虽然这类帖子在IE上已经数不胜数了,不过对于刚工作不到一年的偶,每次看一下还是有些收获的。貌似是LZ自己总结和写出来的,投这么多新手帖真的是不应该的啊
9 楼
Technoboy
2011-04-19
xsxjb 写道
引用
如果BootstrapClassLoader也未成功加载该类,那么会抛出异常,然后自顶向下依次尝试加载,
BootstrapClassLoader是最顶层的啊。它加载不成功,应该交给他的下一层尝试加载啊?为什么要抛异常呢?
抛出ClassNotFoundException异常
8 楼
xsxjb
2011-04-19
引用
如果BootstrapClassLoader也未成功加载该类,那么会抛出异常,然后自顶向下依次尝试加载,
BootstrapClassLoader是最顶层的啊。它加载不成功,应该交给他的下一层尝试加载啊?为什么要抛异常呢?
7 楼
chinpom
2011-04-19
虽然这类帖子在IE上已经数不胜数了,不过对于刚工作不到一年的偶,每次看一下还是有些收获的。貌似是LZ自己总结和写出来的,投这么多新手帖真的是不应该的啊
6 楼
cobb.chan
2011-04-19
正在学习CLASSLOADER,此文章拜读了...感谢LZ分享精神。继续在JAVA道路上前行
5 楼
Technoboy
2011-04-19
tcray 写道
不错 have studied
4 楼
tcray
2011-04-19
不错 have studied
3 楼
Technoboy
2011-04-18
fivestarwy 写道
尝试过看ClassLoader,Reflection的实现,里面全是native code,由于C++太烂不得不放弃
2 楼
fivestarwy
2011-04-17
尝试过看ClassLoader,Reflection的实现,里面全是native code,由于C++太烂不得不放弃
1 楼
程序新手
2011-04-17
再次学习啦
发表评论
-
video
2014-01-14 15:28 0testssssss -
Java Object Serialization
2011-06-02 10:57 27221. Overview Java中的序列化就是将Java对 ... -
Java Concurrent Programming (7)
2011-05-24 10:31 14827. Double-Checked Locking ... -
Java Concurrent Programming (6)
2011-05-16 11:46 15056. 并发集合类 Hashtable ... -
Java Concurrent Programming (5)
2011-05-12 21:09 17615 原子变量 java.util.concurrent.a ... -
Java Concurrent Programming (4)
2011-05-11 21:12 20414 锁 锁是递归的,是基于每线程的。锁提供了两种主要特性: ... -
Java Concurrent Programming (2)
2011-05-10 21:27 22172 线程死锁 死锁(dead lock)是指两个或多个线程 ... -
Java Concurrent Programming (3)
2011-05-10 09:13 28793 线程异常 线程在执行其run方法时,很有可能抛出异常。 ... -
Java Object Cloning
2011-05-05 22:03 22321. Overiew 在实际编程中,我们经常会遇到这样一个 ... -
Java Concurrent Programming (1)
2011-05-04 21:39 27561. 线程概述 线程(thread)的英文原意是" ... -
Java Class Loader
2011-04-17 18:54 67011. ClassLoader 类加载器(class loa ... -
Java RMI (2)
2011-04-02 10:11 14258. Activation 通过调用UnicastRemo ... -
Java RMI (1)
2011-04-01 15:54 16231. Java RMI Java Remote Method ...
相关推荐
自己收集的java class loader相关的一些网络资源文档, 希望对大家有所帮助
Java Class Loader总结
java 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loaderjava 类加载器 class loader
深入 Java 的Class Loader(类加载器)
Dynamic class loading in the Java Virtual Machine
The Class Loader Architecture The Java Class File The Java API The Java Programming Language Architectural Tradeoffs Future Trends On the CD-ROM The Resources Page 2 Platform independence Why ...
loader Byte code Verifier Javac Hello.java Netwo Hello class Interpreter code Runtime generator/ Hardware 1:编写代码 首先把我们想要计算机做的事情,通过Java表达出来,写成Java文件,这个过程就是 编写代码的...
Class Loader 是一个可视化的基本 .net 2.0 软件。 使用类加载器,您可以在没有命令提示符的情况下执行 .class 文件。 只需打开类文件!
js 类加载器(Java) 一种免费软件工具,用于捆绑和提供具有内置依赖项检测功能的大型 Javascript 代码库。 请参阅网站 和 github 仓库: : 了解更多信息。
6.2Security Checks in the Class Loader 6.3The Byte Code Verification Process 6.3.1The Byte Code Verifier 6.4Security in the Java Networking Package 6.5Summary 7. Multithreading 7.1...
主要介绍了Java中的类加载器,是Java入门学习中的基础知识,需要的朋友可以参考下
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412) at org.eclipse.osgi.internal....
你可以创建个新的class loader,然后用loadClass加载,再newInstance;原来加载的classloader是不能重新加载的;这算是一个典型的容器思路。 《深入理解java虚拟机》 2、对java“书写一次,到处运行”(Write once, ...
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421) at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412) at org.eclipse.osgi.internal....
描述Java虚拟机规范中关于内存管理的部分 主要介绍Runtime Data Area,包括Java Stack,Native Method Stack, ...还简要介绍了Runtime Data Area周边的模块,包括Class Loader,Execution Engine,Native Interface
Java虚拟机的基本结构图:Java虚拟机包含一个类装载器(class loader),可以从程序和API中装载class文件,其中API只有程序执行时需要的那
With OSGi-style classloading getting more and more traction, and a number of new Java modules/classloading specifications on the horizon, it was high time we revamped our classloading layer in order ...
The class definitions are basically ports to Java of the original header files in C/C++, and I deliberately decided to keep as much of the original syntax as possible. For example, here is a method ...
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325) at org.apache.catalina...
类加载器(class loader)是 Java™ 中的一个很重要的概念。类加载器负责加载 Java 类的字节代码到 Java 虚拟机中。本文首先详细介绍了 Java 类加载器的基本概念,包括代理模式、加载类的具体过程和线程上下文类加载...