0 Replies Latest reply on Mar 11, 2013 5:03 AM by geekerebos

    javassist not injecting annotation on an existing field

    geekerebos

      0 down vote  favorite   

       

      I'm trying to inject JAXB annotation at runtime using Javassist. I have written following code:

      public class AssistAnnotationInjector { 
         public static void addAnnotationRunTime(String className, String fieldName) throws NotFoundException, CannotCompileException, IOException, ClassNotFoundException{
        CtClass ctClass = ClassPool.getDefault().get(className);
      ClassFile ccFile = ctClass.getClassFile();
      ConstPool constPool = ccFile.getConstPool();
      AnnotationsAttribute attr = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
      Annotation annot = new Annotation("javax.xml.bind.annotation.XmlTransient",constPool); attr.addAnnotation(annot);
      CtField field = ctClass.getDeclaredField(fieldName);
      field.getFieldInfo().addAttribute(attr);
      System.out.println(field.getAnnotation(XmlTransient.class));
      ccFile.setVersionToJava5(); ctClass.writeFile();


      public static void main (String args[]) throws CannotCompileException, NotFoundException, IOException, SecurityException, NoSuchMethodException, ClassNotFoundException, JAXBException, NoSuchFieldException
      {
         Person<Student> p = new Person<Student>();
      p.setName("XYZ");
      Student s = new Student();
      s.setName("ABC");
      s.setId("239423");
      p.setPayload(s); 
      addAnnotationRunTime("RuntimeAnnotation.Person", "name");
        Field f = p.getClass().getDeclaredField("name");
      System.out.println(f.getAnnotation(XmlTransient.class));
      JAXBContext context = JAXBContext.newInstance(p.getClass());
        Marshaller mr = context.createMarshaller();
      mr.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
      mr.marshal(p, System.out);
      } }

      And Person.java class is:

      @XmlRootElement(name="Person")
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlSeeAlso({Student.class})
      public class Person <T>

      private T payload;
        private String name; 
      public void setPayload(T payload)
      {
      this.payload = payload;
      }
      public T getPayload()
      {
      return payload;

      public void setName(String name)
      {
      this.name = name;
      }
        public String getName()
      {
      return name;
      }
      }

      In AssistAnnotationInjector.java, I am trying to add XmlTransient annotation to 'name' field. But the name field is still coming in marshalling output. Why is it so?

      PS: marshal output is :

      @javax.xml.bind.annotation.XmlTransient null <?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
      <Person>
      <payload xmlns:xsi="
      http://www.w3.org/2001/XMLSchema-instance" xsi:type="student">
      <name>ABC</name>
      <id>239423</id>
      </payload>
      **<name>XYZ</name>**
      </Person>

      name tag was not expected to present in output..