《深入理解JAVA虚拟机》9.类加载及执行子系统的案例与实践

一、Tomcat:正统的类加载器架构

从图中的委派关系中可以看出:
  • CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用。
  • CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。
  • WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
  • JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.Class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。
WebAppClassLoader
    1.检查我们先前加载的本地类缓存,加载过就不加载了
    2.通过javase 的 ClassLoader检查源码是否有重复类,有的话就通过javaseLoader加载
    3.通过filter方法判断一些特定的类,如果属于特定的类,就通过父加载器加载
    4.剩余的就自己加载,加载失败的通过父类加载(破坏了双亲委派)
如果tomcat的CommonClassLoader想加载 WebAppClassLoader中的类,那么可以使用线程上下文类加载器实现。
 

二、字节码生成技术与动态代理的实现

 
使用Proxy.newProxyInstance(类加载器,类,被代理对象)生成代理对象,可使用参数sun.misc.ProxyGenerator.saveGeneratedFiles=true保存代理后的class文件。源码jdk/src/share/classes/sun/misc下的sun.misc.ProxyGenerator。
 

三、自己动手实现远程执行功能

ByteUtils:主要实现字节数组的操作,如字节数组的的替换。
ClassModifier:实现修改Class字节码,修改常量池的符号引用。
ClassLoader:Java抽象的ClassLoader
HotSwapClassLoader:主要是暴露 ClassLoader的defineClass()。
HackSystem:挟持System,其中out、err替换,其余都转发到System处理。
JavaClassExecuter:执行器,创建ClassModifer修改目标Class byte的System的符号引用为HackSystem,然后使用HotSwapClassLoader加载修改后的类,再使用反射运行该类的main方法,异常信息也输出到 HackSystem,返回HackSystem中的缓存字符串。
 
代码如下:
public class JavaClassExecuter {
    public static String execute(byte[] classByte){
        //清理HackSystem中缓存
        HackSystem.clearBuffer ();
        //创建Class修改器
        ClassModifier cm = new ClassModifier (classByte);
        //修改System符号引用为HackSystem
        byte[] modifyBytes = cm.modifyUTF8Constant ("java/lang/System","javasource/jvm/hotswap/HackSystem");
        //创建类加载器
        HotSwapClassLoader loader = new HotSwapClassLoader ();
        //加载修改后的Class
        Class clazz = loader.loadByte (modifyBytes);
        try {
            //反射调用main方法
            Method method = clazz.getMethod ("main",new Class[]{String[].class});
            method.invoke (null,new String[]{});
        }catch (Exception e){
            //将异常也输出到HackSystem中
            e.printStackTrace (HackSystem.out);
        }
        //返回HackSystem中的缓存内容
        return HackSystem.getBufferString ();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值