post-compilation removal of annotations from byte code

前端 未结 4 2163
太阳男子
太阳男子 2021-02-08 15:50

we are using a library that contains beans that are annotated with JAXB annotations. nothing in the way we use these classes depends on JAXB. in other words, we don\'t need JAXB

4条回答
  •  名媛妹妹
    2021-02-08 16:22

    I have used ByteBuddy library to remove annotations. Unfortunately I was unable to remove annotation with high level api, so I used ASM api. Here is example, how you can remove @Deprecated annotation from field of a class:

    import net.bytebuddy.ByteBuddy;
    import net.bytebuddy.asm.AsmVisitorWrapper;
    import net.bytebuddy.description.field.FieldDescription;
    import net.bytebuddy.description.type.TypeDescription;
    import net.bytebuddy.jar.asm.AnnotationVisitor;
    import net.bytebuddy.jar.asm.FieldVisitor;
    import net.bytebuddy.jar.asm.Opcodes;
    import net.bytebuddy.jar.asm.Type;
    import net.bytebuddy.matcher.ElementMatchers;
    
    import java.lang.annotation.Annotation;
    import java.util.Arrays;
    
    public class Test {
    
        public static class Foo {
            @Deprecated
            public Integer bar;
        }
    
        public static void main(String[] args) throws Exception {
            System.out.println("Annotations before processing " + getAnnotationsString(Foo.class));
            Class modifiedClass = new ByteBuddy()
                    .redefine(Foo.class)
                    .visit(new AsmVisitorWrapper.ForDeclaredFields()
                            .field(ElementMatchers.isAnnotatedWith(Deprecated.class),
                                    new AsmVisitorWrapper.ForDeclaredFields.FieldVisitorWrapper() {
                                        @Override
                                        public FieldVisitor wrap(TypeDescription instrumentedType,
                                                                 FieldDescription.InDefinedShape fieldDescription,
                                                                 FieldVisitor fieldVisitor) {
                                            return new FieldVisitor(Opcodes.ASM5, fieldVisitor) {
                                                @Override
                                                public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                                                    if (Type.getDescriptor(Deprecated.class).equals(desc)) {
                                                        return null;
                                                    }
                                                    return super.visitAnnotation(desc, visible);
                                                }
                                            };
                                        }
                                    }))
                    // can't use the same name, because Test$Foo is already loaded
                    .name("Test$Foo1")
                    .make()
                    .load(Test.class.getClassLoader())
                    .getLoaded();
            System.out.println("Annotations after processing " + getAnnotationsString(modifiedClass));
        }
    
        private static String getAnnotationsString(Class clazz) throws NoSuchFieldException {
            Annotation[] annotations = clazz.getDeclaredField("bar").getDeclaredAnnotations();
            return Arrays.toString(annotations);
        }
    }
    

提交回复
热议问题