3

My goal is to 'around' all the equals methods of the subclasses of a type. So, I wrote the following aspect.

I'm using the aspectj-maven-plugin, and I'm telling it to weave the code in a dependency jar file, since that's where all the equals methods are.

I am rewarded with:

Warning:(22, 0) ajc: does not match because declaring type is java.lang.Object, if match desired use target(com.basistech.rosette.dm.BaseAttribute+) [Xlint:unmatchedSuperTypeInCall] 
Warning:(22, 0) ajc: advice defined in com.basistech.rosette.dm.AdmEquals has not been applied [Xlint:adviceDidNotMatch]

I am puzzled. Plenty of types in the hierarchy of BaseAttribute declare equals, so it should not be looking at Object. Adding &&target(BaseAttribute+) does not seem to make this error go away.

What am I missing, and/or how should I go about tracking this down?

package com.basistech.rosette.dm;

/**
 * See if we can't make an aspect to spy on equals ...
 */
public aspect AdmEquals {
    // we would like to narrow this to subclasses ...
    boolean around(Object other): call(public boolean BaseAttribute+.equals(java.lang.Object)) && args(other) {
        boolean result = proceed(other);
        if (!result) {
            System.out.println(this);
            System.out.println(other);
            System.out.println(result);
        }
        return true;
    }
}
bmargulies
  • 97,814
  • 39
  • 186
  • 310

1 Answers1

3

OK, light dawned. The AspectJ call specs describe where a method is defined at the base of the class hierarchy, apparently, not where it is overridden. So the following purports to do the necessary dirty work.

public aspect AdmEquals {
    // we would like to narrow this to subclasses ...
    boolean around(Object other) : 
        call(public boolean Object.equals(java.lang.Object)) &&
        args(other) &&
        target(BaseAttribute+)
    {
        boolean result = proceed(other);
        if (!result) {
            System.out.println(this);
            System.out.println(other);
            System.out.println(result);
        }
        return true;
    }
}
kriegaex
  • 63,017
  • 15
  • 111
  • 202
bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • No, this is not the solution. I will write another answer and explain why and what to do instead. – kriegaex Oct 13 '14 at 09:12
  • Oops, my bad, I did not scroll horizontally to see the `target()` part of the pointcut. I have just reformatted the code with line breaks to make the crucial part visible. – kriegaex Oct 13 '14 at 09:27
  • As an alternative you might want to consider using an execution instead of a call pointcut. It also weaves fewer places in your code which often is favourable: `execution(public boolean BaseAttribute+.equals(Object))` This way you also do not need the `target()` limitation. – kriegaex Oct 13 '14 at 09:29
  • Thanks. I eventually realized that for myself. – bmargulies Oct 13 '14 at 11:17