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(`
The class of redefine
cannot modify, add or delete the field and method of the class, including method parameters, method names and return values.
If mc
fails, you can compile the class file in the local development environment, upload it to the target system, and use redefine
to hot load the class.
At present, redefine
conflicts with watch / trace / jad / tt
commands. Reimplementing redefine
function in the future will solve this problem.
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.
Name | Specification |
---|---|
[c:] | hashcode of the class loader |
[classLoaderClass:] | The class name of the ClassLoader that executes the expression. |
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
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
jad
command to decompile bytecode, and then you can use other editors, such as vim to modify the source code.mc
command to compile the modified coderedefine
commandThe 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.
Convert the .class
file to base64 first, then save it as result.txt
Base64 < Test.class > result.txt
Login the server, create and edit result.txt
, copy the local content, paste and save
Restore result.txt
on the server to .class
Base64 -d < result.txt > Test.class
Use the md5 command to verify that the .class
files are consistent.
System.out.println
added below, only the run()
function will take effect.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());
}
}
}