1

I would like to implement this 3rd-party annotation to map my class's fields/properties to my database table columns. I can easily implement the annotations at compile time (as shown in the example code below) but I can't find a way to do this at runtime. (I am loading the library at runtime using reflection.)

My question is how can I implement the same mapping annotation when loading a library at run time? Can Byte Buddy handle this for Android?

//3rd party annotation code
package weborb.service;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface MapToProperty {
    String property();
}

/////////////////////////////////////////////////////

//Here is the implementation using non-reflection
import weborb.service;
    Class Person
    {
        @MapToProperty(property="Person_Name")
        String name;

        @MapToProperty(property="Person_Age")
        int age;

        @MaptoProperty(property="Person_Name")
        public String getName()
        {
            return this.name;
        }

        @MaptoProperty(property="Person_Name")
        public void setName(String name)
        {
            this.name = name;
        }

        @MaptoProperty(property="Person_Age")
        public int getAge()
        {
             return this.age;
        }

        @MaptoProperty(property="Person_Age")
        public void setAge(int age)
        {
            this.age = age;
        }
    }
Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
Key
  • 139
  • 1
  • 9

1 Answers1

5

Yes, please refer to the Annotations section of the documentation for details.

You can build an annotation using an AnnotationDescription.Builder by:

AnnotationDescription.Builder.ofType(MapToProperty.class)
                             .define("property", "<value>")
                             .build();

The resulting AnnotationDescription can be supplied to a dynamic type builder as an argument:

new ByteBuddy()
  .subclass(Object.class)
  .defineField("foo", Void.class)
  .annotateField(annotationDescription)
  .make();

Similarly, it works for methods.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192
  • Class Person { String name; int age; public String getName() { return this.name; } public void setName(String name) { this.name = name; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } – Key Jan 20 '16 at 13:31
  • Thank you. Can I apply similar to add annotations at run time on an existing class? I'm using Byte-Buddy, Byte-Buddy-Android, and dx. – Key Jan 20 '16 at 13:40
  • In theory, yes, but Android does not implement Java's instrumentation API. Therefore, it is only possible if a class file is embedded into an application and if the modified class is loaded by a new class loader. – Rafael Winterhalter Jan 20 '16 at 15:56
  • @RafaelWinterhalter could you please explain how to make it work for methods without changing the method implementation? Would really appreciate, cannot find a good example :( – lub0v Jul 30 '19 at 19:39