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.2.adoc 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. = AspectJ 1.2
  2. _© Copyright 2003,2004 Contributors. All rights reserved._
  3. The definition of the AspectJ language is unchanged in the 1.2 release.
  4. Instead, AspectJ 1.2 provides major improvements to the functionality of
  5. the supporting tools and enforces some language limits that went
  6. unchecked before. This document describes the tools differences between
  7. AspectJ versions 1.2 and 1.1.1. Users new to AspectJ need only read the
  8. link:progguide/index.html[AspectJ Programming Guide] since it describes
  9. the 1.2 language. Users familiar with AspectJ 1.1 may find this document
  10. a quicker way to learn what changed in the tools, and should use it as a
  11. guide for porting programs from 1.1 to 1.2, together with porting.html.
  12. This document first summarizes changes from the 1.1.1 release in
  13. * xref:#compiler[the compiler],
  14. * xref:#tools[the support tools],
  15. * xref:#runtime[the runtime],
  16. * xref:#devenv[the development environment support],
  17. then xref:#details[details] some of the changes, and finally points
  18. readers to the bug database for xref:#allchanges[all the changes].
  19. '''''
  20. [[compiler]]
  21. == The Compiler
  22. Compared to AspectJ 1.1.1, the AspectJ 1.2 compiler...
  23. * xref:#WEAVE_TIME[Is faster], with weaving completing in less than half
  24. the time it used to take in many cases.
  25. [[WEAVE_CHART]]image:images/AspectJ11v12.JPG[image].
  26. * Supports the xref:#LAZY_TJP[-XlazyTjp option] which produces code that
  27. runs faster and uses less memory in some common cases.
  28. * Has xref:#INCREMENTAL[much better support for incremental
  29. compilation].
  30. * Produces xref:#ERROR_MESSAGES[better error messages].
  31. * Has some xref:#LINT[new lint warnings] to catch common mistakes and
  32. changes to serializability.
  33. * Supports the xref:#REWEAVABLE[-Xreweavable option] that allows classes
  34. to be woven more than once.
  35. * {blank}
  36. * Supports the xref:#INPATH[-inpath option] which allows both
  37. directories and jars containing class files to be specified as input to
  38. the weaver.
  39. * xref:#COMPLIANCE[Changes the default compiler compliance mode] from
  40. -1.3 to -1.4.
  41. A short description of the options ajc accepts is available with
  42. "`ajc -help`". Longer descriptions are available in the
  43. link:devguide/ajc-ref.html[Development Environment Guide section on
  44. ajc].
  45. '''''
  46. [[tools]]
  47. == Support Tools
  48. AspectJ 1.2 contains two important changes to the supporting tools:
  49. * xref:#AJDOC[ajdoc] is back
  50. * A sample script is supplied for xref:#LTW[load-time weaving] from the
  51. command-line.
  52. '''''
  53. [[runtime]]
  54. == The Runtime Library
  55. This release has minor updates to the runtime library classes. As with
  56. any release, you should compile and run with the runtime library that
  57. came with your compiler, and you may run with a later version of the
  58. library without recompiling your code.
  59. * xref:#SOFTEX[`SoftException`] now supports `getCause()`.
  60. * Although not part of `aspectjrt.jar` this release also provides a new
  61. set of tools APIs in the xref:#LTW2[`org.aspectj.weaver.tools`] that
  62. provide a weaving class loader and an adapter that can be used to
  63. integrate load-time weaving into an existing class loader hierarchy.
  64. * Cflow stack management has been modified to use thread local storage
  65. on JVMs that support this feature. This improves performance in terms of
  66. heap usage for multi-threaded applications that use cflow.
  67. '''''
  68. [[devenv]]
  69. == The AJDE Tools
  70. The AJDE based tools for JBuilder, NetBeans and Emacs continue to be
  71. independent SourceForge projects. The AspectJ 1.2 distribution includes
  72. an updated version of the AjBrowser tool that benefits from all the
  73. enhancements made in the 1.2 compiler.
  74. The 1.2 release of AspectJ also lays a lot of the groundwork for a much
  75. better AspectJ IDE experience that we hope to surface initially through
  76. AJDT (AspectJ support for Eclipse). Amongst the many improvements, we
  77. will have full eager parsing support that avoids the need to keep the
  78. whole structure model of a project in memory, hopefully making AJDT much
  79. less memory hungry and much slicker to use. For more details see the
  80. https://www.eclipse.org/ajdt[AJDT project website].
  81. '''''
  82. [[details]]
  83. == Details of some compiler changes
  84. [[WEAVE_TIME]]
  85. === Compilation (weave) times reduced.
  86. Our benchmark suite shows that AspectJ 1.2 is at least twice as fast in
  87. the weaving phase as AspectJ 1.1.1 for matches based on a variety of
  88. pointcut expressions (see the xref:#WEAVE_CHART[chart above]). We've
  89. also made the base incremental compilation implementation in AspectJ 1.2
  90. approximately twice as fast as in AspectJ 1.1.1, so when this is
  91. combined with the weave time improvements you should see speed-ups of up
  92. to 4x for incremental compilation.
  93. In addition, AspectJ 1.2 maintains only weak references to some of its
  94. recoverable data structures, allowing the JVM to optimise between
  95. performance and memory usage. Experiments forcing GC showed that we can
  96. achieve about a 20% memory usage reduction in this manner if needed.
  97. [[LAZY_TJP]]
  98. === The -XlazyTjp option.
  99. Under AspectJ 1.1.1, if the body of an advice contained a reference to a
  100. non-statically determinable portion of `thisJoinPoint` (such as for
  101. example a call to `getArgs()`), then a JoinPoint object was always
  102. creating before entering the advice. This was the case even if the
  103. advice was guarded with an `if()` pointcut that evaluated to false.
  104. AspectJ 1.2 now supports the `-XlazyTjp` option that only creates the
  105. JoinPoint object just before dispatching to the advice body. By
  106. promoting the guard to a test in an `if()` pointcut, the creation of the
  107. JoinPoint object can be avoided altogether in the case where the test
  108. returns false.
  109. Consider a simple tracing aspect as follows:
  110. [source, java]
  111. ....
  112. public aspect Tracing {
  113. public static boolean enabled = false;
  114. pointcut toBeTraced() : execution(* *(..)) || execution(new(..));
  115. before() : toBeTraced() && if(enabled) {
  116. Object[] args = thisJoinPoint.getArgs();
  117. // format args and print out entry trace record etc....
  118. }
  119. }
  120. ....
  121. The most important consideration is the system overhead when tracing is
  122. turned off. Using the `-XlazyTjp` option makes the program above run
  123. 10-100x faster, even when running a small test case with minimal GC
  124. issues. The optimization is disabled at join points advised by around
  125. advice, and an Xlint warning will be displayed in these cases.
  126. [[INCREMENTAL]]
  127. === Improvements to incremental compilation.
  128. AspectJ 1.2 provides more complete incremental compilation support than
  129. AspectJ 1.1.1. Firstly, incremental compilation resulting from a change
  130. to a source file is now approximately twice as fast as it was under
  131. 1.1.1 (even before taking the improvements to weaving time into
  132. account). Secondly, the incremental coverage now takes into account
  133. changes to resources, classes and jars on the inpath, injars, and
  134. aspectpath. The new `inpath` option in AspectJ 1.2 allows directories to
  135. be specified in addition to jars (just like a classpath) as input to the
  136. weaver. Any update, addition or deletion of a class file in a directory
  137. on the inpath will cause incremental (re)weaving.
  138. Changes to a jar file on the inpath, injars or aspectpath will now be
  139. detected, but will trigger a full rebuild, as will any change to the
  140. paths used to control compilation.
  141. [[ERROR_MESSAGES]]
  142. === Improved error messages.
  143. AspectJ 1.1.1 did not provide source context information for messages
  144. produced during the weaving phase, even in the case where source files
  145. were passed to the compiler. For example, an error message arising as a
  146. result of a `declare error` statement might look as follows under
  147. AspectJ 1.1.1:
  148. [source, text]
  149. ....
  150. BadClass.java:6 should not be calling bad methods
  151. ....
  152. whereas in AspectJ 1.2 you will see:
  153. [source, text]
  154. ....
  155. BadClass.java:6 error should not be calling bad methods
  156. new C().bad();
  157. ^^^^^^^^^^^^^^
  158. method-call(void C.bad())
  159. see also: DeclareError.java:5
  160. ....
  161. There are four new things to note about this error message. Firstly,
  162. errors and warnings are now prefixed with the word "error", or "warning"
  163. as appropriate. Secondly, the offending line of source is shown if
  164. source code is available. Thirdly, in the case of weaver messages
  165. arising as a result of `declare error` and `declare warning` statements,
  166. AspectJ now shows not only the location of the error or warning, but
  167. also the location of the `declare` statement itself. Finally, note that
  168. messages produced as a result of `declare error` and `declare warning`
  169. statements now also display the matched join point at the location of
  170. the error:
  171. When source code is not available, the messages show the binary input
  172. source (class file or jar file) in which the error or warning was
  173. detected:
  174. [source, text]
  175. ....
  176. BadClass.java:6 error should not be calling bad methods
  177. (no source information available)
  178. method-call(void C.bad())
  179. see also: C:\...\DeclareError.java:5
  180. see also: C:\...\bin-input.jar
  181. ....
  182. This error message tells us that `BadClass.class` contained in a jar on
  183. the inpath called `bin-input.jar`, and originally compiled from a source
  184. file called `BadClass.java`, contains a join point
  185. (`method-call(void C.bad())` matched by a `declare error` statement on
  186. line 5 of the file `DeclareError.java`.
  187. [[LINT]]
  188. === New lint warnings.
  189. Consider the program:
  190. [source, java]
  191. ....
  192. /*01*/ class A {
  193. /*02*/ public void doIt() {...};
  194. /*03*/ }
  195. /*04*/
  196. /*05*/ class B extends A {
  197. /*06*/ public void doThisToo() {...};
  198. /*07*/ }
  199. /*08*/
  200. /*09*/
  201. /*10*/ public class CallsAandB {
  202. /*11*/
  203. /*12*/ public static void main(String[] args) {
  204. /*13*/ B b = new B();
  205. /*14*/ A bInDisguise = new B();
  206. /*15*/
  207. /*16*/ b.doIt(); // AspectJ 1.2 matches here
  208. /*17*/ bInDisguise.doIt(); // this is never matched
  209. /*18*/ }
  210. /*19*/
  211. /*20*/ }
  212. /*21*/
  213. /*22*/ aspect CallPCDMatchingExample {
  214. /*23*/
  215. /*24*/ before() : call(* B.doIt(..)) {
  216. /*25*/ System.out.println("About to call B.doIt(...)");
  217. /*26*/ }
  218. /*27*/
  219. /*28*/ }
  220. ....
  221. Because the static type of `bInDisguise` is `A` (line 14), the call on
  222. line 17 is never matched by the pointcut expression on 24, even though
  223. the runtime type of `bInDisguise` is `B`. Type patterns matched in
  224. `call` pointcut designators are matched based on static type matching.
  225. Some users have found this static type matching confusing, and AspectJ
  226. 1.2 has a new Xlint warning (`unmatchedSuperTypeInCall`) which is
  227. enabled by default.
  228. The compiler will now produce a warning whenever a call pointcut
  229. designator does not match at a join point, and a user may have expected
  230. it to. Compiling the above program using AspectJ 1.2 produces the
  231. following compiler output:
  232. [source, text]
  233. ....
  234. CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall]
  235. before() : call(* B.doIt(..)) {
  236. ^^^^^^^^^^^^^^^
  237. see also: CallsAandB.java:17
  238. 1 warning
  239. ....
  240. The warning is telling us that the call pointcut associated with the
  241. before advice on line 24 of the source file does not match at a join
  242. point where the user may have expected it to. The source location
  243. corresponding to the unmatched join point is indicated by the "see also"
  244. line - in this case line 17 of the source file. At line 17 we find a
  245. call to `bInDisguise.doIt()`. Since the static type of `bInDisguise` is
  246. `A`, this call will never be matched. The warning also tells us a
  247. possible solution if we intended the pointcut to match at this join
  248. point: use `call(* doIt(..) && target(B)`.
  249. If you find warnings of this kind coming out when you use the AspectJ
  250. 1.2 compiler, the recommended fix is to switch to using the `target`
  251. designator in place of a type pattern in the `call` pointcut expression.
  252. Note that there is no loss of runtime efficiency here - runtime tests
  253. are only added in the cases where it cannot be determined at compile
  254. time whether the type of the receiver will match the type specified in
  255. the `target` expression. Also note that `target` cannot be used in
  256. `declare` statements.
  257. A new Xlint warning, `needsSerialVersionUIDField` (disabled by default)
  258. will produce a warning at compile time if the process of weaving changes
  259. the default `serialVersionUID` of a serializable class, and the class
  260. does not define a `serialVersionUID`. By defining a `serialVersionUID`
  261. field, the programmer can ensure that objects serialized without the
  262. aspect present can be read by a version of the program in which the
  263. aspect is present, and vice-versa.
  264. A complimentary Xlint warning, `brokeSerialVersionCompatibility`
  265. (disabled by default) will produce a warning at compile time if the
  266. process of weaving makes an incompatible change to a serializable class
  267. (for example, through the addition of an inter-type declared field).
  268. [[REWEAVABLE]]
  269. === The -Xreweavable option.
  270. The new `-Xreweavable` option produces class files that contain enough
  271. additional information in them that they can be rewoven. In time we hope
  272. that this can become a standard option, replacing the current
  273. `-Xnoweave` option. Using reweavable produces class files that can be
  274. legally loaded by a JVM, whereas with noweave, it is too easy to produce
  275. class files that will result in a verify error at runtime. The
  276. reweavable option makes it easy to weave code many times without having
  277. to decide which weave is the final one. In a future version of the
  278. AspectJ compiler, producing reweavable class files may become the
  279. default option. The trade-off at the moment is that reweavable class
  280. files are currently approximately twice the size of their non-reweavable
  281. counterparts.
  282. To ensure consistent semantics when reweaving, the AspectJ compiler
  283. requires that all aspects that have previously modified a class file
  284. during weaving be present in the system during a reweave. An error will
  285. be issued if any are missing.
  286. [[INPATH]]
  287. === The -inpath option.
  288. The new `-inpath` option replaces the `-injars` option (which is still
  289. supported for backwards compatibility). It allows both directories and
  290. jar files to be specified using path separators to separate entries in
  291. the path. This option makes it easy for class files produced as the
  292. result of building one project to become binary input to the compilation
  293. of a second project.
  294. [[COMPLIANCE]]
  295. === The default compliance mode of the compiler has changed from -1.3 to -1.4.
  296. The default AspectJ compiler compliance level is now 1.4 (whereas in
  297. previous releases the default compliance level was 1.3). This has a
  298. number of implications:
  299. * class files generated by the compiler are now JRE v1.2 and upwards
  300. compatible. (At compliance level 1.3, AspectJ generated class files that
  301. were compatible with JRE 1.1 also).
  302. * `call` pointcuts may match more join points than in the same program
  303. compiled at compliance level 1.3.
  304. The AspectJ compiler can be restored to 1.3 compliance settings by
  305. specifying the "-1.3" option on the command-line.
  306. Consider again the following example program which illustrates the
  307. differences in join point matching with the `call` pointcut designator
  308. between 1.4 and 1.3 compliance levels.
  309. [source, java]
  310. ....
  311. /*01*/ class A {
  312. /*02*/ public void doIt() {...};
  313. /*03*/ }
  314. /*04*/
  315. /*05*/ class B extends A {
  316. /*06*/ public void doThisToo() {...};
  317. /*07*/ }
  318. /*08*/
  319. /*09*/
  320. /*10*/ public class CallsAandB {
  321. /*11*/
  322. /*12*/ public static void main(String[] args) {
  323. /*13*/ B b = new B();
  324. /*14*/ A bInDisguise = new B();
  325. /*15*/
  326. /*16*/ b.doIt(); // AspectJ 1.2 matches here
  327. /*17*/ bInDisguise.doIt(); // this is never matched
  328. /*18*/ }
  329. /*19*/
  330. /*20*/ }
  331. /*21*/
  332. /*22*/ aspect CallPCDMatchingExample {
  333. /*23*/
  334. /*24*/ before() : call(* B.doIt(..)) {
  335. /*25*/ System.out.println("About to call B.doIt(...)");
  336. /*26*/ }
  337. /*27*/
  338. /*28*/ }
  339. ....
  340. When this program is compiled with AspectJ 1.2 using the default
  341. compiler options, it will produce one line of output when it is
  342. executed:
  343. `About to call B.doIt(...)`
  344. The same program compiled under AspectJ 1.1 (or using AspectJ 1.2 with
  345. the -1.3 flag specified) does not produce any output when it is run. The
  346. reason for the additional call pcd match is that prior to compliance
  347. level 1.4, Java compilers produced bytecodes that call A.doIt() (the
  348. defining type of the method), rather than B.doIt() (the declared type in
  349. the program text). The generated call to A.doIt() is not matched by the
  350. call pcd used in the before advice. At compliance level 1.4, the
  351. bytecodes retain the declared type of the receiver in the program
  352. source, generating a call to B.doIt(), which _is_ matched by the call
  353. pcd.
  354. This is a good example of why the recommended style is to use
  355. `call(* doIt(..)) && target(B)`, which always matches based on the
  356. actual type of the receiver.
  357. '''''
  358. [[AJDOC]]
  359. === The ajdoc tool makes a comeback in the AspectJ 1.2 distribution.
  360. `ajdoc` (the AspectJ replacement for the `javadoc` tool) is once again
  361. included in the AspectJ distribution. The `ajdoc` tool produces regular
  362. javadoc that also shows advises and advised by relationships next to
  363. methods and advice. A future enhancement will show inter-type
  364. declarations in the target class too.
  365. *Known limitations:* Please note that `ajdoc` documents advice and
  366. pointcut members, shows where advice applies and links affected members
  367. back to the advice. It currently does not document or add structural
  368. links for any inter-type declarations or other declare forms.
  369. Run the "ajdoc.bat" script just as you run javadoc. For a list of
  370. accepted parameters run "ajdoc -help". For example, to document
  371. everything in the Spacewar example run: +
  372. > cd examples +
  373. > ajdoc -d doc -private spacewar coordination
  374. `ajdoc` sample output for an aspect source file:
  375. image:images/ajdoc1.JPG[image]
  376. `ajdoc` sample output for advised methods:
  377. image:images/ajdoc2.JPG[image]
  378. [[LTW]]
  379. === A sample script is supplied that supports load-time weaving from the command-line
  380. The AspectJ 1.2 distribution ships with sample scripts for Windows and
  381. Unix platforms that exploit AspectJ's binary weaving capabilities at
  382. application load time. You will find these scripts in the
  383. `doc/examples/ltw` directory of your AspectJ installation.
  384. The scripts allow you to set an environment variable, `ASPECTPATH`,
  385. containing a path-separator delimited list of aspect-library jar files.
  386. A Java application can then be launched using the "`aj`" script ("`aj`"
  387. is to "`ajc`" as "`java`" is to "`javac`"). If the `ASPECTPATH` is unset
  388. or empty, "`aj`" behaves exactly the same as "`java`", but if the
  389. `ASPECTPATH` contains one or more aspect libraries, the aspects in the
  390. library will be linked (woven) with the application code as it is
  391. loaded.
  392. The `doc/examples/ltw` directory of your AspectJ installation contains a
  393. sample application that demonstrates these capabilities. Following the
  394. instructions in the `README` file in that directory, running
  395. "`aj tracing.ExampleMain`" with `ASPECTPATH` unset produces the output:
  396. [source, text]
  397. ....
  398. c1.perimeter() = 12.566370614359172
  399. c1.area() = 12.566370614359172
  400. s1.perimeter() = 4.0
  401. s1.area() = 1.0
  402. c2.distance(c1) = 4.242640687119285
  403. s1.distance(c1) = 2.23606797749979
  404. s1.toString(): Square side = 1.0 @ (1.0, 2.0)
  405. ....
  406. If you set `ASPECTPATH` to include `../jars/tracingLib.jar`, and run
  407. "`aj tracing.ExampleMain`" again, the output will be:
  408. [source, text]
  409. ....
  410. --> tracing.TwoDShape(double, double)
  411. <-- tracing.TwoDShape(double, double)
  412. --> tracing.Circle(double, double, double)
  413. <-- tracing.Circle(double, double, double)
  414. --> tracing.TwoDShape(double, double)
  415. <-- tracing.TwoDShape(double, double)
  416. --> tracing.Circle(double, double, double)
  417. <-- tracing.Circle(double, double, double)
  418. --> tracing.Circle(double)
  419. <-- tracing.Circle(double)
  420. --> tracing.TwoDShape(double, double)
  421. <-- tracing.TwoDShape(double, double)
  422. --> tracing.Square(double, double, double)
  423. <-- tracing.Square(double, double, double)
  424. --> tracing.Square(double, double)
  425. <-- tracing.Square(double, double)
  426. --> double tracing.Circle.perimeter()
  427. <-- double tracing.Circle.perimeter()
  428. c1.perimeter() = 12.566370614359172
  429. --> double tracing.Circle.area()
  430. <-- double tracing.Circle.area()
  431. c1.area() = 12.566370614359172
  432. --> double tracing.Square.perimeter()
  433. <-- double tracing.Square.perimeter()
  434. s1.perimeter() = 4.0
  435. --> double tracing.Square.area()
  436. <-- double tracing.Square.area()
  437. s1.area() = 1.0
  438. --> double tracing.TwoDShape.distance(TwoDShape)
  439. --> double tracing.TwoDShape.getX()
  440. <-- double tracing.TwoDShape.getX()
  441. --> double tracing.TwoDShape.getY()
  442. <-- double tracing.TwoDShape.getY()
  443. <-- double tracing.TwoDShape.distance(TwoDShape)
  444. etc...
  445. ....
  446. The scripts only support JDK 1.4 and above - attempting to use them with
  447. a 1.3 or lower JDK will most likely produce `NoClassDefFound` errors. We
  448. welcome contributions from users to improve these scripts.
  449. '''''
  450. [[SOFTEX]]
  451. === SoftException now supports getCause()
  452. `org.aspectj.lang.SoftException` now supports the `getCause()` method,
  453. which returns the original exception wrapped by the `SoftException`.
  454. This means that exception chains will print correctly on 1.4 and later
  455. JREs.
  456. [[LTW2]]
  457. === org.aspectj.weaver.tools package added
  458. A new set of public APIs are exported by the
  459. link:api/index.html[`org.aspectj.weaver.tools`] package that can be used
  460. to integrate load-time weaving into an existing class loader hierachy.
  461. The package implementation is included in `aspectjtools.jar`. For an
  462. example of how to use these APIs, see the
  463. `org.aspectj.weaver.WeavingURLClassLoader` implementation.
  464. '''''
  465. [[allchanges]]
  466. == All changes are listed in the bug database
  467. For a complete list of changes in the 1.2 release, search for
  468. `target 1.2` in the bug database:
  469. https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler&target_milestone=1.2