Reputation: 4504
I want to intercept all assignments to a field which is annotated with MyAnnotation in this case. If it works when the value is assigned with reflction is much better. This is what I tried, but it does not run, and I think that something else might be wrong:
public privileged aspect MyAnnotationAspect {
pointcut hasAnnotation(MyAnnotation annotation) : @annotation(annotation);
pointcut methodExecution() : execution(* *(..));
Object around(MyAnnotation annotation) : set(String word) && methodExecution() && hasAnnotation(annotation) {
Object result = null;
try {
result = proceed(annotation, "new"); //Just to try I want to assign "new" instead of the variable word
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}
It says that are too many arguments for the method proceed. Can anyone help me? Thank you!
EDIT
Now it throws "Warning:(10, 0) ajc: advice defined in aspects.AnnotationAspect has not been applied [Xlint:adviceDidNotMatch]"
This is my aspect:
public aspect AnnotationAspect {
pointcut hasAnnotation(Annotation annotation) : @annotation(annotation);
Object around(Annotation annotation, String word) : hasAnnotation(annotation) && set(String *) && args(word) {
Object result = null;
System.out.println(thisJoinPoint);
try {
result = proceed(annotation, "intercepted");
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
}
This is the annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Annotation {
}
I have a dummy in order to test it:
class DummyEntity{
@Annotation
var name: String =_
def setName(n: String): Unit ={
name = n
}
}
And this is the test where I'm testing it:
public class AnnotationAspectTest {
private DummyEntity dummyEntity;
@Before
public void setUp(){
dummyEntity = new DummyEntity();
}
@Test
public void testing(){
dummyEntity.setName("newName");
Assert.assertEquals("intercepted", dummyEntity.name());
}
}
Upvotes: 0
Views: 1022
Reputation: 67297
The methodExecution()
is counter-productive here because you do not want to capture method executions, but field write access. Because set(..) && execution(..)
are mutually exclusive, this makes no logical sense.
Furthermore, you need to bind the assigned value to a parameter via args()
in order to be able to modify it.
package de.scrum_master.aspect;
import de.scrum_master.app.MyAnnotation;
public aspect MyAnnotationAspect {
Object around(MyAnnotation annotation, String word) :
@annotation(annotation) && set(String *) && args(word)
{
System.out.println(thisJoinPoint);
Object result = null;
try {
result = proceed(annotation, "altered value");
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
return result;
}
}
Upvotes: 1