You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pointcuts.xml 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <chapter id="pointcuts" xreflabel="Debugging Pointcuts">
  2. <title>Debugging Pointcuts</title>
  3. <sect1 id="pointcuts-introduction">
  4. <title>Introduction</title>
  5. <para>
  6. This section describes how to write and debug pointcuts
  7. using the usual approach of iteration and decomposition.
  8. New users are often stumped when their advice does not match.
  9. That means the pointcut doesn't match; they rewrite the
  10. pointcut and it still doesn't match, with no new information.
  11. This can be frustrating if each iteration involves building,
  12. deploying, and testing a complex application. Learning to
  13. break it down, particularly into parts that can be checked
  14. at compile-time, can save a lot of time.
  15. </para>
  16. </sect1>
  17. <sect1 id="pointcuts-debugging">
  18. <title>Debugging pointcuts</title>
  19. <para>
  20. Go at it top-down and then bottom-up. Top-down, draft significant
  21. aspects by first writing the comments to specify responsibilities.
  22. Advice responsibility usually takes the form, "When X, do Y."
  23. Pointcut responsibility for "When X" often takes the form,
  24. "When [join points] [in locations] [are ...]". These []'s often
  25. translate to named pointcuts (like `libraryCalls() &amp;&amp; within(Client)
  26. &amp;&amp; args(Context)`) which form a semantic bridge to the plain-text
  27. meaning in a comment (e.g., `// when the client passes only context into
  28. the library`).
  29. This gets you to a point where you can debug the parts of the
  30. pointcut independently.
  31. </para>
  32. <para>
  33. Bottom up (to build each part), consider each primitive pointcut
  34. designator (PCD), then the composition, and then any implicit
  35. constraints:
  36. <orderedlist>
  37. <listitem><para>
  38. What kinds of join points should it match? (constructor-call?
  39. field-get?)? This translates to using the kinded pointcuts
  40. (`call(..)`, `get(..)`, etc.).
  41. </para></listitem>
  42. <listitem><para>
  43. Are these restricted to being lexically within something? This
  44. translates to using `within{code}(..)`. If this is true, it should
  45. always be used, to speed up weaving.
  46. </para></listitem>
  47. <listitem><para>
  48. What runtime constraints and context should be true and available at
  49. each join point? This translates to `this()`, `target()`, `args()`,
  50. `cflow{below}()` and `if(..)`.
  51. </para></listitem>
  52. <listitem><para>
  53. Are there any advice or implementation limitations at issue? This
  54. involves knowing the few constraints on AspectJ imposed by Java bytecode
  55. as listed in the AspectJ Programming Guide section on
  56. <ulink url="../progguide/implementation.html">Implementation Notes</ulink>.
  57. </para></listitem>
  58. </orderedlist>
  59. </para>
  60. <para>
  61. It's much faster to iterate a pointcut at compile-time
  62. using declare warning (even better, some errors are identified
  63. at parse-time in the latest versions of AJDT).
  64. Start with the parts of the pointcut
  65. that are staticly-determinable (i.e., they do not involve
  66. the runtime PCD's listed above). If compiles themselves
  67. take too long because of all the AspectJ weaving, then
  68. try to only include the debugging aspect with the prototype
  69. pointcut, and limit the scope using <literal>within(..)</literal>.
  70. </para>
  71. <para>
  72. Some mistakes in primitive pointcuts:
  73. <itemizedlist>
  74. <listitem><para>
  75. `this(Foo) &amp;&amp; execution(static * *(..))`: There is no `this` in a static
  76. context, so `this()` or `target()` should not be used in a static
  77. context or when targetting a static context (respectively). This
  78. happens most often when you want to say things like "all calls to Foo from Bar"
  79. and you only pick out calls to instance methods of Foo
  80. or you try to pick out calls from static methods of Bar.
  81. </para></listitem>
  82. <listitem><para>
  83. `target(Foo) &amp;&amp; call(new(..)`: This will never match. In
  84. constructor-call join points, there is no target because the object
  85. has not been created yet.
  86. </para></listitem>
  87. <listitem><para>
  88. `call(* Foo.*(..))`: `Foo` refers to the compile-time type of the
  89. invoking reference, not the implementing class. In Java before 1.4,
  90. the compile-time type was rendered as the defining type, not the
  91. reference type; this was corrected in 1.4 (as shown when using ajc
  92. with the -1.4 flag) Most people should use `target(Foo) &amp;&amp; call(...)`.
  93. </para></listitem>
  94. <listitem><para>
  95. `execution(* Foo.bar(..))`: An execution join point for Foo is
  96. always within Foo, so this won't pick out any overrides of bar(..).
  97. Use `target(Foo) &amp;&amp; execution(* bar(..))` for instance methods.
  98. </para></listitem>
  99. <listitem><para>
  100. `within(Foo)`: anonymous types are not known at weave-time to be
  101. within the lexically-enclosing type (a limitation of Java bytecode).
  102. </para></listitem>
  103. </itemizedlist>
  104. </para>
  105. <para>
  106. Some mistakes in composition:
  107. <itemizedlist>
  108. <listitem><para>
  109. `call(* foo(Bar, Foo)) &amp;&amp; args(Foo)`: This will never match.
  110. The parameters in `args(..)` are position-dependent, so `args(Foo)` only picks
  111. out join points where there is only one argument possible, of type Foo.
  112. Use the indeterminate-arguments operator '..' as needed, e.g., `args(Foo, ..)`.
  113. </para></listitem>
  114. <listitem><para>
  115. `call(* foo()) &amp;&amp; execution(* foo())`: This will never match. Each
  116. pointcut must be true at each join point matched. For a union of different
  117. kinds of join points (here, call or execution), use '||'.
  118. E.g., to match both method-call and field-get join points, use
  119. `call(* ...) || get(...)`.
  120. </para></listitem>
  121. </itemizedlist>
  122. </para>
  123. <para>
  124. Some mistakes in implicit advice constraints:
  125. <itemizedlist>
  126. <listitem><para>
  127. `after () returning (Foo foo) : ...`: after advice can bind the
  128. returned object or exception thrown. That effectively acts like
  129. `target()`, `this()`, or `args()` in restricting when the advice
  130. runs based on the runtime type of the bound object, even though it is
  131. not explicitly part of the pointcut.
  132. </para></listitem>
  133. </itemizedlist>
  134. </para>
  135. <para>
  136. Some mistakes in implementation requirements:
  137. <itemizedlist>
  138. <listitem><para>
  139. `ajc` has to control the code for a join point in order to implement
  140. the join point. This translates to an implicit `within({code under
  141. the control of the compiler})` for all join points, with additional
  142. caveat for some join points. Take exception handlers, for example:
  143. there is no way to be sure from the bytecode where the original handler
  144. ends, so `ajc` can't implement after advice on handler join points.
  145. (Since these are on a per-join-point basis, they should be considered
  146. for each corresponding primitive pointcut designator.) Unlike the
  147. mistakes with the primitive PCDs above, the compiler will emit an
  148. error for these caveats.
  149. </para></listitem>
  150. <listitem><para>
  151. `call(@SuperAnnotation Subclass.meth()`: Annotations are not inherited
  152. by default, so e.g., if the pointcut specifies an annotation, then
  153. subclass implementations of that method will not be matched.
  154. </para></listitem>
  155. </itemizedlist>
  156. </para>
  157. </sect1>
  158. </chapter>