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.

README-169.html 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  2. <html> <head>
  3. <title>AspectJ 1.6.9 Readme</title>
  4. <style type="text/css">
  5. <!--
  6. P { margin-left: 20px; }
  7. PRE { margin-left: 20px; }
  8. LI { margin-left: 20px; }
  9. H4 { margin-left: 20px; }
  10. H3 { margin-left: 10px; }
  11. -->
  12. </style>
  13. </head>
  14. <body>
  15. <div align="right"><small>
  16. &copy; Copyright 2010 Contributors.
  17. All rights reserved.
  18. </small></div>
  19. <h1>AspectJ 1.6.9 Readme</h1>
  20. <p>The full list of resolved issues in 1.6.9 is available <a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_status=RESOLVED;bug_status=VERIFIED;bug_status=CLOSED;product=AspectJ;target_milestone=1.6.9;target_milestone=1.6.9M1;target_milestone=1.6.9M2;target_milestone=1.6.9RC1">here</a></h2>
  21. <h2>Features</h2>
  22. <h3>declare annotation supports compound signature patterns: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=287613">287613</a></h3>
  23. <p>Until now it wasn't possible to express a compound pattern in any of the declare annotation constructs that
  24. take a member signature. For example, if you wanted to attach an annotation to all your getter like methods, you needed
  25. two constructs</p>
  26. <pre><code>
  27. declare @method: * is*(): @FooBar;
  28. declare @method: * get*(): @FooBar;
  29. </code></pre>
  30. <p>Now AspectJ allows compound patterns for declare @method/@constructor/@field.</p>
  31. <pre><code>
  32. declare @method: (* is*()) || (* get*()): @FooBar;
  33. </code></pre>
  34. <h3>Intertype declaration of member types</h3>
  35. <p>It is now possible to ITD member types. The syntax is as would be expected. This example introduces a new member type called
  36. Inner into type Foo:</p>
  37. <pre><code>public class Foo {
  38. public static void main(String[] args) {
  39. new Inner().run();
  40. }
  41. }
  42. aspect Magic {
  43. public static class Foo.Inner {
  44. public void run() {
  45. System.out.println("Inner.run() executing");
  46. }
  47. }
  48. }</code></pre>
  49. <p>Only static member types are supported.</p>
  50. <h3>'Optional' aspects: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=310506">310506</a></h3>
  51. <p>It is not uncommon to ship a library aspect separately to a jar upon which it depends. In the case of Spring there is
  52. an aspect library containing a multitude of aspects that attach different technologies (transactions/persistence/etc) to your
  53. application. Normally an aspect will fail with a "can't find type" style message if a weaver is told to use it and yet it
  54. references some missing dependency. This can be annoying and require you to include jars on your classpath (or in your maven
  55. configuration) that you don't actually use, they are *only* there to avoid problems with the aspect. In 1.6.9 you can add
  56. a setting to these aspects in the aop.xml that makes them optional. The setting mentions a type and if that type cannot be found
  57. the aspect immediately shuts itself down. This basically means that the aspect is only going to do its job if the type being
  58. mentioned in the setting is around. This enables the aspect library to be on the aspect path but any aspects within it to
  59. switch-off if there is nothing for them to do.
  60. </p>
  61. <p>Here is an example, 'AspectA' will switch itself off if the type 'a.b.c.Anno' cannot be found:</p>
  62. <code><pre>
  63. &lt;aspect name="AspectA" requires="a.b.c.Anno"/&gt;
  64. </pre></code>
  65. <h3>Reduction in class file sizes: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=312839">312839</a></h3>
  66. <p>More details here: <a href="http://andrewclement.blogspot.com/2010/05/aspectj-size-is-important.html">http://andrewclement.blogspot.com/2010/05/aspectj-size-is-important.html</a>
  67. but basically some work has been done to improve the serialized form of aspects. As an example, a compiled Roo petclinic sample (which
  68. uses lots of aspects and ITDs) is down from 1Meg (AspectJ 1.6.9m2) to 630k (AspectJ 1.6.9rc1).</p>
  69. <h3>Transparent weaving: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743">309743</a></h3>
  70. <p>In a further step towards transparent weaving, support for the AjType reflection system is now being made optional.
  71. This means if intending to use the AjTypeSystem to reflect on woven code, then the code must be built with the
  72. option -makeAjReflectable. This change is being made because the reflection supporting metadata that
  73. enables the AjTypeSystem to work can break other tools that are just using regular reflection on the classes. These
  74. days many more users are processing classes using standard reflection than are using AjTypeSystem. The related bugzilla
  75. discussing this issue is <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=309743">309743</a>.</p>
  76. <h3>Overweaving: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450">293450</a></h3>
  77. <p>Preliminary support for overweaving was added in AspectJ 1.6.7, but now in AspectJ 1.6.9m2 it is much more reliable.
  78. Basically it is an alternative to reweaving when needing to weave a class multiple times. Overweaving can cope with
  79. 'other tools' modifying the bytecode in between AspectJ weaves, whereas reweaving cannot. More details are in the related
  80. bugzilla <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=293450">293450</a> and in this
  81. <a href="http://andrewclement.blogspot.com/2010/05/aspectj-overweaving.html">blog article</a>. A weaver is switched
  82. into overweaving mode by the option -Xset:overWeaving=true - which can be specified on the command line or in the weaver
  83. options section of aop.xml. There is still more work to be done on this feature - any feedback is welcome.</p>
  84. <h3>AOP Scoping: <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=124460">124460</a></h3>
  85. <p>Another feature that had preliminary support a while ago is aspect scoping in aop.xml. This has also been improved in
  86. AspectJ1.6.9m2. For those not aware of it, it is the ability to specify a scope against aspects defined in your loadtime
  87. weaving aop.xml file. A scope effectively enables the user to limit the applicability of your aspect to some subset of all those
  88. types included by the weaver include section. Why is it needed? It can be useful when taking an aspect that did not
  89. originally scope itself properly (using a within clause) and needing to limit its effect in a load time weaving context.
  90. Think of it as a within
  91. pattern that you can put into the aop.xml that augments all the pointcuts defined in the original aspect.</p>
  92. <p>Here is an example:</p>
  93. <code><pre>
  94. &lt;aspectj&gt;
  95. &lt;aspects&gt;
  96. &lt;aspect name="X"/&gt;
  97. &lt;aspect name="Y" scope="com.foo..*"/&gt;
  98. &lt;/aspects&gt;
  99. &lt;weaver&gt;
  100. &lt;include within="com..*"/&gt;
  101. &lt;/weaver&gt;
  102. &lt;/aspectj&gt;
  103. </pre></code>
  104. <p>In this example the weaver include section specifies all the types in com..* should be woven and the
  105. aspects to be used are X and Y. The new 'scope' setting on aspect Y's definition allows finer control, and specifies that
  106. Y should in fact only be applied to com.foo..* types.</p>
  107. <h3>Message inserts for declare warning/error messages</h3>
  108. <p>It is now possible to use joinpoint context in the messages attached to declare warning and declare error constructs. Some
  109. examples:</p>
  110. <code><pre>
  111. declare warning: execution(* A.m(..)): "joinpoint is {joinpoint}";
  112. declare warning: execution(* A.m(..)): "joinpoint kind is '{joinpoint.kind}'";
  113. declare warning: get(int *) && within(A): "joinpoint signature is {joinpoint.signature}";
  114. declare warning: execution(* A.m(..)): "joinpoint declaring type is {joinpoint.signature.declaringType}";
  115. declare warning: execution(* A.m(..)): "signature name for method is {joinpoint.signature.name}";
  116. declare warning: execution(* A.m(..)): "joinpoint location is {joinpoint.sourcelocation.sourcefile}:{joinpoint.sourcelocation.line}";
  117. declare warning: execution(* A.m(..)): "joinpoint line is '{joinpoint.sourcelocation.line}'";
  118. declare warning: get(int *): "warning is from aspect {advice.aspecttype}";
  119. declare warning: execution(* A.m(..)): "warning sourcelocation is {advice.sourcelocation.sourcefile}:{advice.sourcelocation.line}";
  120. </pre></code>
  121. <p>The syntax is to enclose the relevant key within curly brackets within the message. Please raise an enhancement request
  122. if you need other keys - the set supported so far are all those shown in the example above.</p>
  123. <h3>declare warning/error for type patterns</h3>
  124. <p>It is now possible to use a type pattern with declare warning and declare error. For example:</p>
  125. <code><pre>
  126. declare warning: I+ && !hasfield(int i): "Implementations of I are expected to have a int field called i";
  127. </pre></code>
  128. <h3>Type category type patterns</h3>
  129. <p>This is the ability to narrow the types of interest so that interfaces can be ignored, or inner
  130. types, or classes or aspects. There is now a new is() construct that enables this:</p>
  131. <code><pre>
  132. execution(* (!is(InnerType)).m(..)) {}
  133. !within(* && is(InnerType)) {}
  134. </pre></code>
  135. <p>Options for use in is() are: ClassType, AspectType, InterfaceType, InnerType, AnonymousType, EnumType, AnonymousType.</p>
  136. <p>Note: It is important to understand that "!within(is(InnerType))" and "within(!is(InnerType))" are not the same. The latter one is
  137. unlikely to be what you want to use. For example here:
  138. <code><pre>
  139. class Boo {
  140. void foo() {}
  141. class Bar {
  142. void foo() {}
  143. }
  144. }
  145. </pre></code>
  146. <p>Bar.foo() will match within(!is(InnerType)) because within considers all surrounding types (so although Bar doesn't match the
  147. pattern, the surrounding Boo will match it). Bar.foo() will not match !within(is(InnerType)) because Bar will match the pattern
  148. and then the result of that match will be negated.</p>
  149. <h3>Intertype fields preserve visibility and name</h3>
  150. <p>Some users always expect this:</p>
  151. <code><pre>
  152. class C {
  153. }
  154. aspect X {
  155. private int C.someField;
  156. }
  157. </pre></code>
  158. <p>To cause a private field called 'someField' to be added to C. This is conceptually what happens during compilation but if any
  159. user then later attempts to access someField via reflection or runs a javap against the class file, they will see that isn't
  160. what happens in practice. A public member is added with a mangled name. For code attempting to access someField built with ajc,
  161. the visibility of the declaration will, of course, be respected. But for frameworks accessing the code later (typically through
  162. reflection), it can cause confusion. With AspectJ 1.6.9 the name and visibility are now preserved. Compile time semantics
  163. remain the same, it is only the weaving process that has changed to produce slightly different output.</p>
  164. <p>Here is the output of javap when that is built with 1.6.8:</p>
  165. <code><pre>
  166. class C extends java.lang.Object{
  167. public int ajc$interField$X$someField;
  168. C();
  169. }
  170. </pre></code>
  171. <p>Here is the output of javap when that is built with 1.6.9:</p>
  172. <code><pre>
  173. class C extends java.lang.Object{
  174. private int someField;
  175. C();
  176. public static int ajc$get$someField(C);
  177. public static void ajc$set$someField(C, int);
  178. }
  179. </pre></code>
  180. <p>The name 'someField' is preserved. The visibility is also preserved but because of that we also need to generate some accessors
  181. to get at the field.</p>
  182. <h3>AspectJ snapshots in a maven repo</h3>
  183. <p>To ease how AspectJ development builds can be consumed, they are now placed into a maven repo. When a new version of AspectJ
  184. is put into AJDT it is also put into the maven.springframework.org repo.
  185. The maven compatible repo is <code>maven.springframework.org/snapshot/org/aspectj</code> - and if you browse to it you will
  186. see it currently contains 1.6.9 dev builds under the name 1.6.9.BUILD-SNAPSHOT.
  187. The repo is added with this magic:</p>
  188. <code><pre>
  189. &lt;repository&gt;
  190. &lt;id&gt;maven.springframework.org&lt;/id&gt;
  191. &lt;name&gt;SpringSource snapshots&lt;/name&gt;
  192. &lt;url&gt;http://maven.springframework.org/snapshot&lt;/url&gt;
  193. &lt;/repository&gt;
  194. </pre></code>
  195. <p>
  196. and then the version to depend upon is:
  197. 1.6.9.BUILD-SNAPSHOT</p>
  198. <hr>
  199. <h4>
  200. <!-- ============================== -->
  201. </body>
  202. </html>