这里说的 把Java类写入到.class文件 不是 Java对象序列化 ObjectOutputStream
,Java对象序列化写入的是类中的数据,并不是类本身。
这里说的是如果在运行过程中把类本身字节码写入到文件中,便于反编译查看类的结构信息。
如果类本身就是从文件中加载,直接读取类文件即可,或者根本就不用读取在写入新的文件,因为类文件本身就存在。但是如果一个类是运行中生成的,如果把这种动态生成的类写入到磁盘呢?
1. Java Agent
Agent
1 | package xyz.kail.demo.agent; |
ClassFileTransformer
1 | package xyz.kail.demo.agent.transformer; |
Maven 打包 plugin
1 | <plugin> |
启动时加入 java agent 参数
1 | java -jar \ |
2. 运行时添加 Java Agent
上面 premain
类型的 Java Agent 只能在程序运行前,在启动命令中指定 javaagent 参数 才能生效。
Java SE 6 新特性改变了这种情况,通过 Java Tool API 中的 attach 方式,我们可以很方便地在运行过程中动态地设置加载代理类。
Agent
在 Agent 类中新增 agentmain
方法,参数和 premain
中的是一样的
1 | public class Agent { |
依赖 tools 包
1 | <dependency> |
Maven 打包 plugin
1 | <plugin> |
Attach
1 | import com.sun.tools.attach.VirtualMachine; |
或 通过 jar 运行上面的 AgentTest.main 方法
1 | java -Xbootclasspath/a:${JAVA_HOME}lib/tools.jar -jar target/agent-1.0.0.jar |
3. HSDB
HSDB(Hotspot Debugger) 是 ${JAVA_HOME}/lib/sa-jdi.jar
中提供的一个图形化界面工具,可以查看Java对象的oops、查看类信息、线程栈信息、堆信息、方法字节码 和 JIT编译后的汇编代码 等,可以说非常底层全面。
sa 全称 Serviceability Agent ,原本是Sun公司用来debug Hotspot的工具,后来开放给Hotspot使用者,能够查看Java的内部数据结构等信息,它可以直接观察一个JVM 进程。
步骤
- 启动图形化界面:
sudo java -cp ${JAVA_HOME}/lib/sa-jdi.jar sun.jvm.hotspot.HSDB
- Attach JVM 进程:菜单 -> File -> Attach to HotSpot process
- 查看所有运行中的类:菜单 -> Tools -> Class Browser
- 下载类字节码到文件: 搜索指定的类,点击 “Create .class for all classes” 就会下载指定的类到类路径下