JVM笔记整理(第9章 类加载及执行子系统的案例与实战)

时间:2022-12-25 14:14:43

参考资料:《深入理解java虚拟机》



首先,这节内容是非常少的,主要是针对从源程序编译为.class文件,到加载到JVM运行过程中,人工可以干预哪些环节,以及对于干预的实例。

 

 

前言:在class文件格式和执行引擎这部分中,用户程序能干预到的非常少,比如文件格式存储必须是字节码格式是固定的,类何时加载,如何连接,已经JVM如何执行字节码指令等等,这些都是JVM自己去实现的。所以想要对我们写的程序、JVM功能进行干预,当然这种干预是通过我们写代码进行干预的,那么也就还有2个功能是可以改造的:字节码生成、类加载器。那么,本章,就是在这两个功能的基础上,分别列举了两个例子,描述我们是如何对这两个功能进行改造的。

对于类加载器的实际改造的两个例子:一个是传统的类加载器,就是tomcat的类加载器;另一个是比较灵活的类加载器,OSGi 。

对于字节码生成的过程干预的两个例子:一个是通过动态代理技术去控制我们程序中一部分字节码的生成;另一个是介绍了一个可以直接修改字节码的工具Retrotranslator,它可以实现将JDK1.5编译出来的.class文件转为可以在JDK1.3或者1.4上面部署的版本。它是“java逆向移植”工具中比较出色的一个。

 

 

 

1、类加载器

 

1.1、Tomcat类加载器

1.1.1、定位:正统的类加载器架构。

1.1.2、完成功能:其他web服务器也一样

A、部署在同一个服务器上的两个web应用程序所使用的java类库可以实现相互隔离。

B、部署在同一个服务器上的两个web应用程序使用的java类库可以实现相互共享。

C、服务器本身要尽可能不受部署web程序的影响。

D、大多数服务器应该支持HotSwap(热替换)功能。

1.1.3、多个ClassPath:为了支持上述4个功能而存在。这样每个ClassPath下面,可以存放不同的类库,并且,通常每个目录下面,都有一个自定义类加载器去加载里面的java类库。

 

1.2、OSGi

1.2.1、名称:全名英文:Open ServiceGateway Initiative

全名中文:开放服务网关协议

1.2.2、地位:是java语言的动态模块化规范。

1.2.3、OSGi中每个模块(Bundle)和java类库区别不大的表现。

A、两者都一般以jar封装。

B、内部存储的都是Java Package和Class.

1.2.4、Bundle特点:

A、每个Bundle可以声明它依赖的JavaPackage(通过Import-Package描述),也可以声明它允许导出发布的Java Package(通过Export-Package描述)。

B、Bundle之间的关系从传统的上下层依赖关系改为:平级模块间的依赖。

C、一个Bundle里面只有被Export过的Package才能被外界访问。

1.2.5、OSGi“诱人”的特点

A、基于OSGi的程序很可能实现模块级的热插拔。

B、最重要的是,归于其灵活的类加载机制。OSGi各个Bundle中的类加载器之间只有规则,没有固定的委派关系。

 

 

 

2、字节码生成

 

2.1、动态代理技术对字节码生成的影响

2.1.1、动态代理技术例子: Spring中的Bean技术

2.1.2、优势:可以实现在原始类和接口未知的情况下,确定代理类的行为。

2.1.3、动态代理如何影响字节码生成的?

代理类通过调用代理类生成的方法,在程序运行时,可以产生一个描述代理类的字节码byte[]数组。从而控制了字节码的生成过程。

2.1.4、字节码生成过程实质:根据class文件格式,去拼装字节码。

 

 

2.2、Retrotranslator操作字节码

2.2.1、功能:将JDK1.5编译出来的.class文件转为可以在JDK1.3或者1.4上面部署的版本。

2.2.2、功能实质:利用ASM框架直接对字节码进行处理。

2.2.3、能够对java进行逆向移植的工具应该有什么功能?才能保证逆向后的代码能够正常运行?需要考虑4个方面的内容,也就是JDK版本升级过程中,提供的新功能有哪些方面?

A、在编译器层次方面做的改进。

B、对Java API的代码增强。

C、需要对字节码中进行的支持。

D、虚拟机内部的改进。

2.2.4、Retrotranslator仅仅能模拟以上前两种功能。后面两种功能对于一般的逆向工具都是不能模拟的。