JVM 字节码,做为虚拟机执行的指令,对于平时做 Java 应用开发来说,一直像蒙着一层神秘面纱,朦朦胧胧。
但其实理解了字节码指令,对于 Java 虚拟机的工作原理,对于基于「栈」的指令执行,对于一些 JVM 的新特性、语法糖都能更好的理解本质。
一般英文文章中介绍一些深入底层原理的时候,都喜欢用这个词:「under the hood」,本意是指汽车等引擎盖下,后来引申为一些底层原理。
而 掀开JVM 的盖,字节码指令也可以说是很重要的一部分了。理解了它,对于一些 ORM 框架等做的编译时的(Enhance)字节码增强,你就能知道他到底干了点啥。
理解了字节码指令之后,可能就会抱怨其使用的繁琐。
而 ASM、Javassist 等工具就是免去你重新搬砖盖房子的,直接以更方便的API提供给用户,免除了手工解析的苦恼。
我在前面的文章里写过几篇关于Java 虚拟机以及字节码指令在 虚拟机内的执行方式。还有一个基于 Javassist 实现类的热替换的实践,感兴趣的朋友可以往前翻翻。
那理解和掌握了 JVM 字节码,除了偶尔编辑和分析一下 class 文件,少数情况下通过ASM等增加或修改些指令外,其实还能做不少有意思的事儿。像类的加载时增强,Agent attach、Instrument实现类的 transform,运行时的retransform等...
最近华章IT 出版的这本『深入理解 JVM字节码』,就在上述两个方面有比较详细的介绍。
第一部分是关于 class 文件的结构、字节码的工作原理、 Javac的编译原理,以及 ASM、Javassist工具的使用做了细致的介绍。此外还包含对于 Java Instrumentation 的原理,Lombok 这种 JSR 269的插件化注解的处理原理等也有介绍。
第二部分介绍了一些比较有意思的实战思路和尝试。像字节码在 Dubbo 通过Javassist实现动态代理的应用 、在 JaCoCo中对于代码覆盖率的实现。如果这些你觉得老生常谈,那软件的破解和防破解可能会让你耳目一新。
咱们都知道 Java 的 class 虽然经过了编译,但通过反编译工具可以轻松的查看源码,甚至不差分毫。
所以书里对于破解提到了直接修改class 文件和通过 Java agent 的无痛破解两种方式。所以对于Java 应用,通过反编译能很快的了解到软件的实现思路,甚至对于商业软件会面临盗版、破解的风险。
不知攻怎么知道防,理解了破解的方式,对于书中介绍的混淆和通过自定义类加载器来加载加密的 class文件防,都是不错的思路。
另外,现在分布式应用、微服务系统越来越流行,给对应的分析和监控带来了不小的挑战,书中全链路分布式跟踪、通过ASM 操作字节码,实现 APM 工具,进行应用的性能分析、诊断等,都有借鉴意义。