如何在 Eclipse 外部的 Tomcat Web 应用程序 运行 中执行热代码替换?
How can I perform Hot Code Replace in Tomcat web application running outside eclipse?
当 Tomcat 是来自 eclipse 的 运行 时,我正在使用热代码替换功能,它工作得很好。
但是,当 Tomcat 是 运行 在 eclipse 之外时,我如何手动执行此操作?
经过一番搜索,我发现我需要使用像HotswapAgent这样的代理。但是,他们使用的是经过修改的 JDK 称为 DCEVM 的代理。我不想使用修改后的 JDK。我想用 OpenJDK 达到同样的效果。
我知道修改仅限于方法体,但这对我来说不是问题。我怎样才能在不使用 IDE 的情况下为外部 运行 Tomcat 的热代码替换做完全相同的事情?
编辑:Eclipse 示例只是为了阐明我想要实现的目标。我根本不想使用 Eclipse。我只想在 Tomcat.
中的应用程序 运行 中执行热代码替换
是的,可以在 运行 JVM 中执行热代码替换。这涉及几个步骤。
- 准备(编译)要替换的 classes 的新版本。比方说,你想替换
org.pkg.MyClass
,而这个 class 的新版本位于 /new/path/org/pkg/MyClass.class
创建一个使用 Instrumentation API to redefine 给定 class 的 Java 代理。最简单的代理可能如下所示:
import java.lang.instrument.*;
import java.nio.file.*;
public class HotCodeReplace {
public static void agentmain(String args, Instrumentation instr) throws Exception {
Class oldClass = Class.forName("org.pkg.MyClass");
Path newFile = Paths.get("/new/path/org/pkg/MyClass.class");
byte[] newData = Files.readAllBytes(newFile);
instr.redefineClasses(new ClassDefinition(oldClass, newData));
}
}
编译上面的agent,打包成.jar
,下面MANIFEST.MF
Agent-Class: HotCodeReplace
Can-Redefine-Classes: true
创建命令HotCodeReplace.jar
:
jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
将代理 .jar 加载到目标 JVM 中。这可以通过 Attach API or simply with jattach
实用程序来完成:
jattach <pid> load instrument false /path/to/HotCodeReplace.jar
当 Tomcat 是来自 eclipse 的 运行 时,我正在使用热代码替换功能,它工作得很好。
但是,当 Tomcat 是 运行 在 eclipse 之外时,我如何手动执行此操作?
经过一番搜索,我发现我需要使用像HotswapAgent这样的代理。但是,他们使用的是经过修改的 JDK 称为 DCEVM 的代理。我不想使用修改后的 JDK。我想用 OpenJDK 达到同样的效果。
我知道修改仅限于方法体,但这对我来说不是问题。我怎样才能在不使用 IDE 的情况下为外部 运行 Tomcat 的热代码替换做完全相同的事情?
编辑:Eclipse 示例只是为了阐明我想要实现的目标。我根本不想使用 Eclipse。我只想在 Tomcat.
中的应用程序 运行 中执行热代码替换是的,可以在 运行 JVM 中执行热代码替换。这涉及几个步骤。
- 准备(编译)要替换的 classes 的新版本。比方说,你想替换
org.pkg.MyClass
,而这个 class 的新版本位于/new/path/org/pkg/MyClass.class
创建一个使用 Instrumentation API to redefine 给定 class 的 Java 代理。最简单的代理可能如下所示:
import java.lang.instrument.*; import java.nio.file.*; public class HotCodeReplace { public static void agentmain(String args, Instrumentation instr) throws Exception { Class oldClass = Class.forName("org.pkg.MyClass"); Path newFile = Paths.get("/new/path/org/pkg/MyClass.class"); byte[] newData = Files.readAllBytes(newFile); instr.redefineClasses(new ClassDefinition(oldClass, newData)); } }
编译上面的agent,打包成
.jar
,下面MANIFEST.MF
Agent-Class: HotCodeReplace Can-Redefine-Classes: true
创建命令
HotCodeReplace.jar
:jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
将代理 .jar 加载到目标 JVM 中。这可以通过 Attach API or simply with
jattach
实用程序来完成:jattach <pid> load instrument false /path/to/HotCodeReplace.jar