1

I'm writing an aspect for making that possible for dependencies from external libraries to return values that are correctly formatted for my application.

With this in mind, I've created an annotation with name @SafeReturns. I wire this class from the external library with the help of spring and in addition, I add my annotation.

@SafeReturns
@Autowired
public PermissionsClient client; 

Now I try to make an aspect of it, but unfortunately, I can't catch all the calls to all the methods on the field annotated with this annotation. I tried different pointcuts. e.g.

@Pointcut("execution(@myApp.SafeReturns * *(..))")

@Around("safeReturnsPointCut()")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {    
}

None of them helps me to achieve the behaviour of catching all the methods. Is there a way to catch them?

dvelopp
  • 4,095
  • 3
  • 31
  • 57
  • what is the difference between the methods for which it does work, and for those it doesn't? You do have the proceed call in logAround, I assume? – Stultuske Jan 19 '18 at 10:01
  • Aspect is in the context. But, it doesn't work for the case with SafeReturns on the field . – dvelopp Jan 19 '18 at 10:07
  • ... Fields aren't pointCuts. what exactly are you trying to do here? – Stultuske Jan 19 '18 at 10:08
  • I want to catch all methods invocations on the object that is declared as a field and has this annotation – dvelopp Jan 19 '18 at 10:10
  • that's not how it works, you need to add the annotation to the methods themselves. – Stultuske Jan 19 '18 at 10:11
  • This class is inside the library . That's why I can't add annotation there – dvelopp Jan 19 '18 at 10:12
  • or, to the class, is another option. that way, it would be the same as putting it on the field, but it would run for each and every instance – Stultuske Jan 19 '18 at 10:12
  • afaik, aop only takes method invocations into account as pointCuts, you can't add the configuration on a field. – Stultuske Jan 19 '18 at 10:13
  • Any thoughts how the current task can be solved if the class is in the library? Maybe create my own with the same interface but with annotation and delegating all the calls... ? But, that looks awful to make it only to apply annotation – dvelopp Jan 19 '18 at 10:15
  • you could create alternative methods 'in between', so, if you call an add method in that object, call addHandler() {myField.add(); } and annotate that addHandler method – Stultuske Jan 19 '18 at 10:18
  • Yes, but in this case, this annotation requires additional code to be written for new classes and objects if I want to use it with them.. – dvelopp Jan 19 '18 at 10:20
  • ... why? it is triggered by the annotation, so as soon as you add the annotation, it should be fine to go – Stultuske Jan 19 '18 at 10:21
  • I would need to write addHandler method for all the class methods? – dvelopp Jan 19 '18 at 10:25
  • it's one way to try, yes. – Stultuske Jan 19 '18 at 10:28
  • @Stultuske, sorry to tell you again, but I am seeing that you are trying really hard to help someone, just like in the other question. So you have my **great respect** for that. But anyway, you seem to have just dangerous half knowledge about AOP in general and Spring AOP and AspectJ in particular. Your comments and guesses keep irritating users with even less knowledge instead of leading them to the right solution. Maybe you tone it down, if you do not mind. As I said, I do respect your effort, but it really is not all that helpful. – kriegaex Jan 20 '18 at 05:02

1 Answers1

1

There are several problems with your approach and your assumptions about aspect syntax and execution logic:

  • You are using Spring AOP, but that one only works with Spring-managed beans/components due to its proxy-based nature, as is well documented in the Spring AOP manual. It does not work with non-Spring third-party code.

  • In order to target third-party code you need to use full AspectJ via LTW (load-time weaving). The Spring AOP manual also explains how to configure LTW.

  • Your pointcut says to target all method executions (of Spring components, if you are using Spring AOP) where the methods are annotated by SafeReturns. Neither with Spring AOP nor with AspectJ can you expect this syntax to apply to objects that happen to be assigned to instance member variables with a certain annotation. So your expectations of how you dream AOP to work and how it really does are quite divergent.

My suggestion is to switch to AspectJ via LTW and then write pointcuts which either target external method execution()s directly or to solve the problem indirectly by routing your external calls through annotated facades and target them with your pointcuts. This would even work with Spring AOP if the facades are Spring components.

There also is a direct way of solving this with advanced AspectJ + some manual bookkeeping. You can use set() pointcuts in order to find out when objects are assigned to your annotated fields (or unassigned later). Then you can have the aspect do manual bookkeeping of assigned objects and make sure that whatever your aspect advices do is only triggered if the object in question happens to be assigned to an annotated member variable. This works, I also have done that in the past. But it means you have to weave all of your application's method calls and then dynamically decide via look-ups in your bookkeeping whether or not the code should be executed or not, because there yould be object instances which are not assigned to any of your annotated fields. This incurs a certain performance penalty because this kind of thing cannot be determined during compile time by any aspect weaver. Please see my answer here for sample code for the manual bookkeeping thing.

I hope that my explanation was not too complicated, but your issue is quite technical and intricate.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Thanks for accepting my answer after more than 3 years. I had to read it again in order to remember what it was about. – kriegaex Apr 22 '21 at 06:16
  • FWIW, I read my [other answer](https://stackoverflow.com/a/38420605/1082681) again, too, and added some comments about shortcomings and why I do not like the manual bookkeeping solution in general. – kriegaex Apr 22 '21 at 07:38