Как изменить импорт с помощью Byte Buddy?

Я хотел бы изменить импорт класса, чтобы он указывал на другой пакет. Документы Byte Buddy не дают много информации о том, как этого можно добиться. Это то, что у меня есть до сих пор:

 
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;
    }
}

Моя цель — изменить некоторые имена префиксов пакетов, чтобы к ним добавлялся «.proxy». Обратите внимание, что мне нужно изменить только сигнатуры методов, поскольку целью являются интерфейсы.


person Claude    schedule 28.09.2016    source источник


Ответы (1)


Я нашел решение. Оказывается, у Byte Buddy есть удобный класс под названием ClassRemapper для достижения именно того, что я хочу:

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;
    }
}
person Claude    schedule 28.09.2016
comment
Это правильный способ сделать это, но обратите внимание, что он использует базовый API ASM. Наконец, в байт-коде нет таких вещей, как импорт, вы просто заменяете один тип другим. Вы несете ответственность за обеспечение правильности программы. - person Rafael Winterhalter; 29.09.2016