Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Re: ReferenceType.isCoerceableFrom question

Ah, I think I see.  The pointcut definition is just saying that as long as it's a getter and the class implements the interface, the advice applies to it, regardless of whether the getter is defined in the interface or not.

Is there a way to restrict it to only implemented methods defined in the interface?  I think I can work around it now that I know what's happening, but I'm curious.

Pretty sneaky....

> I suspect your problem is that EPR is an interface.
>
> > The class "com.sabre.liberty.web.RequestTypeRegistry" extends Object and
> > implements no interfaces.  The interface "com.sabre.liberty.user.EPR"
> > extends no other interfaces.
>
> Suppose I wrote this (probably non-sensical but possible) code:
>
> class Foo extends RequestTypeRegistry implements EPR {
> }
>
> Object o = new Foo().getRequestTypes();
>
> Should it be advised?  Clearly it should as that is what you wrote in
> the pointcut:
>
> execution (* *.get*()) && this(com.sabre.liberty.user.EPR)
>
> Although it is advised, you will see the '[with runtime test]' check
> attached to the weaveinfo message, and I imagine if you looked in the
> woven code you would see the runtime test is 'instanceof EPR' which
> acts as a guard before the advise is called.  So the code will do what
> you asked, but it can be worrying when it advises so many places like
> this.
>
> This is a well known gotcha with using an interface type as at runtime
> the types flowing around could implement any old interface - so to do
> the right thing we have to advised lots of places - but include
> runtime checks to prevent advise running when it should not.
>
> just a note: if RequestTypeRegistry was 'final' (and so could not be
> subclassed), the get method would not be advised in this case.
>
> Does it cause you a problem that the extra places are advised?
>
> Andy.
>
> 2009/5/11 James Stangler <jastangler@xxxxxxxxx>:
> > I hope someone can help me understand what's going wrong (or let me know
> > what additional information I need to provide).  I have an aspect where the
> > pointcut seems to be advising code that it shouldn't be advising and it
> > seems to be getting the ok from the isCoerceableFrom method in
> > ReferenceType.  I'm using aspectJ 1.6.4 with LTW.
> >
> > My aspect is defined with:
> >
> >    @Pointcut("(execution (* *.get*()) && this(com.sabre.liberty.user.EPR))")
> >
> >    @Pointcut("(execution (* *.is*()) && this(com.sabre.liberty.user.EPR))")
> >
> >    @Around(value = "monitorEprGetMethod() || monitorEprIsMethod()")
> >
> > The pointcut should only be applied to instances of
> > "com.sabre.liberty.user.EPR" and its subclasses.  Unfortunately it seems to
> > be getting applied to almost any getter such as:
> >
> > [TomcatInstrumentableClassLoader@18346a3] weaveinfo Join point
> > 'method-execution(java.util.List
> > com.sabre.liberty.web.RequestTypeRegistry.getRequestTypes())' in Type
> > 'com.sabre.liberty.web.RequestTypeRegistry' (RequestTypeRegistry.java:54)
> > advised by around advice from
> > 'com.sabre.liberty.modules.util.greenbeans.IceDebugAspect'
> > (IceDebugAspect.java) [with runtime test]
> > [TomcatInstrumentableClassLoader@18346a3] weaveinfo Join point
> > 'method-execution(java.lang.Object
> > com.sabre.liberty.web.RequestTypeRegistry.getDefaultRequestType())' in Type
> > 'com.sabre.liberty.web.RequestTypeRegistry' (RequestTypeRegistry.java:58)
> > advised by around advice from
> > 'com.sabre.liberty.modules.util.greenbeans.IceDebugAspect'
> > (IceDebugAspect.java) [with runtime test]
> >
> > The class "com.sabre.liberty.web.RequestTypeRegistry" extends Object and
> > implements no interfaces.  The interface "com.sabre.liberty.user.EPR"
> > extends no other interfaces.
> >
> > It appears that the method ReferenceType.isCoerceableFrom is the one that
> > allows the methods to be advised.  The command in the method
> > isCoerceableFrom has the comment "true iff the statement "this = (ThisType)
> > other" would compile" which would never be the case since none of the
> > methods overlap (I guess a subclass could implement the interface and define
> > the methods, but the advice would always be applied to the subclass and
> > never this class).  Why would this method decide that one was coerceable to
> > the other?  The stacktrace below was while seeing if the advice
> > "@Around(value = "monitorEprGetMethod() || monitorEprIsMethod()")" should be
> > applied to "com.sabre.liberty.web.RequestTypeRegistry.getRequestTypes()".
> > The method returns true.
> >
> > Thread [main] (Suspended)
> >     ReferenceType.isCoerceableFrom(ResolvedType) line: 298
> >     ExactTypePattern.matchesInstanceof(ResolvedType) line: 177
> >     ExactTypePattern(TypePattern).matches(ResolvedType,
> > TypePattern$MatchKind) line: 150
> >     ThisOrTargetPointcut.matchInternal(Shadow) line: 113
> >     ThisOrTargetPointcut(Pointcut).match(Shadow) line: 146
> >     AndPointcut.matchInternal(Shadow) line: 54
> >     AndPointcut(Pointcut).match(Shadow) line: 146
> >     AndPointcut.matchInternal(Shadow) line: 52
> >     AndPointcut(Pointcut).match(Shadow) line: 146
> >     OrPointcut.matchInternal(Shadow) line: 53
> >     OrPointcut(Pointcut).match(Shadow) line: 146
> >     BcelAdvice(ShadowMunger).match(Shadow, World) line: 79
> >     BcelAdvice(Advice).match(Shadow, World) line: 112
> >     BcelAdvice.match(Shadow, World) line: 145
> >     BcelClassWeaver.match(BcelShadow, List) line: 3025
> >     BcelClassWeaver.match(LazyMethodGen) line: 2499
> >     BcelClassWeaver.weave() line: 480
> >     BcelClassWeaver.weave(BcelWorld, LazyClassGen, List, List, List,
> > boolean) line: 103
> >     BcelWeaver.weave(UnwovenClassFile, BcelObjectType, boolean) line:
> > 1735
> >     BcelWeaver.weaveWithoutDump(UnwovenClassFile, BcelObjectType) line:
> > 1696
> >     BcelWeaver.weaveAndNotify(UnwovenClassFile, BcelObjectType,
> > IWeaveRequestor) line: 1458
> >     BcelWeaver.weave(IClassFileProvider) line: 1272
> >     ClassLoaderWeavingAdaptor(WeavingAdaptor).getWovenBytes(String, byte[])
> > line: 423
> >     ClassLoaderWeavingAdaptor(WeavingAdaptor).weaveClass(String, byte[],
> > boolean) line: 286
> >     Aj.preProcess(String, byte[], ClassLoader) line: 95
> >     ClassPreProcessorAgentAdapter.transform(ClassLoader, String, Class<?>,
> > ProtectionDomain, byte[]) line: 52
> >
> > AspectJWeavingEnabler$AspectJClassBypassingClassFileTransformer.transform(ClassLoader,
> > String, Class<?>, ProtectionDomain, byte[]) line: 92
> >
> > InstrumentationLoadTimeWeaver$FilteringClassFileTransformer.transform(ClassLoader,
> > String, Class<?>, ProtectionDomain, byte[]) line: 181
> >     TransformerManager.transform(ClassLoader, String, Class,
> > ProtectionDomain, byte[]) line: not available
> >     InstrumentationImpl.transform(ClassLoader, String, Class,
> > ProtectionDomain, byte[], boolean) line: not available
> >     ClassLoader.defineClass1(String, byte[], int, int, ProtectionDomain,
> > String) line: not available [native method]
> >     TomcatInstrumentableClassLoader(ClassLoader).defineClass(String, byte[],
> > int, int, ProtectionDomain) line: not available
> >     TomcatInstrumentableClassLoader(SecureClassLoader).defineClass(String,
> > byte[], int, int, CodeSource) line: not available
> > <snip>



Back to the top