如何在独立于Eclipse运行的Tomcat Web应用程序中执行热代码替换?

huangapple go评论75阅读模式
英文:

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中执行热代码替换是可能的。这涉及几个步骤。

  1. 编译要替换的新类版本。假设你想要替换org.pkg.MyClass,而这个类的新版本位于/new/path/org/pkg/MyClass.class

  2. 创建一个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));
        }
    }
    
  3. 编译上述代理并将其打包成带有以下MANIFEST.MF.jar文件:

    Agent-Class: HotCodeReplace
    Can-Redefine-Classes: true
    

    创建HotCodeReplace.jar的命令:

    jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
    
  4. 将代理的.jar加载到目标JVM中。可以使用Attach API进行加载,或者简单地使用jattach工具进行加载:

    jattach <pid> load instrument false /path/to/HotCodeReplace.jar
    

了解更多关于Java代理的信息 »

英文:

Yes, it's possible to perform Hot Code Replace in a running JVM. This involves several steps.

  1. 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

  2. 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(&quot;org.pkg.MyClass&quot;);
    
             Path newFile = Paths.get(&quot;/new/path/org/pkg/MyClass.class&quot;);
             byte[] newData = Files.readAllBytes(newFile);
    
             instr.redefineClasses(new ClassDefinition(oldClass, newData));
         }
     }
    
  3. Compile the above agent and pack it into .jar with the following MANIFEST.MF

     Agent-Class: HotCodeReplace
     Can-Redefine-Classes: true
    

The command to create HotCodeReplace.jar:

    jar cvfm HotCodeReplace.jar MANIFEST.MF HotCodeReplace.class
  1. Load the agent .jar into the target JVM. This can be done with Attach API or simply with jattach utility:

     jattach &lt;pid&gt; load instrument false /path/to/HotCodeReplace.jar
    

More about Java agents »

huangapple
  • 本文由 发表于 2020年4月4日 13:37:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/61024212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定