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-1.6.9.adoc 11KB

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