“This is the seventh day of my participation in the First Challenge 2022.

Online code modification

Arthas can be used to temporarily modify the online code when a production environment encounters a very urgent problem, or a bug is suddenly discovered and it is not convenient to re-release, or the release does not work. The steps to modify Arthas are as follows:

1. Read from a. Class file 2. Compile to a. Java file 3. Modify the. Java file. 4. Compile the modified. Java file into a new. Load the new. Class file into the JVM via the classloaderCopy the code

Step 1: Read the.class file

sc -d *DeadLockTest*
Copy the code

Use the sc command to view information about classes loaded by the JVM. About sc command, check the official document: arthas.aliyun.com/doc/sc.html

  • -d: displays detailed information about the printed class

The last parameter, classLoaderHash, represents the hash value to be loaded by the class in the JVM, which is what we want to get.

Step 2: UsejadCommand to decompile a. Class file into a. Java file

jad -c 7c53a9eb --source-only com.lxl.jvm.DeadLockTest > /Users/lxl/Downloads/DeadLockTest.java
Copy the code
  • The jad command decompiles source code that specifies a loaded class
  • -c: indicates the hashcode of the ClassLoader to which the class belongs
  • –source-only: by default, the decompilation result will contain source-onlyClassLoaderInformation, via--source-onlyOption to print only the source code.
  • Com.lxl.jvms.DeadLockTest: Full path to the target class
  • / Users/LXL/Downloads/DeadLockTest. Java: the preservation of the path decompiled files
/* * Decompiled with CFR. * * Could not load the following classes: * com.lxl.jvm.User */ package com.lxl.jvm; import com.lxl.jvm.User; import java.util.ArrayList; import java.util.List; public class DeadLockTest { private static Object lock1 = new Object(); private static Object lock2 = new Object(); private static List<String> names = new ArrayList<String>(); private List<String> citys = new ArrayList<String>(); public static List<String> getCitys() { DeadLockTest deadLockTest = new DeadLockTest(); /*25*/ deadlocktest.citys.add (" Beijing "); /*27*/ return deadLockTest.citys; }... public static void main(String[] args) { ...... }}Copy the code

This is a snippet of code.

Step 3: Modify the Java file

Public static List<String> getCitys() {system.out.println ("----- "); DeadLockTest deadLockTest = new DeadLockTest(); /*25*/ deadlocktest.citys.add (" Beijing "); /*27*/ return deadLockTest.citys; }Copy the code

Step 4: UsemcCommand to compile a. Java file into a. Class file

mc -c 512ddf17 -d /Users/luoxiaoli/Downloads /Users/luoxiaoli/Downloads/DeadLockTest.java
Copy the code
  • MC: compile. Java file. The class files, detailed usage arthas.aliyun.com/doc/mc.html refer to official document
  • -c: Specifies the hash value of the classLoader
  • -d: Specifies the output directory
  • The last parameter is the Java file path

This is the decompiled class bytecode file

Step 5: Reload the. Class file into the JVM using the re-define command

redefine -c 512ddf17 /Users/lxl/Downloads/com/lxl/jvm/DeadLockTest.class
Copy the code
  • -c: Specifies the hashcode of the ClassLoader

Re-define Success re-loaded the. Class file into the JVM successfully.

Matters needing attention

Re-define and then jad reset the bytecode to what it was before the change. The official statement on the re-define order

Step 6: Test the effect

Here the effect is detected, the interface is called, and the log is executed.