下面列出了怎么用org.objectweb.asm.commons.Remapper的API类实例代码及写法,或者点击链接到github查看源代码。
public static byte[] remapClass(byte[] resource, String nameFrom, String nameTo) {
ClassReader reader = new ClassReader(resource);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = new RemappingClassAdapter(writer, new Remapper() {
@Override
public String map(String from) {
if (from.equals(nameFrom)) {
return nameTo;
}
return from;
}
});
reader.accept(visitor, ClassReader.EXPAND_FRAMES);
return writer.toByteArray();
}
public ObfMapping map(Remapper mapper) {
if (mapper == null) {
return this;
}
if (isMethod()) {
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
} else if (isField()) {
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
}
s_owner = mapper.mapType(s_owner);
if (isMethod()) {
s_desc = mapper.mapMethodDesc(s_desc);
} else if (s_desc.length() > 0) {
s_desc = mapper.mapDesc(s_desc);
}
return this;
}
public ObfMapping map(Remapper mapper) {
if (mapper == null) {
return this;
}
if (isMethod()) {
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
} else if (isField()) {
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
}
s_owner = mapper.mapType(s_owner);
if (isMethod()) {
s_desc = mapper.mapMethodDesc(s_desc);
} else if (s_desc.length() > 0) {
s_desc = mapper.mapDesc(s_desc);
}
return this;
}
@Override
public void process(FabricLauncher launcher, Consumer<ClassNode> classEmitter) {
if (classExists(launcher, TO)
&& !classExists(launcher, "cpw.mods.fml.relauncher.FMLRelauncher")) {
if (!(launcher instanceof Knot)) {
throw new RuntimeException("1.2.5 FML patch only supported on Knot!");
}
debug("Detected 1.2.5 FML - Knotifying ModClassLoader...");
try {
ClassNode patchedClassLoader = loadClass(launcher, FROM);
ClassNode remappedClassLoader = new ClassNode();
patchedClassLoader.accept(new ClassRemapper(remappedClassLoader, new Remapper() {
@Override
public String map(String internalName) {
return FROM_INTERNAL.equals(internalName) ? TO_INTERNAL : internalName;
}
}));
classEmitter.accept(remappedClassLoader);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
static byte[] createFaviconServletExtension(String name) throws IOException {
ClassReader reader = new ClassReader(FaviconServletExtension.class.getClassLoader().getResourceAsStream(FaviconServletExtension.class.getName().replace('.', '/') + ".class"));
String slashName = name.replace('.', '/');
ClassWriter writer = new ClassWriter(0);
Remapper remapper = new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("org/wildfly/swarm/undertow/internal/FaviconServletExtension")) {
return slashName;
}
return super.map(typeName);
}
};
ClassRemapper adapter = new ClassRemapper(writer, remapper);
reader.accept(adapter, ClassReader.EXPAND_FRAMES);
writer.visitEnd();
return writer.toByteArray();
}
static byte[] createFaviconErrorHandler(String name) throws IOException {
ClassReader reader = new ClassReader(FaviconErrorHandler.class.getClassLoader().getResourceAsStream(FaviconErrorHandler.class.getName().replace('.', '/') + ".class"));
String slashName = name.replace('.', '/');
ClassWriter writer = new ClassWriter(0);
Remapper remapper = new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("org/wildfly/swarm/undertow/internal/FaviconErrorHandler")) {
return slashName;
}
return super.map(typeName);
}
};
ClassRemapper adapter = new ClassRemapper(writer, remapper);
reader.accept(adapter, ClassReader.EXPAND_FRAMES);
writer.visitEnd();
return writer.toByteArray();
}
public static byte[] create(String name, String path) throws IOException {
ClassReader reader = new ClassReader(basicClassBytes());
String slashName = name.replace('.', '/');
ClassWriter writer = new ClassWriter(0);
Remapper remapper = new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("org/wildfly/swarm/jaxrs/runtime/DefaultApplication")) {
return slashName;
}
return super.map(typeName);
}
};
ClassRemapper adapter = new ClassRemapper(writer, remapper);
reader.accept(adapter, 0);
AnnotationVisitor ann = writer.visitAnnotation("Ljavax/ws/rs/ApplicationPath;", true);
ann.visit("value", path);
ann.visitEnd();
writer.visitEnd();
return writer.toByteArray();
}
public ObfMapping map(Remapper mapper) {
if (isMethod()) {
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
} else if (isField()) {
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
}
s_owner = mapper.mapType(s_owner);
if (isMethod()) {
s_desc = mapper.mapMethodDesc(s_desc);
} else if (s_desc.length() > 0) {
s_desc = mapper.mapDesc(s_desc);
}
return this;
}
public ObfMapping map(Remapper mapper) {
if (isMethod()) {
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
} else if (isField()) {
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
}
s_owner = mapper.mapType(s_owner);
if (isMethod()) {
s_desc = mapper.mapMethodDesc(s_desc);
} else if (s_desc.length() > 0) {
s_desc = mapper.mapDesc(s_desc);
}
return this;
}
public ObfMapping map(Remapper mapper) {
if (isMethod()) {
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
} else if (isField()) {
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
}
s_owner = mapper.mapType(s_owner);
if (isMethod()) {
s_desc = mapper.mapMethodDesc(s_desc);
} else if (s_desc.length() > 0) {
s_desc = mapper.mapDesc(s_desc);
}
return this;
}
static byte[] create(String name, String path) throws IOException {
ClassReader reader = new ClassReader(DefaultApplication.class.getClassLoader().getResourceAsStream(DefaultApplication.class.getName().replace('.', '/') + ".class"));
String slashName = name.replace('.', '/');
ClassWriter writer = new ClassWriter(0);
Remapper remapper = new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("org/wildfly/swarm/jaxrs/internal/DefaultApplication")) {
return slashName;
}
return super.map(typeName);
}
};
RemappingClassAdapter adapter = new RemappingClassAdapter(writer, remapper);
reader.accept(adapter, 0);
AnnotationVisitor ann = writer.visitAnnotation("Ljavax/ws/rs/ApplicationPath;", true);
ann.visit("value", path);
ann.visitEnd();
writer.visitEnd();
return writer.toByteArray();
}
static byte[] create() throws IOException {
ClassReader reader = new ClassReader(FaviconExceptionMapper.class.getClassLoader().getResourceAsStream(FaviconExceptionMapper.class.getName().replace('.', '/') + ".class"));
ClassWriter writer = new ClassWriter(0);
Remapper remapper = new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("org/wildfly/swarm/jaxrs/internal/FaviconExceptionMapper")) {
return "org/wildfly/swarm/generated/FaviconExceptionMapper";
}
return super.map(typeName);
}
};
RemappingClassAdapter adapter = new RemappingClassAdapter(writer, remapper);
reader.accept(adapter, 0);
writer.visitAnnotation("Ljavax/ws/rs/ext/Provider;", true).visitEnd();
writer.visitEnd();
return writer.toByteArray();
}
public CloseResourceMethodSpecializer(
ClassVisitor cv, String targetResourceInternalName, boolean isResourceAnInterface) {
super(
cv,
new Remapper() {
@Override
public String map(String typeName) {
if (typeName.equals("java/lang/AutoCloseable")) {
return targetResourceInternalName;
} else {
return typeName;
}
}
});
this.targetResourceInternalName = targetResourceInternalName;
this.isResourceAnInterface = isResourceAnInterface;
}
UnprefixingClassWriter(int flags) {
super(Opcodes.ASM8);
this.writer = new ClassWriter(flags);
this.cv = this.writer;
if (!prefix.isEmpty()) {
this.cv =
new ClassRemapper(
this.writer,
new Remapper() {
@Override
public String map(String typeName) {
return unprefix(typeName);
}
});
}
}
public ObfMapping map(Remapper mapper) {
if (mapper == null)
return this;
if (isMethod())
s_name = mapper.mapMethodName(s_owner, s_name, s_desc);
else if (isField())
s_name = mapper.mapFieldName(s_owner, s_name, s_desc);
s_owner = mapper.mapType(s_owner);
if (isMethod())
s_desc = mapper.mapMethodDesc(s_desc);
else if (s_desc.length() > 0)
s_desc = mapper.mapDesc(s_desc);
return this;
}
private TinyRemapper(Collection<IMappingProvider> mappingProviders, boolean ignoreFieldDesc,
int threadCount,
boolean keepInputData,
Set<String> forcePropagation, boolean propagatePrivate,
boolean removeFrames,
boolean ignoreConflicts,
boolean resolveMissing,
boolean checkPackageAccess,
boolean fixPackageAccess,
boolean rebuildSourceFilenames,
boolean skipLocalMapping,
boolean renameInvalidLocals,
ClassVisitor extraAnalyzeVisitor, Remapper extraRemapper) {
this.mappingProviders = mappingProviders;
this.ignoreFieldDesc = ignoreFieldDesc;
this.threadCount = threadCount > 0 ? threadCount : Math.max(Runtime.getRuntime().availableProcessors(), 2);
this.keepInputData = keepInputData;
this.threadPool = Executors.newFixedThreadPool(this.threadCount);
this.forcePropagation = forcePropagation;
this.propagatePrivate = propagatePrivate;
this.removeFrames = removeFrames;
this.ignoreConflicts = ignoreConflicts;
this.resolveMissing = resolveMissing;
this.checkPackageAccess = checkPackageAccess;
this.fixPackageAccess = fixPackageAccess;
this.rebuildSourceFilenames = rebuildSourceFilenames;
this.skipLocalMapping = skipLocalMapping;
this.renameInvalidLocals = renameInvalidLocals;
this.extraAnalyzeVisitor = extraAnalyzeVisitor;
this.extraRemapper = extraRemapper;
}
public AsmMethodRemapper(MethodVisitor methodVisitor, Remapper remapper, String owner, MethodNode methodNode, boolean checkPackageAccess, boolean skipLocalMapping, boolean renameInvalidLocals) {
super(methodNode != null ? methodNode : methodVisitor, remapper);
this.owner = owner;
this.methodNode = methodNode;
this.output = methodVisitor;
this.checkPackageAccess = checkPackageAccess;
this.skipLocalMapping = skipLocalMapping;
this.renameInvalidLocals = renameInvalidLocals;
}
private static byte[] rewriteBytecode(Map<String, String> internalPackageNameMap, byte[] bytecode) {
ClassReader classReader = new ClassReader(bytecode);
ClassWriter classWriter = new ClassWriter(0);
classReader.accept(new ClassRemapper(classWriter, new Remapper() {
@Override
public String map(String internalName) {
return interpolateInternalName(internalPackageNameMap, internalName);
}
@Override
public String mapPackageName(String internalPackageName) {
return matchInternalPackagePrefix(internalPackageNameMap, internalPackageName)
.orElse(internalPackageName);
}
@Override
public Object mapValue(Object value) {
if (!(value instanceof String)) {
return super.mapValue(value);
}
// try to patch if it's like a class name (dot form and slash form)
var string = (String)value;
if (lookLikeAClassName(string)) {
var index = string.lastIndexOf('.');
return matchInternalPackagePrefix(internalPackageNameMap, string.substring(0, index).replace('.', '/'))
.map(packageName -> packageName.replace('/', '.') + '.' + string.substring(index + 1))
.map(result -> { System.out.println("literal constant string " + string +" as " + result); return result;})
.orElse(string);
}
return string;
}
}), 0);
return classWriter.toByteArray();
}
BackportingTypeRemapper(ClassVisitor cv) {
super(ASM5, cv, new Remapper() {
@Override public String map(String type) {
String remap = TYPES.get(type);
if (remap != null) {
System.out.println(" Mapping type " + type + " to " + remap);
return remap;
}
return type;
}
});
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
for (Entry<String, String> mapping : remappings.entrySet()) {
if (name.equals(mapping.getValue())) {
String path = mapping.getKey().replace('.', '/').concat(".class");
try {
try (InputStream resource = getResourceAsStream(path)) {
ClassReader reader = new ClassReader(resource);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = new ClassRemapper(writer, new Remapper() {
@Override
public String map(String from) {
String to = remappings.get(from.replace('/', '.'));
if (to == null) {
return from;
} else {
return to.replace('.', '/');
}
}
});
reader.accept(visitor, ClassReader.EXPAND_FRAMES);
byte[] classBytes = writer.toByteArray();
return defineClass(name, classBytes, 0, classBytes.length);
}
} catch (IOException e) {
throw new ClassNotFoundException("IOException while loading", e);
}
}
}
return super.findClass(name);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String key = findKeyFromValue(name).orElseGet(() -> null);
if(key == null) {
return super.findClass(name);
}
String path = key.replace('.', '/').concat(".class");
try (InputStream resource = getResourceAsStream(path)) {
ClassReader reader = new ClassReader(resource);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
Remapper remapper = new Remapper() {
@Override
public String map(String from) {
String to = remappings.get(from.replace('/', '.'));
if (to == null) {
return from;
}
return to.replace('.', '/');
}
};
reader.accept(new ClassRemapper(writer, remapper), ClassReader.EXPAND_FRAMES);
byte[] classBytes = writer.toByteArray();
return defineClass(name, classBytes, 0, classBytes.length);
} catch (IOException e) {
throw new ClassNotFoundException("IOException while loading", e);
}
}
/**
* Copy a method and rename it; everything else will be exactly the same
* @return The renamed method copy
*/
public static MethodNode copyAndRenameMethod(ClassNode classNode, MethodNode method, String newMethodName)
{
MethodVisitor methodCopyVisitor = classNode.visitMethod(method.access, newMethodName, method.desc, method.signature, method.exceptions.toArray(new String[method.exceptions.size()]));
method.accept(new RemappingMethodAdapter(method.access, method.desc, methodCopyVisitor, new Remapper(){}));
return methodCopyVisitor instanceof MethodNode ? (MethodNode) methodCopyVisitor : null;
}
public final ImmutableSetMultimap<Predicate<ClassName>, ClassName> findReferencedTypes(
ImmutableSet<Predicate<ClassName>> typeFilters) {
ImmutableSetMultimap.Builder<ClassName, Predicate<ClassName>> collectedTypes =
ImmutableSetMultimap.builder();
// Takes an advantage of hit-all-referenced-types ASM Remapper to perform type collection.
try (S inputStream = get()) {
ClassReader cr = new ClassReader(inputStream);
cr.accept(
new ClassRemapper(
new ClassWriter(ClassWriter.COMPUTE_FRAMES),
new Remapper() {
@Override
public String map(String internalName) {
ClassName className = ClassName.create(internalName);
collectedTypes.putAll(
className,
typeFilters.stream()
.filter(className::acceptTypeFilter)
.collect(Collectors.toList()));
return super.map(internalName);
}
}),
/* parsingOptions= */ 0);
} catch (IOException e) {
throw new IOError(e);
}
return collectedTypes.build().inverse();
}
public TestClassAdapter(ClassVisitor cv,
final Map<String, String> typeMappings) {
super(cv, new Remapper() {
@Override
public String map(String type) {
return typeMappings.containsKey(type) ? typeMappings.get(type)
: type;
}
});
}
public RemappingClassTransformer(Remapper pr) {
super(new EmptyClassVisitor(), pr);
}
public MethodOptimizer(ClassOptimizer classOptimizer, MethodVisitor mv, Remapper remapper) {
super(Opcodes.ASM5, mv, remapper);
this.classOptimizer = classOptimizer;
}
public ClassOptimizer(final ClassVisitor cv, final Remapper remapper) {
super(Opcodes.ASM5, cv, remapper);
}
public Builder extraRemapper(Remapper remapper) {
extraRemapper = remapper;
return this;
}
public static AnnotationRemapper createAsmAnnotationRemapper(String desc, AnnotationVisitor annotationVisitor, Remapper remapper) {
return annotationVisitor == null ? null : new AsmAnnotationRemapper(annotationVisitor, remapper, desc);
}
public AsmFieldRemapper(FieldVisitor fieldVisitor, Remapper remapper) {
super(fieldVisitor, remapper);
}