aboutsummaryrefslogtreecommitdiffstats
path: root/docs/dist/doc/README-190.html
blob: e90042f6f9106085a90c1bc3ceca97df5c2e8070 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html> <head>
<title>AspectJ 1.9.0.RC3 Readme</title>
<style type="text/css">
<!--
  P   { margin-left:  20px; }
  PRE { margin-left:  20px; }
  LI  { margin-left:  20px; }
  H4  { margin-left:  20px; }
  H3  { margin-left:  10px; }
-->
</style>
</head>

<body>
<div align="right"><small>
&copy; Copyright 2018 Contributors.
All rights reserved.
</small></div>
<h1>AspectJ 1.9.0.RC3 Readme</h1>

<p>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.</p>

<li>1.9.0.RC3 available 5-Feb-2018</li>

<h1>AspectJ 1.9.0.RC2 Readme</h1>

<p>The full list of resolved issues in 1.9.0 is available 
<a href="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</a></h2>.</p>

<ul>
<li>1.9.0.RC2 available 9-Nov-2017
</ul>

<h3>1.9.0.RC2 changes</h3>

<p>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.

<ul>
<li>1.9.0.RC1 available 20-Oct-2017
</ul>

<h3>1.9.0.RC1 changes</h3>

<p>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).</p>


<h4>Automatic Modules</h4>
<p>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 <tt>org.aspectj.runtime</tt> for the <tt>aspectjrt</tt> module:</p>
<pre><code>
$ java --module-path &lt;pathto&gt;/lib/aspectjrt.jar --list-modules | grep aspectj

org.aspectj.runtime file:///&lt;pathto&gt;/lib/aspectjrt.jar automatic

</code></pre>

<p>And similarly <tt>org.aspectj.weaver</tt> and <tt>org.aspectj.tools</tt> for <tt>aspectjweaver</tt> and <tt>aspectjtools</tt> respectively:</p>

<pre><code>
$ java --module-path &lt;pathto&gt;/lib/aspectjweaver.jar --describe-module org.aspectj.weaver

org.aspectj.weaver file:///&lt;pathto&gt;/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
...
</code></pre>
</p>
<br><br>
<h4>Building woven modules</h4>
<p>AspectJ understands module-info.java source files and building modules that include aspects. Here is an example:</p>

<pre><code>
<b>module-info.java</b>

module demo {
	exports pkg;
	requires org.aspectj.runtime;
}


<b>pkg/Demo.java</b>

package pkg;

public class Demo {
	public static void main(String[] argv) {
		System.out.println("Demo running");
	}
}


<b>otherpkg/Azpect.java</b>

package otherpkg;

public aspect Azpect {
	before(): execution(* *(..)) && !within(Azpect) {
		System.out.println("Azpect running");
	}
}

</code></pre>

<p>We can now build those into a module:</p>

<pre><code>
$ 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
...
</code></pre>

<p>Wait, that failed!  Yes, <tt>aspectjrt.jar</tt> (which includes the required <tt>org.aspectj.weaver</tt> module) wasn't supplied.
We need to pass it on the module-path:</p>

<pre><code>
$ ajc -1.9 --module-path &lt;pathto&gt;/aspectjrt.jar module-info.java otherpkg/Azpect.java pkg/Demo.java -outjar demo.jar

</code></pre>

<p>Now we have a demo module we can run:</p>

<pre><code>
$ java --module-path &lt;pathto&gt;/aspectjrt.jar:demo.jar --module demo/pkg.Demo

Azpect running
Demo running
</code></pre>

<p>That's it!</p>

<br><br>

<h4>Binary weaving with modules</h4>

<p>A module is really just a jar with a module-info descriptor. As such you can simply pass a module on the <tt>inpath</tt>
and binary weave it with other aspects.  Take the module we built above, let's weave into it again:</p>

<pre><code>extra/AnotherAzpect.java

package extra;

public aspect AnotherAzpect {
	before(): execution(* *(..)) && !within(*Azpect) {
		System.out.println("AnotherAzpect running");
	}
}
</code></pre>

<pre><code>
$ ajc -inpath demo.jar AnotherAzpect.java -outjar newdemo.jar</code></pre>

<p>Notice how there was no complaint here that the <tt>org.aspectj.runtime</tt> module hadn't been passed in. That is because <tt>inpath</tt>
was being used which doesn't treat specified jars as modules (and so does not check dependencies). There is no <tt>module-inpath</tt> right now.

<p>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:</p>

<pre><code>$ java --module-path ~/installs/aspectj190rc1/lib/aspectjrt.jar:newdemo.jar --module demo/pkg.Demo

Azpect running
AnotherAzpect running
Demo running
</code></pre>
<br><br>

<h4>Faster Spring AOP</h4>
<p>Dave Syer recently created a series of benchmarks for checking the speed of Spring-AspectJ: 
<tt><a href="https://github.com/dsyer/spring-boot-aspectj">https://github.com/dsyer/spring-boot-aspectj</a></tt>

<p>Here we can see the numbers for AspectJ 1.8.11 (on an older Macbook Pro):

<pre><code>
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
</code></pre>

<p>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.
<br>

<p>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.

<p>What difference does that make?

AspectJ 1.9.0.RC1:
<pre><code>
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
</code></pre>

<p>Look at the a20_100 case - instead of impacting start time by 9 seconds, it impacts it by 1 second.

<h3>More to come...</h3>

<ul>
<li><p>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.</p>

<li><p>AspectJ does not currently modify <tt>module-info.java</tt> 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. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526244">Issue 526244</a>)</p>

<li><p>Related to that AspectJ, on detection of aspects should be able to automatically introduce the <tt>requires org.aspectj.runtime</tt> to
the <tt>module-info</tt>. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526242">Issue 526242</a>)</p>

<li><p>Module aware variants of AspectJ paths: <tt>--module-inpath</tt>, <tt>--module-aspectpath</tt>. (<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=526243">Issue 526243</a>)</p>
</ul>

<!-- ============================== -->  
</body>
</html>