3

I'm finding the JPA metamodel generator functionality really useful for avoiding bugs when column names change. It would be really cool if there was some more general-purpose metamodel generation tool that you could point at any class (or a number of packages) that would generate similar metamodel classes. This could then be used to create compile errors rather than runtime ones when things change:

public class SomeClass {
  public int somePublicProperty;

  public String someStringMethod() {
    ..
  }
}

This might create a metamodel class like:

public class SomeClass_ {
  public static final FieldAttribute<SomeClass,Integer> somePublicProperty;

  public static final MethodAttribute<SomeClass,String> somePublicMethod;
}

where FieldAttribute and MethodAttribute have useful Attribute-like methods to assist with reflection calls (i.e. remove the need to have bare strings):

Object someClassInstance = ... 
Integer value = SomeClass_.somePublicProperty.get( someClassInstance );

// rather than 
Integer value = someClassInstance.getClass().getDeclaredField( "somePublicProperty" ).get( someClassInstance );

Is there anything like this currently available? There's a bit of support in Java 8 now we can do method references, but I'd like something a little bit more metamodel-like if it exists.

fancyplants
  • 1,577
  • 3
  • 14
  • 25

1 Answers1

3

I've had this need a few times and I've implemented this: https://github.com/mhagnumdw/bean-info-generator

Below how you do use this

If you're using Maven, add it to pom.xml

<dependency>
    <groupId>io.github.mhagnumdw</groupId>
    <artifactId>bean-info-generator</artifactId>
    <version>0.0.1</version>
    <scope>compile</scope>
</dependency>

Annotate your class with @GenerateBeanMetaInfo

import io.github.mhagnumdw.beaninfogenerator.GenerateBeanMetaInfo;
@GenerateBeanMetaInfo
public class SomeClass {
    private int someProperty;
}

When the build run, SomeClass_INFO.java and SomeClass_INFO.class are generated

public abstract class SomeClass_INFO {
    public static final BeanMetaInfo someProperty = new BeanMetaInfo("someProperty");
}

Now you can do something like this

Field field = SomeClass.class.getDeclaredField(SomeClass_INFO.someProperty.getName());

Generate *_INFO.java at development time in Eclipse

  • Right click on the project > Properties
  • Java Compiler > Annotation Processing > Factory path
  • Add two jars: bean-info-generator-0.0.1.jar and javapoet-1.9.0.jar

I hope it helps!

MhagnumDw
  • 893
  • 1
  • 10
  • 12