> Actually and unfortunately, contrary to your assumption
​> ​
Signature.getDeclaringType() does not yield the same type as
​> ​
thisJoinPoint.getTarget().getClass().

That isn't exactly what I was saying. I was saying this new method you
wanted to add, how would its return value differ from
thisJoinPoint.getTarget().getClass() - I know that getDeclaringType() would
be different from thisJoinPoint.getTarget() since the former is based on
the type referenced in the invoke instruction (it is not based on the type
of the target, even if that could be statically analyzed) whilst the second
is based on the runtime types flowing around. From your test program it
seems you want this new method on tip to return the actual declaring class
of the method involved?

It all depends what you want at the join point - as your test program shows
you can dig around for whatever you want (if you really want the declaring
class of the method involved, you can find it). I could push helper code
into thisJoinPoint for some of this but I need concrete use cases and votes
on requests for it.

cheers,
Andy





On 23 May 2014 06:20, Alexander Kriegisch <alexan...@kriegisch.name> wrote:

> Actually and unfortunately, contrary to your assumption
> Signature.getDeclaringType() does not yield the same type as
> thisJoinPoint.getTarget().getClass().
>
> Here is some sample code (also attached) demonstrating the problem. You
> need
> Apache Commons Lang (my version is 3.3.2) in order to use ClassUtils
> because
> I found it too tedious to deal with Class.forName(<primitive type>) by
> myself:
>
>
> package de.scrum_master.app;
>
> import java.util.ArrayList;
> import java.util.List;
>
> public class MyList<E> extends ArrayList<E> {
>         private static final long serialVersionUID = -8827657434447203955L;
>
>         public MyList() { super(); }
>         @Override public boolean remove(Object o) { return false; }
>
>         public void myMethod() {}
>         public int myOtherMethod(int number) { return number * number; }
>
>         public static void main(String[] args) {
>                 MyList<String> myList = new MyList<>();
>                 myList.add("foo");
>                 myList.add("bar");
>                 myList.remove("bar");
>                 myList.add(0, "XXX");
>                 for (String element : myList)
>                         System.out.println(element);
>                 myList.myMethod();
>                 myList.myOtherMethod(11);
>
>                 List<String> jdkList = new MyList<>();
>                 jdkList.add("one");
>                 jdkList.add("two");
>                 jdkList.remove("two");
>                 jdkList.add(0, "XXX");
>                 for (String element : jdkList)
>                         System.out.println(element);
>         }
> }
>
>
> package de.scrum_master.aspect;
>
> import java.lang.reflect.Method;
>
> import org.apache.commons.lang3.ClassUtils;
> import org.aspectj.lang.Signature;
> import org.aspectj.lang.SoftException;
>
> public aspect MethodTracer pertarget(call(* *(..))) {
>         public MethodTracer() {
>                 super();
>                 System.out.printf(
>                                 "%n%-60s  |  %-30s  |  %-30s  |  %-30s%n",
>                                 "Join point",
>                                 "AJ target class",
>                                 "AJ method declaring type",
>                                 "Real method declaring type"
>                         );
>                 System.out.printf(
>                                 "%-60s==|==%-30s==|==%-30s==|==%-30s%n",
>
> "============================================================",
>                                 "==============================",
>                                 "==============================",
>                                 "=============================="
>                         );
>         }
>
>         before(Object target) : !within(MethodTracer) && call(* *(..)) &&
> target(target) {
>                 Signature methodSignature =
> thisJoinPointStaticPart.getSignature();
>                 Method method;
>                 try {
>                         String[] signatureParts =
> methodSignature.toLongString().split("[()]|, ");
>                         Class<?>[] parameterTypes = new
> Class<?>[signatureParts.length - 1];
>                         int index = -1;
>                         for (String signaturePart : signatureParts) {
>                                 if (++index == 0)
>                                         continue;
>                                 parameterTypes[index - 1] =
> ClassUtils.getClass(signaturePart);
>                         }
>                         method =
> target.getClass().getMethod(methodSignature.getName(), parameterTypes);
>                 } catch (ClassNotFoundException|NoSuchMethodException e) {
>                         throw new SoftException(e);
>                 }
>                 System.out.printf(
>                         "%-60s  |  %-30s  |  %-30s  |  %-30s%n",
>                         thisJoinPointStaticPart,
>                         target.getClass().getName(),
>                         methodSignature.getDeclaringTypeName(),
>                         method.getDeclaringClass().getName()
>                 );
>         }
> }
>
>
> The output looks like this for the two lists I create in the driver class:
>
>
> Join point                                                    |  AJ target
> class                 |  AJ method declaring type        |  Real method
> declaring type
>
> ==============================================================|==================================|==================================|================================
> call(boolean de.scrum_master.app.MyList.add(Object))          |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  java.util.ArrayList
> call(boolean de.scrum_master.app.MyList.add(Object))          |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  java.util.ArrayList
> call(boolean de.scrum_master.app.MyList.remove(Object))       |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  de.scrum_master.app.MyList
> call(void de.scrum_master.app.MyList.add(int, Object))        |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  java.util.ArrayList
> call(Iterator de.scrum_master.app.MyList.iterator())          |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  java.util.ArrayList
> XXX
> foo
> bar
> call(void de.scrum_master.app.MyList.myMethod())              |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  de.scrum_master.app.MyList
> call(int de.scrum_master.app.MyList.myOtherMethod(int))       |
>  de.scrum_master.app.MyList      |  de.scrum_master.app.MyList      |
>  de.scrum_master.app.MyList
>
> Join point                                                    |  AJ target
> class                 |  AJ method declaring type        |  Real method
> declaring type
>
> ==============================================================|==================================|==================================|================================
> call(boolean java.util.List.add(Object))                      |
>  de.scrum_master.app.MyList      |  java.util.List                  |
>  java.util.ArrayList
> call(boolean java.util.List.add(Object))                      |
>  de.scrum_master.app.MyList      |  java.util.List                  |
>  java.util.ArrayList
> call(boolean java.util.List.remove(Object))                   |
>  de.scrum_master.app.MyList      |  java.util.List                  |
>  de.scrum_master.app.MyList
> call(void java.util.List.add(int, Object))                    |
>  de.scrum_master.app.MyList      |  java.util.List                  |
>  java.util.ArrayList
> call(Iterator java.util.List.iterator())                      |
>  de.scrum_master.app.MyList      |  java.util.List                  |
>  java.util.ArrayList
> XXX
> one
> two
>
> --
> Alexander Kriegisch
> http://scrum-master.de
>
>
> Andy Clement schrieb am 23.05.2014 02:51:
>
> > I had a further thought about this problem whilst out on a run, I can
> > imagine (although I haven't coded it up) something around and if() clause
> > and using reflection with <target>.class.getDeclaredMethod(<thisJoinPoint
> > stuff in here>) (and walking up the hierarchy) to check where the method
> > is actually declared. Won't do much for the performance though :)
> >
> >
> > > As for Signature.getDeclaringTypeName(), the acceptance criteria do not
> > seem to involve dynamic method resolution, only static code analysis
> (what
> > is the target's declared type?). Would it be possible to enhance that
> > method, add a toggle or similarly named method for dynamic resolution?
> >
> >
> > Currently that information is built based solely on the invoke
> instruction
> > (static info), we're not actually looking at what is on the stack so are
> > at the mercy of what the compiler decided to do. It is feasible to add a
> > similar named method but isn't that just the same as asking
> > thisJoinPoint.getTarget().getClass() (at least for non static methods)?
> >
> >
> > On 22 May 2014 16:06, Alexander Kriegisch <alexan...@kriegisch.name
> > <mailto:alexan...@kriegisch.name> > wrote:
> >>
> >> An afterthought: As for Signature.getDeclaringTypeName(), the acceptance
> >> criteria do not seem to involve dynamic method resolution, only static
> >> code analysis (what is the target's declared type?). Would it be
> possible
> >> to enhance that method, add a toggle or similarly named method for
> >> dynamic resolution?
> >>
> >>
> >> Alexander Kriegisch schrieb am 23.05.2014 00:55:
> >>
> >> > Okay, so you had the same thoughts ('if' pointcut and stacktrace
> check)
> >> as I
> >> > and also the same results. We would need something like a sneek peek
> >> towards
> >> > method resolution which happens just an instant later, but not quite
> at
> >> the
> >> > call site.
> >> >
> >> > BTW, this was one of my experimental pointcuts:
> >> >
> >> > pointcut jdkType() :
> >> >
> >>
> if(thisJoinPointStaticPart.getSignature().getDeclaringTypeName().startsWith("java."));
> >> >
> >> > But for the reasons I mentioned on StackOverflow this does not (and
> >> cannot)
> >> > work reliably for two out of four cases.
> >> >
> >> > Thank you anyway :-)
> >> >
> >> >
> >> > Andy Clement schrieb am 23.05.2014 00:48:
> >> >
> >> >> I can't immediately think of a way to do that. Even if using an if()
> >> clause on
> >> >> the point cut to insert a runtime test, that test can't tell whose
> >> method is
> >> >> running on the object you have (whether it is a local one or an
> >> inherited
> >> >> one). You can't even inspect the stack trace in the advice (which
> >> would be
> >> >> crude anyway) because the advice invocation is made at the call site
> >> before
> >> >> you enter the method in question.
> >> >>
> >> >> Incidentally I am probably going to be hanging around on stack
> >> overflow more
> >> >> these days so anyone posting questions here, feel free to start
> >> posting there,
> >> >> I will see them :)
> >> >>
> >> >>
> >> >> On 22 May 2014 00:59, Alexander Kriegisch wrote:
> >> >>
> >> >>> On StackOverflow I saw an interesting question. Even though I (user
> >> >>> kriegaex) have answered it as good as I could at
> >> >>>
> >>
> http://stackoverflow.com/questions/23791760/aspectj-separating-native-library-calls-from-application-calls/23799457#23799457
> >> >>> ,
> >> >>> I am still wondering if there might be a way to find out which
> method
> >> a
> >> >>> call really resolves to later in all of the four cases mentioned
> >> there,
> >> >>> because in general a call joinpoint's signature is not necessarily
> >> equal
> >> >>> to what gets executed later.
> >> >>>
> >> >>> I don't know if anyone can answer that, but my best guess would be
> >> Andy
> >> >>> Clement (as usual). ;-)
>
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@eclipse.org
> https://dev.eclipse.org/mailman/listinfo/aspectj-users
>
>
_______________________________________________
aspectj-users mailing list
aspectj-users@eclipse.org
https://dev.eclipse.org/mailman/listinfo/aspectj-users

Reply via email to