英文:
How can I perform Hot Code Replace in Tomcat web application running outside eclipse?
问题
我在Tomcat从eclipse运行时使用热代码替换功能,效果很好。
但是,当Tomcat在eclipse之外运行时,我该如何手动操作呢?
经过一些搜索,我发现我需要使用类似HotswapAgent这样的代理工具。但是,他们是在修改过的JDK(称为DCEVM)上使用此代理工具的。我不想使用修改过的JDK。我希望能够在OpenJDK下实现相同的功能。
我知道修改将仅限于方法主体,但对我来说这不是问题。在不使用集成开发环境的情况下,我如何才能实现与eclipse为外部运行的Tomcat进行热代码替换的完全相同的操作?
编辑:Eclipse的示例只是为了阐明我想要实现的目标。我不想使用eclipse,我只想在运行在Tomcat中的应用程序中执行热代码替换。
英文:
I am using Hot Code Replace feature when Tomcat is running from eclipse and it works great.
But, how can I do this manually when Tomcat is running outside eclipse?
After some searching, I have found that I need to use an agent like HotswapAgent. But, they are using this agent with modified JDK called DCEVM. I don't want to use modified JDK. I want to achieve the same thing with OpenJDK.
I know that modification will be limited to method body only but, that's not a problem for me. How can I achieve the exact same thing eclipse is doing for Hot Code Replace for an externally running Tomcat without using IDE?
Edit : Eclipse example is just to clarify what I want to achieve. I do not want to use eclipse at all. I just want to do Hot Code Replace in an application running in Tomcat.
答案1
得分: 1
是的,在运行的JVM中执行热代码替换是可能的。这涉及几个步骤。
-
编译要替换的新类版本。假设你想要替换
org.pkg.MyClass
,而这个类的新版本位于/new/path/org/pkg/MyClass.class
。 -
创建一个Java Agent,使用Instrumentation API来重新定义给定的类。以下是最简单的代理的示例:
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)); } }
-
编译上述代理并将其打包成带有以下
MANIFEST.MF
的.jar
文件:Agent-Class: HotCodeReplace Can-Redefine-Classes: true
创建
HotCodeReplace.jar
的命令:jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
-
将代理的
.jar
加载到目标JVM中。可以使用Attach API进行加载,或者简单地使用jattach
工具进行加载:jattach <pid> load instrument false /path/to/HotCodeReplace.jar
英文:
Yes, it's possible to perform Hot Code Replace in a running JVM. This involves several steps.
-
Prepare (compile) the new version of classes you want to replace. Let's say, you want to replace
org.pkg.MyClass
, and the new version of this class is located at/new/path/org/pkg/MyClass.class
-
Create a Java Agent that uses Instrumentation API to redefine the given class. Here is how the simplest agent may look like:
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)); } }
-
Compile the above agent and pack it into
.jar
with the followingMANIFEST.MF
Agent-Class: HotCodeReplace Can-Redefine-Classes: true
The command to create HotCodeReplace.jar
:
jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
-
Load the agent .jar into the target JVM. This can be done with Attach API or simply with
jattach
utility:jattach <pid> load instrument false /path/to/HotCodeReplace.jar
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论