0

I am trying to use AspectJ for logging in a Spring Boot project. The latter has been set up with a controller class that handles the initial request for a particular document through a related REST controller. This controller class is extended by specific classes for each document, which assemble the end product; inheritance was not my idea.

To measure performance I want to log execution time for individual methods by using an @Around advice. However, even when the functions are individually annotated, those in the subclass are not advised. Methods further in the call stack that are not inherited from the initial controller class are not ignored. The relevant subclass methods are public and they are not inherited from the superclass.

Logging the execution time of the controller method is meant to provide the overall duration. Information with respect to subsequent functions is supposed to indicate possible bottlenecks. How can I include the methods declared in the subclass?

Confidentiality precludes sharing specifics, but the relevant aspects of the class structure can be conveyed using generic names:

document generator abbreviated class model [

To follow best practices I always intended to implement custom annotations to be used in pointcuts. Nevertheless, initially, I used signature based pointcuts and their combinations. Ignoring package elements of the pointcut declaration:

@Pointcut("execution(public String Controller.*(..)")
public void controllerPointcut() {}

This approach captures the controller methods, as do similar declarations for the reader classes. However such pointcuts are simply ignored in the case of the subclass. Using the + symbol to target child classes does not help. The documentation indicates that inherited or declared methods in a subclass can be targeted by signature. In the specific case this results in an IllegalStateException due to ambiguous mapping, as does the use of a class level annotation, unsurprisingly.

I only need to log two methods in the child classes, so I hoped to target them directly with a common annotation, which I also added to the controller and reader methods. The pattern, excluding package elements is:

@Pointcut("@annotation(LoggableDuration)")
public void readerControllerPointcut() {}

The functions in the latter two are being advised, so the annotation itself is not the problem. Nevertheless, the implementation has been added below. For thoroughness, I used a combined approach as well. The controller methods were targeted with the kind of signature approach shown above and for the rest an annotation was used. The result is the same. The problem seems to be some element of how AspectJ deals with inheritance that I have not been able to discover. However, I did expect that annotating individual methods could possibly allow me to avoid any such considerations.

@Component
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoggableDuration {}

Edit: It seems that Spring Boot was not picking up the subclass. Adding the @Component annotation allows AspectJ to advise the desired methods as does a class level custom annotation with ElementType.Type as the @Target value. However, both lead to an IllegalStateException: ambiguous mapping, presumably because of the inheritance of the Rest controllers. I managed to target the subclass methods with execution based pointcuts, which were not ignored. But, this caused the aforementioned exception to appear again.

kriegaex
  • 63,017
  • 15
  • 111
  • 202
Joe637
  • 1
  • 2
  • https://stackoverflow.com/questions/42607015/emulate-annotation-inheritance-for-interfaces-and-methods-with-aspectj see that please – Игорь Ходыко Jan 16 '23 at 19:01
  • Thank you for your advice and the quick response. I had not seen the linked question. Respectfully, I am not sure whether it applies. The child class inherits some methods that have been annotated, but the ones that are being ignored are declared and explicitly annotated in the subclass. They do not implement abstract methods, nor do they override any concrete functions. The super- and subclass are annotated, but not with AspectJ annotations. – Joe637 Jan 17 '23 at 10:48
  • I have edited my original question to reflect my findings with respect to class level annotation. Based on those developments I am more inclined to agree that JVM limitations with respect to inheritance of annotations were the cause for my original predicament. However, my understanding is still incomplete. With greater clarity I will acknowledge @ИгорьХодыко's reference as valid, if appropriate. I have changed the title to reflect the broader purpose of my original query. Should this be deemed inappropriate, I will ask the resulting question seperately. – Joe637 Jan 18 '23 at 19:14
  • Welcome to SO. Please learn some markdown syntax. I fixed lots of formatting issues in your question, such as the inline image not being displayed, paragraph and code formatting as well as syntax highlighting. – kriegaex Jan 20 '23 at 15:24
  • In order to enable the community to help you better, please and provide a [minimal, complete, and verifiable example](https://stackoverflow.com/help/mcve), ideally on GitHub. Then I should be able to help you quickly. Like this, there is too much code missing, hence there are too many variables concerning what you might have done wrong. Thank you. – kriegaex Jan 20 '23 at 15:27

0 Answers0