vendredi 9 octobre 2020

Unable to add/update Annotation in Java 7

I am trying to dynamically add Annotation in Java 7. But it fails to so. Could use some help.

Following are the 2 ways I am taking. In both the approach, immediately after adding the new Annotation when I check, the class/field doesnt reflect it.

1. Create new Annotation with javaassist

    public void javaassist(String className, List<String> props) throws Exception{
         //pool creation 
         ClassPool pool = ClassPool.getDefault();
         //extracting the class
         CtClass cc = pool.getCtClass(className);
         // create the annotation
         ClassFile ccFile = cc.getClassFile();
         ConstPool constpool = ccFile.getConstPool();
         
         AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
         
         for(String propName: props) {
             javassist.bytecode.annotation.Annotation annot = 
                     new javassist.bytecode.annotation.Annotation("org.hibernate.annotations.ColumnTransformer", constpool);
             annot.addMemberValue("read", new StringMemberValue("aes_decrypt("+propName+", 'mysecret')", ccFile.getConstPool()));
             annot.addMemberValue("write", new StringMemberValue("aes_encrypt(?, 'mysecret')", ccFile.getConstPool()));
             
             attr.addAnnotation(annot);
             
             //looking for the method to apply the annotation on
             CtField propField = cc.getDeclaredField(propName);
             // add the annotation to the method descriptor
             List<AnnotationsAttribute> atts= propField.getFieldInfo().getAttributes();
             System.out.println(atts);
             // propField.getFieldInfo().addAttribute(attr);             
             atts.add(attr);
             System.out.println(atts);
         }
    }

2. Create new Annotation with Class.class.getDeclaredField("annotations")

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private void withNew(Class clazz, List<String> props) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        Field fieldAnnotations = Class.class.getDeclaredField("annotations");
        fieldAnnotations.setAccessible(true);
        Map<Class<? extends Annotation>, Annotation> annotations = (Map<Class<? extends Annotation>, Annotation>) fieldAnnotations.get(clazz);
        for(String prop: props) {
            annotations.put(ColumnTransformer.class, this.buildColTransfAnnotation(prop, key));
        }
    }
    
    private Annotation buildColTransfAnnotation(final String propName, final String key) {
        return new ColumnTransformer() {
            @Override
            public Class<? extends Annotation> annotationType() {
                return ColumnTransformer.class;
            }
            
            @Override
            public String write() {
                return "aes_encrypt(?, '"+key+"')";
            }
            
            @Override
            public String read() {
                return "aes_decrypt("+propName+", '"+key+"')";
            }
            
            @Override
            public String forColumn() {
                return null;
            }
        };
    } 

Following is how I am verifying it

    private void print(List<String> props) throws NoSuchFieldException, SecurityException {
        for(String propName: props) {
            Field field = Partner.class.getDeclaredField(propName);
            
            for(Annotation an: field.getAnnotations()) {
                System.out.println(an);
            }
        }
    }

Seems its something to do with Java 7.





Aucun commentaire:

Enregistrer un commentaire