123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- = AspectJ 1.9.0
- :doctype: book
- :leveloffset: +1
-
- = AspectJ 1.9.0
-
- _© Copyright 2018 Contributors. All rights reserved._
-
- The full list of resolved issues in 1.9.0 is available
- 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]
-
- _Release info: 1.9.0 available 2-Apr-2018_
-
- == Improved runtime interface
-
- New factory methods have been added to the AspectJ runtime. This is an
- attempt to more optimally create `thisJoinPoint` and
- `thisEnclosingJoinPoint` objects. The generated code that invokes these
- now also uses the ability for the `LDC` bytecode instruction to load class
- constants directly (this replaces what was happening previously where
- generated code referenced string class names and class-loading was being
- done from the AspectJ runtime as the woven application was starting).
-
- This is turned on by using `-Xajruntimetarget:1.9`. This option was used
- previously to enable users to target an old runtime if they knew that
- old runtime is all that was available at some deployed target. The new
- generation mechanism is not the default, not until it has had a bit more
- testing out in the wild.
-
- The changes to generated code have a couple of potential side effects:
-
- * *overall size*: the woven code may be smaller due to the use of
- smaller string constant pieces in the generated code (previously strings
- were smashed together in the generated code and then taken apart by
- AspectJ at runtime). Since the pieces are smaller, they can be shared
- across other uses in the class file.
- * *method size*: although the overall class may be smaller there are
- more instructions involved in preparing the data for invocation of the
- new joinpoint factory methods. It is possible if you have a lot of
- joinpoints that we might blow the 64k instruction limit for the
- `ajc$preClinit` method (where the factory invocation code is generated).
- Please provide feedback if this happens to you!
-
- In anticipation of not all build plugins supporting that
- `-Xajruntimetarget` option, you can now specify these kinds of option in
- the `ASPECTJ_OPTS` environment variable. Set that in your environment:
-
- [source, text]
- ....
- export ASPECTJ_OPTS="-Xajruntimetarget:1.9"
- ....
-
- And it should get picked up by AspectJ when it runs.
-
- = AspectJ 1.9.0.RC4
-
- _Release info: 1.9.0.RC4 available 21-Feb-2018_
-
- Primary changes in RC4 are to add support for `<compilerArg>` in the Ant
- task. This enables users of the Ant task to pass in options supported by
- the underlying AspectJ but not yet surfaced elsewhere. Particularly
- useful with Java9 which includes a number of module related commands.
- For example, here is an `iajc` usage with `compilerArg` that is passing
- `--add-modules java.xml.bind`:
-
- [source, xml]
- ....
- <iajc destdir="bin" failonerror="true"
- showWeaveInfo="true" source="1.9" target="1.9"
- debug="true" fork="true" maxmem="256m">
-
- <compilerArg value="--add-modules"/>
- <compilerArg value="java.xml.bind"/>
- <src path="src" />
- <classpath>
- <pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
- </classpath>
-
- </iajc>
- ....
-
- = AspectJ 1.9.0.RC3
-
- _Release info: 1.9.0.RC3 available 5-Feb-2018_
-
- Primary changes in RC3 are to upgrade JDT and pickup all the fixes for
- Java9 that have gone into it over the last few months.
-
- = AspectJ 1.9.0.RC2
-
- _Release info: 1.9.0.RC2 available 9-Nov-2017_
-
- Key change in 1.9.0.RC2 is actually to be more tolerant of JDK10. The
- version handling has been somewhat overhauled so AspectJ 9 will behave
- better on Java 10 and future JDKs. This should put AspectJ in a better
- place if new JDK versions are going to arrive thick and fast.
-
- = AspectJ 1.9.0.RC1
-
- _Release info: 1.9.0.RC1 available 20-Oct-2017_
-
- This is the first release candidate of AspectJ 1.9.0 - the version of
- AspectJ to be based on Java9. It includes a recent version of the
- Eclipse Java9 compiler (from jdt core, commit #062ac5d7a6bf9).
-
- == Automatic Modules
-
- AspectJ can now be used with the new module system available in Java9.
- The key jars in AspectJ have been given automatic module names. The
- automatic module name is `org.aspectj.runtime` for the `aspectjrt` module:
-
- [source, text]
- ....
- $ java --module-path <pathto>/lib/aspectjrt.jar --list-modules | grep aspectj
-
- org.aspectj.runtime file:///<pathto>/lib/aspectjrt.jar automatic
- ....
-
- And similarly `org.aspectj.weaver` and `org.aspectj.tools` for `aspectjweaver`
- and `aspectjtools`, respectively:
-
- [source, text]
- ....
- $ java --module-path <pathto>/lib/aspectjweaver.jar --describe-module org.aspectj.weaver
-
- org.aspectj.weaver file:///<pathto>/lib/aspectjweaver.jar automatic
- requires java.base mandated
- contains aj.org.objectweb.asm
- contains aj.org.objectweb.asm.signature
- contains org.aspectj.apache.bcel
- contains org.aspectj.apache.bcel.classfile
- contains org.aspectj.apache.bcel.classfile.annotation
- contains org.aspectj.apache.bcel.generic
- contains org.aspectj.apache.bcel.util
- contains org.aspectj.asm
- contains org.aspectj.asm.internal
- ...
- ....
-
- == Building woven modules
-
- AspectJ understands `module-info.java` source files and building modules
- that include aspects. Here is an example:
-
- [source, java]
- ....
- // module-info.java
-
- module demo {
- exports pkg;
- requires org.aspectj.runtime;
- }
-
- // pkg/Demo.java
-
- package pkg;
-
- public class Demo {
- public static void main(String[] argv) {
- System.out.println("Demo running");
- }
- }
-
- // otherpkg/Azpect.java
-
- package otherpkg;
-
- public aspect Azpect {
- before(): execution(* *(..)) && !within(Azpect) {
- System.out.println("Azpect running");
- }
- }
- ....
-
- We can now build those into a module:
-
- [source, text]
- ....
- $ ajc -1.9 module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
-
- ...
- module-info.java:3 [error] org.aspectj.runtime cannot be resolved to a module
- ...
- ....
-
- Wait, that failed! Yes, `aspectjrt.jar` (which includes the required
- `org.aspectj.weaver` module) wasn't supplied. We need to pass it on the
- module-path:
-
- [source, text]
- ....
- $ ajc -1.9 --module-path <pathto>/aspectjrt.jar module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar
- ....
-
- Now we have a demo module we can run:
-
- [source, text]
- ....
- $ java --module-path <pathto>/aspectjrt.jar:demo.jar --module demo/pkg.Demo
-
- Azpect running
- Demo running
- ....
-
- That's it!
-
- == Binary weaving with modules
-
- A module is really just a jar with a _module-info_ descriptor. As such, you
- can simply pass a module on the _inpath_ and binary-weave it with other
- aspects. Take the module we built above, let's weave into it again:
-
- [source, java]
- ....
- // extra/AnotherAzpect.java
-
- package extra;
-
- public aspect AnotherAzpect {
- before(): execution(* *(..)) && !within(*Azpect) {
- System.out.println("AnotherAzpect running");
- }
- }
- ....
-
- [source, text]
- ....
- $ ajc -inpath demo.jar AnotherAzpect.java -outjar newdemo.jar
- ....
-
- Notice how there was no complaint here that the `org.aspectj.runtime`
- module hadn't been passed in. That is because inpath was being used
- which doesn't treat specified jars as modules (and so does not check
- dependencies). There is no _module-inpath_ right now.
-
- Because the new JAR produced includes the compiled aspect, the
- _module-info_ specification inside is still correct, so we can run it
- exactly as before:
-
- [source, text]
- ....
- $ java --module-path ~/installs/aspectj190rc1/lib/aspectjrt.jar:newdemo.jar --module demo/pkg.Demo
-
- Azpect running
- AnotherAzpect running
- Demo running
- ....
-
- == Faster Spring AOP
-
- Dave Syer recently created a https://github.com/dsyer/spring-boot-aspectj[series of benchmarks] for checking the speed
- of Spring-AspectJ.
-
- Here we can see the numbers for AspectJ 1.8.11 (on an older Macbook
- Pro):
-
- [source, text]
- ....
- Benchmark (scale) Mode Cnt Score Error Units
- StartupBenchmark.ltw N/A avgt 10 2.553 ~ 0.030 s/op
- StartupBenchmark.ltw_100 N/A avgt 10 2.608 ~ 0.046 s/op
- StartupBenchmark.spring v0_10 avgt 10 2.120 ~ 0.148 s/op
- StartupBenchmark.spring v1_10 avgt 10 2.219 ~ 0.066 s/op
- StartupBenchmark.spring v1_100 avgt 10 2.244 ~ 0.030 s/op
- StartupBenchmark.spring v10_50 avgt 10 2.950 ~ 0.026 s/op
- StartupBenchmark.spring v20_50 avgt 10 3.854 ~ 0.090 s/op
- StartupBenchmark.spring v20_100 avgt 10 4.003 ~ 0.038 s/op
- StartupBenchmark.spring a0_10 avgt 10 2.067 ~ 0.019 s/op
- StartupBenchmark.spring a1_10 avgt 10 2.724 ~ 0.023 s/op
- StartupBenchmark.spring a1_100 avgt 10 2.778 ~ 0.057 s/op
- StartupBenchmark.spring a10_50 avgt 10 7.191 ~ 0.134 s/op
- StartupBenchmark.spring a10_100 avgt 10 7.191 ~ 0.168 s/op
- StartupBenchmark.spring a20_50 avgt 10 11.541 ~ 0.158 s/op
- StartupBenchmark.spring a20_100 avgt 10 11.464 ~ 0.157 s/op
- ....
-
- So this is the average startup of an app affected by aspects applying to
- the beans involved. Where numbers are referenced the first is the number
- of aspects/pointcuts and the second is the number of beans. The 'a'
- indicates an annotation based pointcut vs a non-annotation based
- pointcut ('v'). Notice things are much worse for annotation based
- pointcuts. At 20 pointcuts and 50 beans the app is 9 seconds slower to
- startup. +
-
- In AspectJ 1.8.12 and 1.9.0.RC1 some work has been done here. The key
- change is to recognize that the use of annotations with runtime
- retention is much more likely than annotations with class level
- retention. Retrieving annotations with class retention is costly because
- we must open the bytes for the class file and dig around in there (vs
- runtime retention which are immediately accessible by reflection on the
- types). In 1.8.11 the actual type of the annotation involved in the
- matching is ignored and the code will fetch *all* the annotations on the
- type/method/field being matched against. So even if the match is looking
- for a runtime retention annotation, we were doing the costly thing of
- fetching any class retention annotations. In 1.8.12/1.9.0.RC1 we take
- the type of the match annotation into account - allowing us to skip
- opening the classfiles in many cases. There is also some deeper work on
- activating caches that were not previously being used correctly but the
- primary change is factoring in the annotation type.
-
- What difference does that make? AspectJ 1.9.0.RC1:
-
- [source, text]
- ....
- Benchmark (scale) Mode Cnt Score Error Units
- StartupBenchmark.ltw N/A avgt 10 2.568 ~ 0.035 s/op
- StartupBenchmark.ltw_100 N/A avgt 10 2.622 ~ 0.075 s/op
- StartupBenchmark.spring v0_10 avgt 10 2.096 ~ 0.054 s/op
- StartupBenchmark.spring v1_10 avgt 10 2.206 ~ 0.031 s/op
- StartupBenchmark.spring v1_100 avgt 10 2.252 ~ 0.025 s/op
- StartupBenchmark.spring v10_50 avgt 10 2.979 ~ 0.071 s/op
- StartupBenchmark.spring v20_50 avgt 10 3.851 ~ 0.058 s/op
- StartupBenchmark.spring v20_100 avgt 10 4.000 ~ 0.046 s/op
- StartupBenchmark.spring a0_10 avgt 10 2.071 ~ 0.026 s/op
- StartupBenchmark.spring a1_10 avgt 10 2.182 ~ 0.032 s/op
- StartupBenchmark.spring a1_100 avgt 10 2.272 ~ 0.024 s/op
- StartupBenchmark.spring a10_50 avgt 10 2.557 ~ 0.027 s/op
- StartupBenchmark.spring a10_100 avgt 10 2.598 ~ 0.040 s/op
- StartupBenchmark.spring a20_50 avgt 10 2.961 ~ 0.043 s/op
- StartupBenchmark.spring a20_100 avgt 10 3.093 ~ 0.098 s/op
- ....
-
- Look at the a20_100 case - instead of impacting start time by 9 seconds,
- it impacts it by 1 second.
-
- == More to come...
-
- * Eclipse JDT Java 9 support is still being actively worked on and lots
- of fixes will be coming through over the next few months and included in
- AspectJ 1.9.X revisions.
-
- * AspectJ does not currently modify `module-info.java` files. An aspect
- from one module applying to code in another module clearly introduces a
- dependency between those two modules. There is no reason - other than
- time! - that this can't be done.
- (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526244[Issue 526244])
-
- * Related to that AspectJ, on detection of aspects should be able to
- automatically introduce the `requires org.aspectj.runtime` to the
- _module-info_. (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526242[Issue
- 526242])
-
- * Module-aware variants of AspectJ paths: `--module-inpath`,
- `--module-aspectpath`.
- (https://bugs.eclipse.org/bugs/show_bug.cgi?id=526243[Issue 526243])
|