fix: method body write failed with jakarta renamed

ByteBuddy Advice cache the class method list at first, the method signature will be changed when use jakarta rename, if follow advice need enhance the javax method, it will not find method signature. because ByteBuddy cached javax method, but follow advice need find the jakarta method, boom~
This commit is contained in:
ReaJason
2026-02-08 20:44:00 +08:00
parent 58041fa0b5
commit 4c8343c86f
6 changed files with 54 additions and 57 deletions
@@ -1,5 +1,6 @@
package com.reajason.javaweb.asm;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
@@ -14,12 +15,7 @@ import org.objectweb.asm.commons.SimpleRemapper;
public class ClassRenameUtils {
public static byte[] renameClass(byte[] classBytes, String newName) {
ClassReader reader = null;
try {
reader = new ClassReader(classBytes);
} catch (Exception e) {
throw new RuntimeException("invalid class bytes");
}
ClassReader reader = getClassReader(classBytes);
String oldClassName = reader.getClassName();
String newClassName = newName.replace('.', '/');
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
@@ -29,12 +25,7 @@ public class ClassRenameUtils {
}
public static byte[] relocateClass(byte[] classBytes, String relocateClassPackage, String relocatePrefix) {
ClassReader reader = null;
try {
reader = new ClassReader(classBytes);
} catch (Exception e) {
throw new RuntimeException("invalid class bytes");
}
ClassReader reader = getClassReader(classBytes);
String oldClassName = relocateClassPackage.replace('.', '/');
String newClassName = relocatePrefix.replace('.', '/');
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
@@ -51,4 +42,32 @@ public class ClassRenameUtils {
reader.accept(adapter, 0);
return writer.toByteArray();
}
public static byte[] relocateJakarta(byte[] classBytes) {
ClassReader reader = getClassReader(classBytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassRemapper adapter = new ClassRemapper(writer, new Remapper(Opcodes.ASM9) {
@Override
public String map(String typeName) {
if (typeName.startsWith("javax/servlet/")
|| typeName.startsWith("javax/websocket/")) {
return typeName.replaceFirst("javax", "jakarta");
} else {
return typeName;
}
}
});
reader.accept(adapter, 0);
return writer.toByteArray();
}
private static @NotNull ClassReader getClassReader(byte[] classBytes) {
ClassReader reader = null;
try {
reader = new ClassReader(classBytes);
} catch (Exception e) {
throw new RuntimeException("invalid class bytes");
}
return reader;
}
}