reflection - Annotations on an overridden method are ignored in Java 8 PropertyDescriptor -
reflection - Annotations on an overridden method are ignored in Java 8 PropertyDescriptor -
i'm not quite sure how describe problem succinctly, please bear me.
i investigating upgrading our application java 7 java 8. application relies on utilize of reflection in order dynamically create instances of various business entities (a so-called "adaptive object model"). when seek building application latest java 8 (oracle 1.8.0_25) of tests start fail. specifically, there test checks see if getter method in 'test entity' annotated particular annotation, , test fails because annotation not found. super "entity" class has generic fields apply entity instances (name, description, displayname, etc.), , in test class "test entity" extends "entity" , overrides 1 of getter methods (getdisplayname) , adds additional annotation:
static class entitywithcompositedisplayname extends entity { @compositeproperty("${name} - ${description}") @override public string getdisplayname() { homecoming super.getdisplayname(); } } @compositeproperty our own annotation. has method target , runtime retention.
the test calls next code see if annotation present:
compositeproperty compositeproperty = propd.getreadmethod().getannotation(compositeproperty.class); "compositeproperty" returns null in java 8, not-null in java 7. if seek getannotation() 1 of annotations declare on super getdisplayname() method fine. similarly, if move compositeproperty annotation superclass test passes, not alternative in practice. can explain behaviour?
after little digging in jdk source code, here happens within jdk8 implementation of introspector:
introspector first introspects direct super class property accessors. doing so, each class in hierarchy, instance of introspector created. super class's introspector's gettargetpropertyinfo called subclass instrospector point, extract inherited propertydescriptors. when extracting properties of entitywithcompositedisplayname, 2 properties object::getclass , entity::getname extracted. when extracting methods of entitywithcompositedisplayname, introspector calls getpublicdeclaredmethods(class) method resolved using com.sun.beans.methodfinder::findaccessiblemethod(method). the later method checks declaring (!) class of method public not true entitywithcompositedisplayname. traverses in class hierarchy , tries disover public superclass declares method identical signature , returns method of super class. seems done in order avoid access checks required when accessing package-private class's method outside bundle (educated guess). the method resolution using using methodfinder not implemented in jdk7 (or earlier). consequence, did method expected.
looks side-effect of optimization (and bug) me.
java reflection annotations
Comments
Post a Comment