When I run the application with tomcat it says that the advices has not been aplied, so my aspects won't work. Do I have to configure that anywhere? I haven't done anything about it, so I don't know what code might be useful.
Thank you!
EDIT
I've just found out how to fix that, and even when it says that the aspect has not been applied, when I call the setter it works, but I have a problem when using reflection for that.
I have an aspect which intercept a setter to a field which works well, but when the value is assigned from Gson library por example, it doesn't work.
This is the 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;
try {
result = proceed(annotation, "intercepted");
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
}
And I have this class:
public class JavaEntity {
@Annotation
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
When I do something like this it does not intercept the assignment:
JavaEntity entity = new Gson().fromJson("{\"name\":\"name\"}", JavaEntity.class);
Is there anyway to intercept that? Thank you!
Reflective field access cannot be directly intercepted by AspectJ. You could only work around it by fighting fire with fire, i.e. also using reflection:
- Make sure Gson is on the inpath for the AspectJ compiler (i.e. a weave dependency for AspectJ Maven plugin) so as to be able to weave into its code.
- Intercept calls to
Field.set(..)
.
- In the intercepting advice check which field is to be set, look up its annotations via reflection in order to emulate
@annotation(blah)
, decide whether to modify its value or not.
This is not exactly the usual AspectJ use case, but possible.
BTW, you do not have this kind of problem with execution()
joinpoints because they are also triggered when a method is called reflectively. You would have the problem with call()
, though. But this is just for your information, not directly related to this specific case.
Update: I mean something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>Group</groupId>
<artifactId>model</artifactId>
</weaveDependency>
<weaveDependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>
</plugin>
@Test
public void testingInterceptWithJavaGson(){
javaEntity = new Gson().fromJson("{\"name\":\"newName\"}", JavaEntity.class);
Assert.assertEquals("intercepted", javaEntity.getName());
}
Object around(Field field, Object obj, Object value) :
within(com.google.gson..*) &&
call(public void Field.set(Object, Object)) &&
target(field) &&
args(obj, value)
{
Object result = null;
System.out.println(thisJoinPoint);
System.out.println(" " + field + " -> " + field.getAnnotation(Annotation.class));
System.out.println(" " + obj);
System.out.println(" " + value);
try {
if (field.getAnnotation(Annotation.class) != null && field.getType() == String.class)
result = proceed(field, obj, "intercepted");
else
result = proceed(field, obj, value);
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
Actually you do not need to bind the first parameter obj
via args()
, I just use it for logging so as to show you what happens there. So this slightly simpler form will also do:
Object around(Field field, Object value) :
within(com.google.gson..*) &&
call(public void Field.set(Object, Object)) &&
target(field) &&
args(*, value)
{
Object result = null;
System.out.println(thisJoinPoint);
try {
if (field.getAnnotation(Annotation.class) != null && field.getType() == String.class)
result = proceed(field, "intercepted");
else
result = proceed(field, value);
} catch (RuntimeException ex) {
throw ex;
}
return result;
}
The changes to your existing GitHub repo are contained in yet another pull request from my fork.