思路:为每一台应用启动一个AttachApplication服务,当指定包路径下的字节码文件有变更时,通过Instrumentation重新加载字节码文件到虚拟机,实现不停机秒级更新应用。(只能修改方法体,不支持新增方法和变量)
核心代码:
try {
Class<?> clazz = Class.forName(className);
ClassDefinition classDefinition = new ClassDefinition(clazz, classBytes);
instrumentation.redefineClasses(classDefinition);
System.out.println("Class " + className + " has been redefined.");
} catch (ClassNotFoundException e) {
System.err.println("Class " + className + " not found: " + e.getMessage());
} catch (Exception e) {
System.err.println("Failed to redefine class " + className + ": " + e.getMessage());
}
加载agentjar包发送到虚拟机:
try {
List<VirtualMachineDescriptor> vmDescriptors = VirtualMachine.list();
for (VirtualMachineDescriptor vmd : vmDescriptors) {
if (vmd.displayName().equals("Application")) { // 修改成指定的应用名称
VirtualMachine virtualMachine = VirtualMachine.attach(vmd.id());
// 加载 agent
String agentPath = Paths.get("build", "libs", "java-agent.jar").toAbsolutePath().toString();
virtualMachine.loadAgent(agentPath);
virtualMachine.detach();
}
}
} catch (Exception e) {
throw new RuntimeException();
}