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.9.0.adoc 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. = AspectJ 1.9.0
  2. :doctype: book
  3. :leveloffset: +1
  4. = AspectJ 1.9.0
  5. _© Copyright 2018 Contributors. All rights reserved._
  6. The full list of resolved issues in 1.9.0 is available
  7. https://bugs.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&f0=OP&f1=OP&f3=CP&f4=CP&j1=OR&list_id=16866879&product=AspectJ&query_format=advanced&target_milestone=1.9.0[here]
  8. _Release info: 1.9.0 available 2-Apr-2018_
  9. == Improved runtime interface
  10. New factory methods have been added to the AspectJ runtime. This is an
  11. attempt to more optimally create `thisJoinPoint` and
  12. `thisEnclosingJoinPoint` objects. The generated code that invokes these
  13. now also uses the ability for the `LDC` bytecode instruction to load class
  14. constants directly (this replaces what was happening previously where
  15. generated code referenced string class names and class-loading was being
  16. done from the AspectJ runtime as the woven application was starting).
  17. This is turned on by using `-Xajruntimetarget:1.9`. This option was used
  18. previously to enable users to target an old runtime if they knew that
  19. old runtime is all that was available at some deployed target. The new
  20. generation mechanism is not the default, not until it has had a bit more
  21. testing out in the wild.
  22. The changes to generated code have a couple of potential side effects:
  23. * *overall size*: the woven code may be smaller due to the use of
  24. smaller string constant pieces in the generated code (previously strings
  25. were smashed together in the generated code and then taken apart by
  26. AspectJ at runtime). Since the pieces are smaller, they can be shared
  27. across other uses in the class file.
  28. * *method size*: although the overall class may be smaller there are
  29. more instructions involved in preparing the data for invocation of the
  30. new joinpoint factory methods. It is possible if you have a lot of
  31. joinpoints that we might blow the 64k instruction limit for the
  32. `ajc$preClinit` method (where the factory invocation code is generated).
  33. Please provide feedback if this happens to you!
  34. In anticipation of not all build plugins supporting that
  35. `-Xajruntimetarget` option, you can now specify these kinds of option in
  36. the `ASPECTJ_OPTS` environment variable. Set that in your environment:
  37. [source, text]
  38. ....
  39. export ASPECTJ_OPTS="-Xajruntimetarget:1.9"
  40. ....
  41. And it should get picked up by AspectJ when it runs.
  42. = AspectJ 1.9.0.RC4
  43. _Release info: 1.9.0.RC4 available 21-Feb-2018_
  44. Primary changes in RC4 are to add support for `<compilerArg>` in the Ant
  45. task. This enables users of the Ant task to pass in options supported by
  46. the underlying AspectJ but not yet surfaced elsewhere. Particularly
  47. useful with Java9 which includes a number of module related commands.
  48. For example, here is an `iajc` usage with `compilerArg` that is passing
  49. `--add-modules java.xml.bind`:
  50. [source, xml]
  51. ....
  52. <iajc destdir="bin" failonerror="true"
  53. showWeaveInfo="true" source="1.9" target="1.9"
  54. debug="true" fork="true" maxmem="256m">
  55. <compilerArg value="--add-modules"/>
  56. <compilerArg value="java.xml.bind"/>
  57. <src path="src" />
  58. <classpath>
  59. <pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
  60. </classpath>
  61. </iajc>
  62. ....
  63. = AspectJ 1.9.0.RC3
  64. _Release info: 1.9.0.RC3 available 5-Feb-2018_
  65. Primary changes in RC3 are to upgrade JDT and pickup all the fixes for
  66. Java9 that have gone into it over the last few months.
  67. = AspectJ 1.9.0.RC2
  68. _Release info: 1.9.0.RC2 available 9-Nov-2017_
  69. Key change in 1.9.0.RC2 is actually to be more tolerant of JDK10. The
  70. version handling has been somewhat overhauled so AspectJ 9 will behave
  71. better on Java 10 and future JDKs. This should put AspectJ in a better
  72. place if new JDK versions are going to arrive thick and fast.
  73. = AspectJ 1.9.0.RC1
  74. _Release info: 1.9.0.RC1 available 20-Oct-2017_
  75. This is the first release candidate of AspectJ 1.9.0 - the version of
  76. AspectJ to be based on Java9. It includes a recent version of the
  77. Eclipse Java9 compiler (from jdt core, commit #062ac5d7a6bf9).
  78. == Automatic Modules
  79. AspectJ can now be used with the new module system available in Java9.
  80. The key jars in AspectJ have been given automatic module names. The
  81. automatic module name is `org.aspectj.runtime` for the `aspectjrt` module:
  82. [source, text]
  83. ....
  84. $ java --module-path <pathto>/lib/aspectjrt.jar --list-modules | grep aspectj
  85. org.aspectj.runtime file:///<pathto>/lib/aspectjrt.jar automatic
  86. ....
  87. And similarly `org.aspectj.weaver` and `org.aspectj.tools` for `aspectjweaver`
  88. and `aspectjtools`, respectively:
  89. [source, text]
  90. ....
  91. $ java --module-path <pathto>/lib/aspectjweaver.jar --describe-module org.aspectj.weaver
  92. org.aspectj.weaver file:///<pathto>/lib/aspectjweaver.jar automatic
  93. requires java.base mandated
  94. contains aj.org.objectweb.asm
  95. contains aj.org.objectweb.asm.signature
  96. contains org.aspectj.apache.bcel
  97. contains org.aspectj.apache.bcel.classfile
  98. contains org.aspectj.apache.bcel.classfile.annotation
  99. contains org.aspectj.apache.bcel.generic
  100. contains org.aspectj.apache.bcel.util
  101. contains org.aspectj.asm
  102. contains org.aspectj.asm.internal
  103. ...
  104. ....
  105. == Building woven modules
  106. AspectJ understands `module-info.java` source files and building modules
  107. that include aspects. Here is an example:
  108. [source, java]
  109. ....
  110. // module-info.java
  111. module demo {
  112. exports pkg;
  113. requires org.aspectj.runtime;
  114. }
  115. // pkg/Demo.java
  116. package pkg;
  117. public class Demo {
  118. public static void main(String[] argv) {
  119. System.out.println("Demo running");
  120. }
  121. }
  122. // otherpkg/Azpect.java
  123. package otherpkg;
  124. public aspect Azpect {
  125. before(): execution(* *(..)) && !within(Azpect) {
  126. System.out.println("Azpect running");
  127. }
  128. }
  129. ....
  130. We can now build those into a module:
  131. [source, text]
  132. ....
  133. $ ajc -1.9 module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
  134. ...
  135. module-info.java:3 [error] org.aspectj.runtime cannot be resolved to a module
  136. ...
  137. ....
  138. Wait, that failed! Yes, `aspectjrt.jar` (which includes the required
  139. `org.aspectj.weaver` module) wasn't supplied. We need to pass it on the
  140. module-path:
  141. [source, text]
  142. ....
  143. $ ajc -1.9 --module-path <pathto>/aspectjrt.jar module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
  144. ....
  145. Now we have a demo module we can run:
  146. [source, text]
  147. ....
  148. $ java --module-path <pathto>/aspectjrt.jar:demo.jar --module demo/pkg.Demo
  149. Azpect running
  150. Demo running
  151. ....
  152. That's it!
  153. == Binary weaving with modules
  154. A module is really just a jar with a _module-info_ descriptor. As such, you
  155. can simply pass a module on the _inpath_ and binary-weave it with other
  156. aspects. Take the module we built above, let's weave into it again:
  157. [source, java]
  158. ....
  159. // extra/AnotherAzpect.java
  160. package extra;
  161. public aspect AnotherAzpect {
  162. before(): execution(* *(..)) && !within(*Azpect) {
  163. System.out.println("AnotherAzpect running");
  164. }
  165. }
  166. ....
  167. [source, text]
  168. ....
  169. $ ajc -inpath demo.jar AnotherAzpect.java -outjar newdemo.jar
  170. ....
  171. Notice how there was no complaint here that the `org.aspectj.runtime`
  172. module hadn't been passed in. That is because inpath was being used
  173. which doesn't treat specified jars as modules (and so does not check
  174. dependencies). There is no _module-inpath_ right now.
  175. Because the new JAR produced includes the compiled aspect, the
  176. _module-info_ specification inside is still correct, so we can run it
  177. exactly as before:
  178. [source, text]
  179. ....
  180. $ java --module-path ~/installs/aspectj190rc1/lib/aspectjrt.jar:newdemo.jar --module demo/pkg.Demo
  181. Azpect running
  182. AnotherAzpect running
  183. Demo running
  184. ....
  185. == Faster Spring AOP
  186. Dave Syer recently created a https://github.com/dsyer/spring-boot-aspectj[series of benchmarks] for checking the speed
  187. of Spring-AspectJ.
  188. Here we can see the numbers for AspectJ 1.8.11 (on an older Macbook
  189. Pro):
  190. [source, text]
  191. ....
  192. Benchmark (scale) Mode Cnt Score Error Units
  193. StartupBenchmark.ltw N/A avgt 10 2.553 ~ 0.030 s/op
  194. StartupBenchmark.ltw_100 N/A avgt 10 2.608 ~ 0.046 s/op
  195. StartupBenchmark.spring v0_10 avgt 10 2.120 ~ 0.148 s/op
  196. StartupBenchmark.spring v1_10 avgt 10 2.219 ~ 0.066 s/op
  197. StartupBenchmark.spring v1_100 avgt 10 2.244 ~ 0.030 s/op
  198. StartupBenchmark.spring v10_50 avgt 10 2.950 ~ 0.026 s/op
  199. StartupBenchmark.spring v20_50 avgt 10 3.854 ~ 0.090 s/op
  200. StartupBenchmark.spring v20_100 avgt 10 4.003 ~ 0.038 s/op
  201. StartupBenchmark.spring a0_10 avgt 10 2.067 ~ 0.019 s/op
  202. StartupBenchmark.spring a1_10 avgt 10 2.724 ~ 0.023 s/op
  203. StartupBenchmark.spring a1_100 avgt 10 2.778 ~ 0.057 s/op
  204. StartupBenchmark.spring a10_50 avgt 10 7.191 ~ 0.134 s/op
  205. StartupBenchmark.spring a10_100 avgt 10 7.191 ~ 0.168 s/op
  206. StartupBenchmark.spring a20_50 avgt 10 11.541 ~ 0.158 s/op
  207. StartupBenchmark.spring a20_100 avgt 10 11.464 ~ 0.157 s/op
  208. ....
  209. So this is the average startup of an app affected by aspects applying to
  210. the beans involved. Where numbers are referenced the first is the number
  211. of aspects/pointcuts and the second is the number of beans. The 'a'
  212. indicates an annotation based pointcut vs a non-annotation based
  213. pointcut ('v'). Notice things are much worse for annotation based
  214. pointcuts. At 20 pointcuts and 50 beans the app is 9 seconds slower to
  215. startup. +
  216. In AspectJ 1.8.12 and 1.9.0.RC1 some work has been done here. The key
  217. change is to recognize that the use of annotations with runtime
  218. retention is much more likely than annotations with class level
  219. retention. Retrieving annotations with class retention is costly because
  220. we must open the bytes for the class file and dig around in there (vs
  221. runtime retention which are immediately accessible by reflection on the
  222. types). In 1.8.11 the actual type of the annotation involved in the
  223. matching is ignored and the code will fetch *all* the annotations on the
  224. type/method/field being matched against. So even if the match is looking
  225. for a runtime retention annotation, we were doing the costly thing of
  226. fetching any class retention annotations. In 1.8.12/1.9.0.RC1 we take
  227. the type of the match annotation into account - allowing us to skip
  228. opening the classfiles in many cases. There is also some deeper work on
  229. activating caches that were not previously being used correctly but the
  230. primary change is factoring in the annotation type.
  231. What difference does that make? AspectJ 1.9.0.RC1:
  232. [source, text]
  233. ....
  234. Benchmark (scale) Mode Cnt Score Error Units
  235. StartupBenchmark.ltw N/A avgt 10 2.568 ~ 0.035 s/op
  236. StartupBenchmark.ltw_100 N/A avgt 10 2.622 ~ 0.075 s/op
  237. StartupBenchmark.spring v0_10 avgt 10 2.096 ~ 0.054 s/op
  238. StartupBenchmark.spring v1_10 avgt 10 2.206 ~ 0.031 s/op
  239. StartupBenchmark.spring v1_100 avgt 10 2.252 ~ 0.025 s/op
  240. StartupBenchmark.spring v10_50 avgt 10 2.979 ~ 0.071 s/op
  241. StartupBenchmark.spring v20_50 avgt 10 3.851 ~ 0.058 s/op
  242. StartupBenchmark.spring v20_100 avgt 10 4.000 ~ 0.046 s/op
  243. StartupBenchmark.spring a0_10 avgt 10 2.071 ~ 0.026 s/op
  244. StartupBenchmark.spring a1_10 avgt 10 2.182 ~ 0.032 s/op
  245. StartupBenchmark.spring a1_100 avgt 10 2.272 ~ 0.024 s/op
  246. StartupBenchmark.spring a10_50 avgt 10 2.557 ~ 0.027 s/op
  247. StartupBenchmark.spring a10_100 avgt 10 2.598 ~ 0.040 s/op
  248. StartupBenchmark.spring a20_50 avgt 10 2.961 ~ 0.043 s/op
  249. StartupBenchmark.spring a20_100 avgt 10 3.093 ~ 0.098 s/op
  250. ....
  251. Look at the a20_100 case - instead of impacting start time by 9 seconds,
  252. it impacts it by 1 second.
  253. == More to come...
  254. * Eclipse JDT Java 9 support is still being actively worked on and lots
  255. of fixes will be coming through over the next few months and included in
  256. AspectJ 1.9.X revisions.
  257. * AspectJ does not currently modify `module-info.java` files. An aspect
  258. from one module applying to code in another module clearly introduces a
  259. dependency between those two modules. There is no reason - other than
  260. time! - that this can't be done.
  261. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526244[Issue 526244])
  262. * Related to that AspectJ, on detection of aspects should be able to
  263. automatically introduce the `requires org.aspectj.runtime` to the
  264. _module-info_. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526242[Issue
  265. 526242])
  266. * Module-aware variants of AspectJ paths: `--module-inpath`,
  267. `--module-aspectpath`.
  268. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526243[Issue 526243])