Community
Participate
Working Groups
When using @Aspectj style intertype declaration modifiers and annotations set in the aspect (on the @DeclareParents block) are not retained on the introduced field in the woven class. When weaving for instance persistent Hibernate entities (Hibernate annotations style) the introduced field will be treated as a persistent field. As any @Transient declaration set in the aspect is lost during weaving hence we have no way to tell hibernate to treat the introduced field as non-persistent. A work-around is to use the traditional aspectj syntax where annotations declared on introduced fields are retained in the woven class.
look into what we can do here for 1.6.2
The mixin nature of annotation style declare parents doesn't add any of the fields from the default impl mentioned in the DeclareParents pattern. Only a placeholder field for the associated instance is added to the target type. And forwarding methods are added to the target type to satisfy the interface. As observed by Larry Chu (see first link in bug 243203) in this case the annotations on fields will have no affect on the advised type since the field is never put into the target (so fields in the impl class are not really like itd fields). So this is currently working as designed. But I am not against reviewing the design. Right now I cannot decide whether to: - try and modify the implementation of DeclareParents to copy the fields across to the target and change the code in the decp implementation class to use those copied fields (as opposed to those declared in the impl class) - change the name to DeclareMixin (as per Larrys suggestion) to reduce confusion that it is at all like DeclareParents... My test program so far: -----8<---- import java.lang.annotation.*; import org.aspectj.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @interface Foo {} enum Mood { HAPPY, SAD; } interface Moody { Mood getMood(); }; class MoodyImpl implements Moody { @Foo public Mood mood = Mood.HAPPY; public MoodyImpl() {} @Foo public Mood getMood() { return mood; } } @Aspect class MoodIndicator { @DeclareParents(value="Target",defaultImpl=MoodyImpl.class) private Moody implementedInterface; @Before("execution(* Target.*(..)) && this(m)") public void feelingMoody(Moody m) { System.out.println("I'm feeling " + m.getMood()); } } public class Target { public static void main(String[] argv) { new Target().run01(); } public void run01() { } } -----8<----
unsetting the target field which is currently set for something already released