import{_ as i,o as l,c as p,a as n,b as e,w as o,e as s,d,r as c}from"./app.4d248835.js";const r={},u=n("h1",{id:"redefine",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#redefine","aria-hidden":"true"},"#"),s(" redefine")],-1),m={class:"custom-container tip"},h=n("p",{class:"custom-container-title"},"TIP",-1),k=s("Recommend to use the "),v=s("retransform"),f=s(" command."),b={href:"https://arthas.aliyun.com/3.x/doc/arthas-tutorials?language=en&id=command-mc-redefine",target:"_blank",rel:"noopener noreferrer"},g=n("code",null,"mc-redefine",-1),_=s(" online tutorial"),y=n("div",{class:"custom-container tip"},[n("p",{class:"custom-container-title"},"TIP"),n("p",null,[s("Load the external "),n("code",null,"*.class"),s(" files to re-define the loaded classes in JVM.")])],-1),w=s("Reference: "),x={href:"https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/Instrumentation.html#redefineClasses-java.lang.instrument.ClassDefinition...-",target:"_blank",rel:"noopener noreferrer"},T=s("Instrumentation#redefineClasses"),I=n("h2",{id:"frequently-asked-questions",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#frequently-asked-questions","aria-hidden":"true"},"#"),s(" Frequently asked questions")],-1),C={class:"custom-container tip"},j=n("p",{class:"custom-container-title"},"TIP",-1),L=s("Recommend to use the "),q=s("retransform"),S=s(" command."),N=d(`

WARNING

Notes: Re-defined classes cannot be restored. There are chances that redefining may fail due to some reasons, for example: there's new field introduced in the new version of the class, pls. refer to JDK's documentation for the limitations.

TIP

The reset command is not valid for classes that have been processed by redefine. If you want to reset, you need redefine the original bytecode.

TIP

The redefine command will conflict with the jad/watch/trace/monitor/tt commands. After executing redefine, if you execute the above mentioned command, the bytecode of the class will be reset. The reason is that in the JDK redefine and retransform are different mechanisms. When two mechanisms are both used to update the bytecode, only the last modified will take effect.

Options

NameSpecification
[c:]hashcode of the class loader
[classLoaderClass:]The class name of the ClassLoader that executes the expression.

Usage

redefine /tmp/Test.class
redefine -c 327a647b /tmp/Test.class /tmp/Test\\$Inner.class
redefine --classLoaderClass sun.misc.Launcher$AppClassLoader /tmp/Test.class /tmp/Test\\$Inner.class

Use with the jad/mc command

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

mc /tmp/UserController.java -d /tmp

redefine /tmp/com/example/demo/arthas/user/UserController.class

Tips for uploading .class files to the server

The mc command may fail. You can modify the code locally, compile it, and upload it to the server. Some servers do not allow direct uploading files, you can use the base64 command to bypass.

  1. Convert the .class file to base64 first, then save it as result.txt

    Base64 < Test.class > result.txt
    
  2. Login the server, create and edit result.txt, copy the local content, paste and save

  3. Restore result.txt on the server to .class

    Base64 -d < result.txt > Test.class
    
  4. Use the md5 command to verify that the .class files are consistent.

Restrictions of the redefine command

public class MathGame {
    public static void main(String[] args) throws InterruptedException {
        MathGame game = new MathGame();
        while (true) {
            game.run();
            TimeUnit.SECONDS.sleep(1);
            // This doesn't work because the code keeps running in while
            System.out.println("in loop");
        }
    }

    public void run() throws InterruptedException {
        // This works because the run() function ends completely every time
        System.out.println("call run()");
        try {
            int number = random.nextInt();
            List<Integer> primeFactors = primeFactors(number);
            print(number, primeFactors);

        } catch (Exception e) {
            System.out.println(String.format("illegalArgumentCount:%3d, ", illegalArgumentCount) + e.getMessage());
        }
    }
}
`,17);function R(U,E){const a=c("RouterLink"),t=c("ExternalLinkIcon");return l(),p("div",null,[u,n("div",m,[h,n("p",null,[k,e(a,{to:"/en/doc/retransform.html"},{default:o(()=>[v]),_:1}),f])]),n("p",null,[n("a",b,[g,_,e(t)])]),y,n("p",null,[w,n("a",x,[T,e(t)])]),I,n("div",C,[j,n("p",null,[L,e(a,{to:"/en/doc/retransform.html"},{default:o(()=>[q]),_:1}),S])]),N])}const B=i(r,[["render",R],["__file","redefine.html.vue"]]);export{B as default};