4

I'd like to change the imports of a class so that they point to a different package. Byte Buddy docs don't give much info on how one can achieve this. This is what I have so far:

 
public class ProxyPlugin implements net.bytebuddy.build.Plugin {
    public DynamicType.Builder apply(DynamicType.Builder builder, TypeDescription typeDescription) {
        return builder.name(typeDescription.getPackage().getName() + ".proxy."  + typeDescription.getSimpleName());

    }

    public boolean matches(TypeDescription typeDefinitions) {
        return true;
    }
}

My goal is to change some package prefix names so that they have ".proxy" appended to them. Note that I only need to change method signatures since the targets are interfaces.

Claude
  • 489
  • 4
  • 15

1 Answers1

4

I found a solution. Turns out Byte Buddy has a convenience class called ClassRemapper to achieve exactly what I want:

public class ProxyPlugin implements net.bytebuddy.build.Plugin {
    public DynamicType.Builder apply(DynamicType.Builder builder, TypeDescription typeDescription) {
        DynamicType.Builder proxy = builder.name(typeDescription.getPackage().getName() + ".proxy." + typeDescription.getSimpleName());

        proxy = proxy.visit(new AsmVisitorWrapper() {
            public int mergeWriter(int flags) {
                return 0;
            }

            public int mergeReader(int flags) {
                return 0;
            }

            public ClassVisitor wrap(TypeDescription instrumentedType, ClassVisitor classVisitor, int writerFlags, int readerFlags) {
                return new ClassRemapper(classVisitor, new Remapper() {
                    @Override
                    public String map(String typeName) {
                         if (typeName.startsWith("org/example/api") && !typeName.contains("/proxy/")) {
                            return typeName.substring(0, typeName.lastIndexOf("/") + 1) + "proxy" + typeName.substring(typeName.lastIndexOf("/"));
                        } else {
                            return typeName;
                        }
                    }
                });
            }
        });

        return proxy;
    }

    public boolean matches(TypeDescription typeDescription) {
        return true;
    }
}
Claude
  • 489
  • 4
  • 15
  • 3
    This is the correct way of doing so but note that this is using the underlying ASM API. Finally, there are no such things as imports in byte code, you are simply replacing one type with another. It is your responsibility to assure the correctness of the program. – Rafael Winterhalter Sep 29 '16 at 04:08