`

JVM Class Loader(转)

    博客分类:
  • Java
阅读更多

Java本身是一种设计的非常简单,非常精巧的语言,所以Java背后的原理也很简单,归结
起来就是两点:

1、JVM的内存管理

理解了这一点,所有和对象相关的问题统统都能解决

2、JVM Class Loader

理解了这一点,所有和Java相关的配置问题,包括各种App Server的配置,应用的发布问
题统统都能解决


App Class Loader
|----- EJB Class Loader
|----- Web App Class Loader


如果在App Class Loader级别配置,是全局可见的。如果打包在EJB里面,那么就不会影响
到Web Application,反之亦然,如果你在WEB-INF下面放置Hibernate,也不会影响到EJB
。放在EJB Class Loader或者放在Web App Class Loader级别主要就是在局部范围内有效
,不影响到其它的应用。

试想,如果在一个Weblogic上面配置多个虚拟域,你使用www.bruce.com域名,开发你的网
站,我使用www.fankai.com开发我的网站,那么当然不希望我们的Hibernate相互干扰,所
以就可以放在 EJB Class Loader级别来配置Hibernate。

进一步阐述一下EJB Class Loader的问题:

先再次强调一下,Hibernate和EJB,和App Server不存在兼容性问题,他们本来就是不相
关的东西,就好像JDBC,相信没有人会认为JDBC和EJB不兼容吧,Hibernate也是一样,它
只和JDBC驱动,和数据库有兼容性问题,而和EJB,和App Server完全是不搭界的两回事。
凡是认为Hibernate和EJB不兼容的人,其实是都是因为对EJB学习的不到家,把责任推到H
ibernate身上了。

我前面的帖子提到过Class Loader的层次,这里不重复了,总之我们先来看看Class Load
er的作用范围:

BootStrap Class Loader:

load JRE\lib\rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.j
ar

Ext Class Loader:

load JRE\lib\ext目录下的库文件, load JRE\classes目录下的类

App Class Loader:

load CLASSPATH变量指定路径下的类

以上的load路径都是写死在JVM的C++源代码里面的,不能改变,详细请见王森的《Java深
度历险》

在一个特定的App Server上,Class Loader会继续向下继承,继承的层次会根据不同的Ap
p Server有所不同,但是肯定不会变的就是:

EJB Class Loader:

继承自App Class Loader,继承层次根据App Server有所不同,一个EJB Class Loader它
的load Class的范围仅限于JAR或者EAR范围之内。

Web App Class Loader:

继承自App Class Loader,继承层次根据App Server有所不同,一个Web App Class Load
er:它的load Class的范围在 WEB-INF\lib下的库文件和WEB-INF\classes目录下的class文
件。

Web App Class Loader很好理解,大家毕竟用的很多,App Server上的一个Web Applicat
ion会创建一个Web App Class Loader的实例去负责load class,所以如果你想让Hiberna
te只在这个Web Application内生效,把它放到WEB-INF\lib下去就好了。

如果你把Hibernate放到了CLASSPATH变量指定的路径下,而你在WEB-INF\lib也放了一份,
那么Web App Class Loader由于load范围所限,它会首先找到WEB-INF\lib下的那份Hiber
nate,按照它的配置来初始化Hibernate。

如果你把Hibernate放到了CLASSPATH变量指定的路径下,但你在WEB-INF\lib什么都没有放
,那么Web App Class Loader由于load范围所限,它根本什么都找不到,于是它把load H
ibernate的责任交给上一级的Class Loader,这样直到App Class Loader,它找到了Hibe
rnate,按照它的配置来初始化Hibernate。

EJB Class Loader稍微复杂一点,不那么容易理解。App Server会针对每一个EJB包文件创
建一个EJB Class Loader的实例,例如:

HelloRobbin.jar
HelloBruce.jar

当你把这两个jar发布到App Server上以后,会创建两个EJB Class Loader的实例,分别去
load这两个EJB包,比如说:

CLEJB_Robbin是load HelloRobbin.jar的
CLEJB_Bruce是load HelloBruce.jar的

那么CLEJB_Robbin的load范围就仅仅限于HelloRobbin.jar之内,它load不到HelloRobbin
.jar之外的任何文件,当然它也load不到HelloBruce.jar。

说到这里,我相信大家应该已经明白为什么EJB规范不允许EJB有IO操作了吧?因为EJB Cl
ass Loader根本找不到jar包之外的文件!!!

如果现在你想实现HelloRobbin.jar和HelloBruce.jar的互相调用,那么该怎么办?他们使
用了不同的EJB Class Loader,相互之间是找不到对方的。解决办法就是使用EAR。

现在假设HelloRobbin.jar和HelloBruce.jar都使用了Hibernate,看看该怎么打包和发布

HelloEJB.ear
|------ HelloRobbin.jar
|------ HelloBruce.jar
|------ Hibernate2.jar
|------ pojo.jar (定义所有的持久对象和hbm文件的jar包)
|------ cglib-asm.jar
|------ commons-beanutils.jar
|------ commons-collections.jar
|------ commons-lang.jar
|------ commons-logging.jar
|------ dom4j.jar
|------ odmg.jar
|------ log4j.jar
|------ jcs.jar
|------ hibernate.properties
|------ log4j.properties
|------ cache.ccf
|------ META-INF\application.xml (J2EE规范的要求,定义EAR包里面包括了哪几个EJB
)

除此之外,按照EJB规范要求,HelloRobbin.jar和HelloBruce.jar还必须指出调用jar包之
外的类库的名称,这需要在jar包的manifest文件中定义:

HelloRobbin.jar
|------ META-INF\MANIFEST.MF

MANIFEST.MF中必须包括如下一行:

Class-Path: log4j.jar hibernate2.jar cglib-asm.jar commons-beanutils.jar commo
ns-collections.jar commons-lang.jar
commons-logging.jar dom4j.jar jcs.jar odmg.jar jcs.jar pojo.jar

这样就OK了,当把HelloEJB.ear发布到App Server上以后,App Server创建一个EJB Clas
s Loader实例load EAR包里面的EJB,再根据EJB的jar包里面的MANIFEST.MF指出的Class-
Path去寻找相应的jar包之外的类库。

所以一个EAR包有点类似一个Web Application,EJB Class Loader的load范围也就是EAR范
围之内,它load不到EAR之外的文件。除非把Hibernate定义到CLASSPATH指定的路径下,在
这种情况下,EJB Class Loader找不到Hibernate,只能交给上一级的Class Loader,最后
由App Class Loader找到Hibernate,进行初始化。

没有写完,继续说...

由于EAR这样load Class规则,假设Robbin和Bruce都在同一个Weblogic上运行自己的网站
,而我们都不希望自己的程序里面的Hibernate配置被对方的搞乱掉,那么我们就可以这样
来做:

Robbin's Website:

Robbin.ear
|-------- robbin.war (把Web Application打包)
|-------- robbin.jar (把开发的EJB打包)
|-------- Hibernate2.jar
..........................
|-------- META-INF\application.xml


Bruce's Website:

Bruce.ear
|-------- bruce.war (把Web Application打包)
|-------- bruce.jar (把开发的EJB打包)
|-------- Hibernate2.jar
..........................
|-------- META-INF\application.xml

这样在同一个App Server上运行,就可以互相不干扰。

分享到:
评论

相关推荐

    如何在was中解决jar包冲突.pdf

    WAS 中类加载器是一个具有父子关系的分层结构,包括 JVM Class loader、WebSphere Extensions Class loader、WebSphere lib/app Class loader、WebSphere "server" Class loader 和 Application Module Class Loader...

    JVM加载class文件的原理机制.pdf

    JVM加载class文件的原理机制 JVM加载class文件的原理机制是Java虚拟机中一个非常重要的组件,负责将class文件加载到内存中,以便Java程序的执行。下面是JVM加载class文件的原理机制的详细介绍: 类加载的原理 在...

    jvm笔记

    JVM 可以分为三个部分:CLASS LOADER、RUN TIME DATA AREA 和 EXECUTION ENGINE。CLASS LOADER 负责加载类文件,并将其转换成 JVM 可以识别的格式。RUN TIME DATA AREA 负责存储类加载后的数据,而 EXECUTION ENGINE...

    class loader

    Dynamic class loading in the Java Virtual Machine

    JVM深入理解.xmind

    文件总结了JVM的体系结构:四大块,类装载子系统(class loader subsystem),执行引擎子系统(Executionengine子系统),垃圾回收系统(gc),运行时数据区(JVM内存)。

    JVM内核架构--JVM规范

    Method area: holds the details of each class loaded by the class loader subsystem. Heap: holds every object being created by the threads during execution Thread specific runtime data areas: Program ...

    Java JVM详解

    本文详细讲解了JVM(Java Virtual Machine)的方方面面,首先由java的特性来描绘JVM的大致应用,再细细阐述了JVM的原理及内存管理机制和调优.... 后面会再针对JVM的两大职责class loader和 execution engine进行讲解

    Java虚拟机 JVM 内存结构介绍

    描述Java虚拟机规范中关于内存管理的部分 主要介绍Runtime Data Area,包括Java Stack,Native Method Stack, ...还简要介绍了Runtime Data Area周边的模块,包括Class Loader,Execution Engine,Native Interface

    JVM--内存与垃圾回收篇1

    第二章 类加载子系统作用1、类加载子系统作用1. Class Loader SubSystem(类加载子系统)负责从文件系统或网络中加载Class Files,

    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解.docx

    * -class monitoring class loader * -gc monitoring garbage collector * -gccapacity monitoring garbage collector capacity * -gcnew monitoring new generation garbage collector * -gcnewcapacity monitoring...

    java7rt.jar源码-Java_JVM:这是我的JavaJVM学习笔记

    loader)创建一个初始类(Initial Class)来完成 2.执行 执行一个所谓的Java程序时,真正的执行的是一个叫做Java虚拟机的进程 3.退出 程序正常结束;程序遇到错误或异常时终止运行;Runtime或System类调用exit()方法...

    Java虚拟机工作原理详解

    * User-Defined Class Loader:这是开发人员通过拓展 ClassLoader 类定义的自定义加载器,加载程序员定义的一些类。 类加载器之间存在一种委派模式(Delegation Mode),当 JVM 加载一个类的时候,下层的加载器会将...

    深入解析Java中的Class Loader类加载器

    主要介绍了Java中的类加载器,是Java入门学习中的基础知识,需要的朋友可以参考下

    JAVA核心面试知识点整理

    JVM可以分为两部分:一部分是Class Loader,负责加载Class文件;另一部分是 Execution Engine,负责执行字节码。JVM的运行时内存可以分为五个部分:程序计数器、虚拟机栈、本地方法栈、堆、方法区。 1. 线程 在...

    深入java虚拟机(inside 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 ...

    java.lang.OutOfMemoryError处理错误

    2. Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理。 解决PermGen space错误的方法有多种,常见的...

    15 - ASM之方法Frame - 简书1

    JVM Architecture由Class Loader SubSystem、Runtime Data Areas和Execution Engine三个主要部分组成。其中,Runtime Data Areas包括Method Area、Heap Area、Stack Area、PC Registers和Native Method Stack等部分...

    leetcode200java-java:Java

    Class loader system + runtime data area + Execution Engine. Linux java -version javac -version sudo apt-get install default-jdk 集成开发环境 多变的 数据类型 数据 大小(字节) 范围 布尔值 对或错 1 真假...

    深入理解Java虚拟机笔记(带目录).docx

    * 启动类加载器(Bootstrap Class Loader):加载 Java 核心类。 * 扩展类加载器(Extension Class Loader):加载扩展类。 * 应用类加载器(Application Class Loader):加载应用类。 运行时栈帧的结构 Java 中...

    native-image-service-loader-demo:一个简单的演示项目,用于将ServiceLoader与GraalVM本机图像一起使用

    使用以下命令在JVM上运行: $ java -jar target/ServiceLoaderTest-1.0-SNAPSHOT.jar 输出应为: services.iterator().hasNext() = true service implementation = class service.ServiceImplementation0 service ...

Global site tag (gtag.js) - Google Analytics