`

classloader机制对比

 
阅读更多

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机制

容器 jboss(4.05) tomcat(6.0.30) jetty(7.1.20)
支持child/parent first设置(默认值) Java2ClassLoadingCompliance=false delegate=false _parentLoaderPriority=false
过滤package配置 FilteredPackages
默认值: javax.servlet,org.apache.commons.logging
packageTriggers
默认配置:org.apache.commons.logging
systemClasses
默认配置:java. 
javax.
org.xml.
org.w3c.
org.apache.commons.logging.
org.eclipse.jetty.continuation.
org.eclipse.jetty.jndi.
org.eclipse.jetty.plus.jaas.
org.eclipse.jetty.websocket.
org.eclipse.jetty.servlet.DefaultServlet.
特殊性

1. UseJBossWebLoader=false时,过滤packages才能生效

2. UseJBossWebLoader=true时,不支持过滤packages

3. jboss 5.0以后UseJBossWebLoader参数将不支持

1. 在执行child/parent判断之前,会委托system classloader装载系统class,比如jdk的lib库

1. 多了一个serverclass配置,如果是serverclass优先采用child first

2. systemclass默认的配置,多了javax,org.xml,org.w3c配置。

相关文档 svn url : http://anonsvn.jboss.org/repos/jbossas/tags/JBoss_4_0_5_GA_CP18
jboss社区classloader文档: http://community.jboss.org/wiki/ClassLoadingConfiguration

svn url : http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk

官方classloader机制: http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html

svn url : http://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/tags/jetty-7.2.0.v20101020/

classloader 官方文档: http://docs.codehaus.org/display/JETTY/Classloading

 
 

 





在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的运行机制

    通过对比可以看出,JDK包含了JRE的所有功能,同时还增加了用于开发Java应用的工具集。因此,对于开发者来说,安装JDK是必要的选择,因为它不仅能够满足运行Java程序的需求,还能支持Java应用的开发工作。 综上所述...

    AOP动态代理(反射机制)

    它需要三个参数:一个ClassLoader,表示用来加载代理类的类加载器;一个Interface[],表示代理对象需要实现的接口列表;以及一个InvocationHandler,表示代理对象在调用接口方法时会委托给的处理程序。 2. **...

    Java版水果管理系统源码-java-advanced:java-高级

    使用自定义Classloader机制,实现xlass的加载。 实现xlass打包的xar(类似class文件打包的jar)的加载:xar里是xlass。 基于自定义Classloader实现类的动态加载和卸载:需要设计加载和卸载。 基于自定义Classloader...

    Java基础知识点 - 内容比较全面

    5. **JVM ClassLoader机制**:ClassLoader负责加载类到JVM中,包括Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader。类加载遵循双亲委派模型,确保类加载的唯一性。 6. **Java中的synchronized使用...

    安卓插件机制相关-插件化动态加载在宿主程序中调用插件的组件或类.zip

    - ** DexClassLoader**:Android系统默认的ClassLoader无法直接加载外部的Dex文件,所以需要自定义ClassLoader,如DexClassLoader,来加载插件的.dex文件。 - **类加载策略**:为了确保宿主和插件之间的类不冲突,...

    一种面向构件化软件的在线演化方法.pdf

    6. **技术原理**:方案的核心是增强构件容器,扩展Java的ClassLoader机制,识别并管理构件实例的生命周期,确保在演化过程中不影响已有的服务。 7. **实现步骤**:文章详细介绍了如何通过改进容器来实现构件的在线...

    编程***经验(汇总)

    #### Java类加载机制 - **类的查找与加载顺序**:Bootstrap ClassLoader负责加载JRE的核心类库,Extension ClassLoader加载扩展类库,而Application ClassLoader则负责加载应用程序的类。这种层次结构确保了核心库...

    安卓逆向学习笔记之ART定制方案比较和流程.docx

    本文档旨在探讨Android Runtime (ART)环境下,针对不同ART定制方案的对比分析,并介绍实现逆向工程过程中的具体步骤与技巧。逆向工程是研究软件内部工作原理的一种技术手段,在移动开发、安全审计等领域具有广泛的...

    java面试题(经典)

    - 类加载器:了解Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader和自定义类加载器。 - JVM性能调优:包括堆内存、栈内存、方法区的调整。 10. **设计模式** - 了解常见的设计模式,如工厂模式...

    Java常用基础知识-kaic.docx

    4. Exception 和 Error 的对比:Exception 是程序运行过程中预期的异常,可以通过 try-catch 语句进行捕获处理。它们分为可检查异常(需要在编译时处理)和不检查异常(如运行时异常,通常与编程错误有关)。Error ...

    java 经典 面试题 绝对有用

    - **类加载器**:分析Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader的作用。 - **JVM调优**:通过JVM参数调整内存设置,优化程序性能。 10. **Spring框架** - **依赖注入**:理解DI的概念,...

    方立勋30天轻松掌握JavaWeb视频笔记

    - **HTTP版本差异**:对比HTTP 1.0与HTTP 1.1的主要区别。 - **请求与响应**:详细介绍HTTP请求与响应的格式和结构。 - **状态码与头信息**:分析常见的HTTP状态码及请求响应头的意义。 #### Servlet开发 ##### 13...

    java面试评价表

    - **ClassLoader**:讲解JVM中的类加载机制,包括自定义类加载器的实现。 - **双亲委派模型**:解释双亲委派机制的运作过程及其好处,以及破坏该模型的场景。 - **JVM调优**:探讨常见的JVM性能调优方法,包括具体的...

    Android界面防劫持,Activity防劫持,无视Android系统版本限制,无需操作栈

    7. **自定义ClassLoader**:替换默认的ClassLoader,对加载的类进行检查,防止恶意代码注入。 8. **异常处理**:添加异常捕获和处理机制,当检测到异常行为时,能够及时恢复或退出Activity,避免被恶意利用。 9. *...

    OpenJDK1.8源码简析V1.0.pptx

    OpenJDK 1.8的源码主要由C/C++编写,采用gmake进行编译,其结构包括线程模型(如OSThread、JAVAThread)、对象管理(HEAP、STACK、ClassLoader)、代码生成与解释器、GC框架、运行时监控、基础设施以及库使用等。...

    Java基础面试题

    3. **Java接口与C++虚类的对比**: - 相同点:两者都用于实现多态性,允许子类重写父类的方法。 - 不同点:Java接口中没有方法实现,所有方法默认为public抽象;接口支持多重继承,而C++类只能单继承。C++的虚类...

    AndFixdemo源码及补丁文件

    - **理解Android ClassLoader**:AndFix 需要通过自定义ClassLoader来加载补丁,因此要了解如何替换或扩展Android的默认ClassLoader。 - **熟练运用反射**:在实际应用AndFix时,可能需要通过反射技术来定位和修复...

    tomcat 学习与分析总结资料

    主要有三个类加载器:Bootstrap ClassLoader、Common ClassLoader和Webapp ClassLoader。Bootstrap加载JDK的类,Common加载`common.loader`指定的类,而Webapp类加载器则负责加载每个Web应用自己的类。理解类加载...

    JAVA面试100题

    - **自动内存管理**:Java提供了垃圾回收机制来自动管理内存,这与C++中的手动管理形成鲜明对比。 - **资源释放**:在Java中,当一个对象不再被引用时,垃圾回收器会自动回收其占用的内存。而在C++中,需要程序员...

Global site tag (gtag.js) - Google Analytics