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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. [[ltw]]
  2. = Load-Time Weaving
  3. [[ltw-introduction]]
  4. == Introduction
  5. The AspectJ weaver takes class files as input and produces class files
  6. as output. The weaving process itself can take place at one of three
  7. different times: compile-time, post-compile time, and load-time. The
  8. class files produced by the weaving process (and hence the run-time
  9. behaviour of an application) are the same regardless of the approach
  10. chosen.
  11. * Compile-time weaving is the simplest approach. When you have the
  12. source code for an application, ajc will compile from source and produce
  13. woven class files as output. The invocation of the weaver is integral to
  14. the ajc compilation process. The aspects themselves may be in source or
  15. binary form. If the aspects are required for the affected classes to
  16. compile, then you must weave at compile-time. Aspects are required,
  17. e.g., when they add members to a class and other classes being compiled
  18. reference the added members.
  19. * Post-compile weaving (also sometimes called binary weaving) is used to
  20. weave existing class files and JAR files. As with compile-time weaving,
  21. the aspects used for weaving may be in source or binary form, and may
  22. themselves be woven by aspects.
  23. * Load-time weaving (LTW) is simply binary weaving defered until the
  24. point that a class loader loads a class file and defines the class to
  25. the JVM. To support this, one or more "weaving class loaders", either
  26. provided explicitly by the run-time environment or enabled through a
  27. "weaving agent" are required.
  28. You may also hear the term "run-time weaving". We define this as the
  29. weaving of classes that have already been defined to the JVM (without
  30. reloading those classes). AspectJ 5 does not provide explicit support
  31. for run-time weaving although simple coding patterns can support
  32. dynamically enabling and disabling advice in aspects.
  33. === Weaving class files more than once
  34. As of AspectJ 5 aspects (code style or annotation style) and woven
  35. classes are reweavable by default. If you are developing AspectJ
  36. applications that are to be used in a load-time weaving environment with
  37. an older version of the compiler you need to specify the `-Xreweavable`
  38. compiler option when building them. This causes AspectJ to save
  39. additional state in the class files that is used to support subsequent
  40. reweaving.
  41. [[ltw-rules]]
  42. == Load-time Weaving Requirements
  43. All load-time weaving is done in the context of a class loader, and
  44. hence the set of aspects used for weaving and the types that can be
  45. woven are affected by the class loader delegation model. This ensures
  46. that LTW complies with the Java 2 security model. The following rules
  47. govern the interaction of load-time weaving with class loading:
  48. [arabic]
  49. . All aspects to be used for weaving must be defined to the weaver
  50. before any types to be woven are loaded. This avoids types being
  51. "missed" by aspects added later, with the result that invariants across
  52. types fail.
  53. . All aspects visible to the weaver are usable. A visible aspect is one
  54. defined by the weaving class loader or one of its parent class loaders.
  55. All concrete visible aspects are woven and all abstract visible aspects
  56. may be extended.
  57. . A class loader may only weave classes that it defines. It may not
  58. weave classes loaded by a delegate or parent class loader.
  59. [[ltw-configuration]]
  60. == Configuration
  61. New in AspectJ 5 are a number of mechanisms to make load-time weaving
  62. easy to use. The load-time weaving mechanism is chosen through JVM
  63. startup options. Configuration files determine the set of aspects to be
  64. used for weaving and which types will be woven. Additional diagnostic
  65. options allow the user to debug the configuration and weaving process.
  66. === Enabling Load-time Weaving
  67. AspectJ 5 supports several ways of enabling load-time weaving for an
  68. application: agents, a command-line launch script, and a set of
  69. interfaces for integration of AspectJ load-time weaving in custom
  70. environments.
  71. Agents::
  72. AspectJ 5 ships with a load-time weaving agent that enables load-time
  73. weaving. This agent and its configuration is execution environment
  74. dependent. Configuration for the supported environments is discussed
  75. later in this chapter.
  76. +
  77. Using Java 5 JVMTI you can specify the
  78. `-javaagent:pathto/aspectjweaver.jar` option to the JVM.
  79. +
  80. Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no
  81. longer part of AspectJ. JRockit JDK never supported Java versions
  82. higher than 1.6. Several JRockit JVM features are now part of HotSpot
  83. and tools like Mission Control available for OpenJDK and Oracle JDK.
  84. Command-line wrapper scripts `aj`::
  85. The `aj` command runs Java programs in Java 1.4 or later by setting up
  86. `WeavingURLClassLoader` as the system class loader. For more
  87. information, see xref:aj.adoc#aj[`aj`, the AspectJ load-time weaving launcher].
  88. +
  89. The `aj5` command runs Java programs in Java 5 by using the
  90. `-javaagent:pathto/aspectjweaver.jar` option described above. For more
  91. information, see xref:aj.adoc#aj[`aj`, the AspectJ load-time weaving launcher].
  92. Custom class loader::
  93. A public interface is provided to allow a user written class loader to
  94. instantiate a weaver and weave classes after loading and before
  95. defining them in the JVM. This enables load-time weaving to be
  96. supported in environments where no weaving agent is available. It also
  97. allows the user to explicitly restrict by class loader which classes
  98. can be woven. For more information, see xref:aj.adoc#aj[`aj`, the AspectJ load-time weaving launcher] and the API
  99. documentation and source for `WeavingURLClassLoader` and
  100. `WeavingAdapter`.
  101. [[configuring-load-time-weaving-with-aopxml-files]]
  102. === Configuring Load-time Weaving with aop.xml files
  103. The weaver is configured using one or more `META-INF/aop.xml` files
  104. located on the class loader search path. Each file may declare a list of
  105. aspects to be used for weaving, type patterns describing which types
  106. should woven, and a set of options to be passed to the weaver. In
  107. addition AspectJ 5 supports the definition of concrete aspects in XML.
  108. Aspects defined in this way must extend an abstract aspect visible to
  109. the weaver. The abstract aspect may define abstract pointcuts (but not
  110. abstract methods). The following example shows a simple aop.xml file:
  111. [source, xml]
  112. ....
  113. <aspectj>
  114. <aspects>
  115. <!-- declare two existing aspects to the weaver -->
  116. <aspect name="com.MyAspect"/>
  117. <aspect name="com.MyAspect.Inner"/>
  118. <!-- define a concrete aspect inline -->
  119. <concrete-aspect name="com.xyz.tracing.MyTracing"
  120. extends="tracing.AbstractTracing"
  121. precedence="com.xyz.first, *">
  122. <pointcut name="tracingScope" expression="within(org.maw.*)"/>
  123. </concrete-aspect>
  124. <!-- Of the set of aspects declared to the weaver
  125. use aspects matching the type pattern "com..*" for weaving. -->
  126. <include within="com..*"/>
  127. <!-- Of the set of aspects declared to the weaver
  128. do not use any aspects with the @CoolAspect annotation for weaving -->
  129. <exclude within="@CoolAspect *"/>
  130. </aspects>
  131. <weaver options="-verbose">
  132. <!-- Weave types that are within the javax.* or org.aspectj.*
  133. packages. Also weave all types in the foo package that do
  134. not have the @NoWeave annotation. -->
  135. <include within="javax.*"/>
  136. <include within="org.aspectj.*"/>
  137. <include within="(!@NoWeave foo.*) AND foo.*"/>
  138. <!-- Do not weave types within the "bar" pakage -->
  139. <exclude within="bar.*"/>
  140. <!-- Dump all types within the "com.foo.bar" package
  141. to the "./_ajdump" folder on disk (for diagnostic purposes) -->
  142. <dump within="com.foo.bar.*"/>
  143. <!-- Dump all types within the "com.foo.bar" package and sub-packages,
  144. both before are after they are woven,
  145. which can be used for byte-code generated at runtime
  146. <dump within="com.foo.bar..*" beforeandafter="true"/>
  147. </weaver>
  148. </aspectj>
  149. ....
  150. The DTD defining the format of this file is available here:
  151. https://www.eclipse.org/aspectj/dtd/aspectj.dtd.
  152. An aop.xml file contains two key sections: `aspects` defines one or more
  153. aspects to the weaver and controls which aspects are to be used in the
  154. weaving process; `weaver` defines weaver options and which types should
  155. be woven.
  156. The simplest way to define an aspect to the weaver is to specify the
  157. fully-qualified name of the aspect type in an aspect element. You can
  158. also declare (and define to the weaver) aspects inline in the aop.xml
  159. file. This is done using the `concrete-aspect` element. A
  160. concrete-aspect declaration must provide a pointcut definition for every
  161. abstract pointcut in the abstract aspect it extends. This mechanism is a
  162. useful way of externalizing configuration for infrastructure and
  163. auxiliary aspects where the pointcut definitions themselves can be
  164. considered part of the configuration of the service. Refer to the next
  165. section for more details.
  166. The `aspects` element may optionally contain one or more `include` and
  167. `exclude` elements (by default, all defined aspects are used for
  168. weaving). Specifying include or exclude elements restricts the set of
  169. defined aspects to be used for weaving to those that are matched by an
  170. include pattern, but not by an exclude pattern. The `within` attribute
  171. accepts a type pattern of the same form as a within pcd, except that &&
  172. and || are replaced by 'AND' and 'OR'.
  173. Note that `include` and `exclude` elements affect all aspects declared
  174. to the weaver including those in other aop.xml files. To help avoid
  175. unexpected behaviour a lint warning is issued if an aspect is not
  176. declared as a result of of applying these filters. Also note `aspect`
  177. and `concrete-aspect` elements must be used to declare aspects to the
  178. weaver i.e. `include` and `exclude` elements cannot be used find aspects
  179. on the class loader search path.
  180. The `weaver` element is used to pass options to the weaver and to
  181. specify the set of types that should be woven. If no include elements
  182. are specified then all types visible to the weaver will be woven. In
  183. addition the `dump` element can be used capture on disk byte-code of
  184. woven classes for diagnostic purposes both before, in the case of those
  185. generated at runtime, and after the weaving process.
  186. When several configuration files are visible from a given weaving class
  187. loader their contents are conceptually merged. The files are merged in
  188. the order they are found on the search path (with a regular
  189. `getResourceAsStream` lookup) according to the following rules:
  190. * The set of available aspects is the set of all declared and defined
  191. aspects (`aspect` and `concrete-aspect` elements of the `aspects`
  192. section).
  193. * The set of aspects used for weaving is the subset of the available
  194. aspects that are matched by at least one include statement and are not
  195. matched by any exclude statements. If there are no include statements
  196. then all non-excluded aspects are included.
  197. * The set of types to be woven are those types matched by at least one
  198. weaver `include` element and not matched by any weaver `exclude`
  199. element. If there are no weaver include statements, then all non-excluded
  200. types are included.
  201. * The weaver options are derived by taking the union of the options
  202. specified in each of the weaver options attribute specifications. Where
  203. an option takes a value e.g. `-warn:none` the most recently defined
  204. value will be used.
  205. It is not an error for the same aspect to be defined to the weaver in
  206. more than one visible `META-INF/aop.xml` file. However, if the same
  207. concrete aspect is defined in more than one aop.xml file then an error
  208. will be issued. A concrete aspect defined in this way will be used to
  209. weave types loaded by the class loader that loaded the aop.xml file in
  210. which it was defined.
  211. A `META-INF/aop.xml` can be generated by using either the `-outxml` or
  212. `-outxmlfile` options of the AspectJ compiler. It will simply contain a
  213. (possibly empty) set of aspect elements; one for each abstract or
  214. concrete aspect defined. When used in conjuction with the `-outjar`
  215. option a JAR is produced that can be used with the `aj5` command or a
  216. load-time weaving environment.
  217. [[concrete-aspect]]
  218. === Using Concrete Aspects
  219. It is possible to make an abstract aspect concrete by means of the
  220. `META-INF/aop.xml` file. This is useful way to implement abstract
  221. pointcuts at deployment time, and also gives control over precedence
  222. through the `precedence` attribute of the `concrete-aspect` XML element.
  223. Consider the following:
  224. [source, java]
  225. ....
  226. package mypack;
  227. @Aspect
  228. public abstract class AbstractAspect {
  229. // abstract pointcut: no expression is defined
  230. @Pointcut
  231. abstract void scope();
  232. @Before("scope() && execution(* *..doSome(..))")
  233. public void before(JoinPoint jp) {
  234. // ...
  235. }
  236. }
  237. ....
  238. This aspect is equivalent to the following in code style:
  239. [source, java]
  240. ....
  241. package mypack;
  242. public abstract aspect AbstractAspect {
  243. // abstract pointcut: no expression is defined
  244. abstract pointcut scope();
  245. before() : scope() && execution(* *..doSome(..)) {
  246. // ...
  247. }
  248. }
  249. ....
  250. This aspect (in either style) can be made concrete using
  251. `META-INF/aop.xml`. It defines the abstract pointcut `scope()`. When
  252. using this mechanism the following rules apply:
  253. * The parent aspect must be abstract. It can be an @AspectJ or a regular
  254. code style aspect.
  255. * Only a simple abstract pointcut can be implemented i.e. a pointcut
  256. that doesn't expose state (through `args(), this(), target(), if()`). In
  257. @AspectJ syntax as illustrated in this sample, this means the method
  258. that hosts the pointcut must be abstract, have no arguments, and return
  259. void.
  260. * The concrete aspect must implement all inherited abstract pointcuts.
  261. * The concrete aspect may not implement methods so the abstract aspect
  262. it extends may not contain any abstract methods.
  263. _A limitation of the implementation of this feature in AspectJ 1.5.0 is
  264. that aspects defined using aop.xml are not exposed to the weaver. This
  265. means that they are not affected by advice and ITDs defined in other
  266. aspects. Support for this capability will be considered in a future
  267. release._
  268. If more complex aspect inheritance is required use regular aspect
  269. inheritance instead of XML. The following XML definition shows a valid
  270. concrete sub-aspect for the abstract aspects above:
  271. [source, xml]
  272. ....
  273. <aspectj>
  274. <aspects>
  275. <concrete-aspect name="mypack.__My__AbstractAspect" extends="mypack.AbstractAspect">
  276. <pointcut name="scope" expression="within(yourpackage..*)"/>
  277. </concrete-aspect>
  278. <aspects>
  279. </aspectj>
  280. ....
  281. It is important to remember that the `name` attribute in the
  282. `concrete-aspect` directive defines the fully qualified name that will
  283. be given to the concrete aspect. It must a valid class name because the
  284. aspect will be generated on the fly by the weaver. You must also ensure
  285. that there are no name collisions. Note that the concrete aspect will be
  286. defined at the classloader level for which the aop.xml is visible. This
  287. implies that if you need to use the `aspectof` methods to access the
  288. aspect instance(s) (depending on the perclause of the aspect it extends)
  289. you have to use the helper API `org.aspectj.lang.Aspects.aspectOf(..)`
  290. as in:
  291. [source, java]
  292. ....
  293. // exception handling omitted
  294. Class myConcreteAspectClass = Class.forName("mypack.__My__AbstractAspect");
  295. // here we are using a singleton aspect
  296. AbstractAspect concreteInstance = Aspects.aspectOf(myConcreteAspectClass);
  297. ....
  298. [[concrete-aspect-precedence]]
  299. === Using Concrete Aspects to define precedence
  300. As described in the previous section, the `concrete-aspect` element in
  301. `META-INF/aop.xml` gives the option to declare the precedence, just as
  302. `@DeclarePrecedence` or `declare precedence` do in aspect source code.
  303. Sometimes it is necessary to declare precedence without extending any
  304. abstract aspect. It is therefore possible to use the `concrete-aspect`
  305. element without the `extends` attribute and without any `pointcut`
  306. nested elements, just a `precedence` attribute. Consider the following:
  307. [source, xml]
  308. ....
  309. <aspectj>
  310. <aspects>
  311. <concrete-aspect name="mypack.__MyDeclarePrecedence"
  312. precedence="*..*Security*, Logging+, *"/>
  313. </aspects>
  314. </aspectj>
  315. ....
  316. This deployment time definitions is only declaring a precedence rule.
  317. You have to remember that the `name` attribute must be a valid fully
  318. qualified class name that will be then reserved for this concrete-aspect
  319. and must not conflict with other classes you deploy.
  320. [[weaver-options]]
  321. === Weaver Options
  322. The table below lists the AspectJ options supported by LTW. All other
  323. options will be ignored and a warning issued.
  324. [cols=",",options="header",]
  325. |===
  326. |Option |Purpose
  327. |`-verbose` |Issue informational messages about the weaving process.
  328. Messages issued while the weaver is being bootstrapped are accumulated
  329. until all options are parsed. If the messages are required to be output
  330. immediately you can use the option `-Daj.weaving.verbose=true` on the
  331. JVM startup command line.
  332. |`-debug` |Issue a messages for each class passed to the weaver
  333. indicating whether it was woven, excluded or ignored. Also issue
  334. messages for classes defined during the weaving process such as around
  335. advice closures and concrete aspects defined in `META-INF/aop.xml`.
  336. |`-showWeaveInfo` |Issue informational messages whenever the weaver
  337. touches a class file. This option may also be enabled using the System
  338. property `-Dorg.aspectj.weaver.showWeaveInfo=true`.
  339. |`-Xlintfile:pathToAResource` |Configure lint messages as specified in
  340. the given resource (visible from this aop.xml file' classloader)
  341. |`-Xlint:default, -Xlint:ignore, ...` |Configure lint messages, refer to
  342. documentation for meaningfull values
  343. |`-nowarn, -warn:none` |Suppress warning messages
  344. |`-Xreweavable` |Produce class files that can subsequently be rewoven
  345. |`-XnoInline` |Don't inline around advice.
  346. |`-XmessageHandlerClass:...` |Provide alternative output destination to
  347. stdout/stderr for all weaver messages. The given value must be the full
  348. qualified class name of a class that implements the
  349. `org.aspectj.bridge.IMessageHandler` interface and is visible to the
  350. classloader with which the weaver being configured is associated.
  351. Exercise caution when packaging a custom message handler with an
  352. application that is to be woven. The handler (as well as classes on
  353. which it depends) cannot itself be woven by the aspects that are
  354. declared to the same weaver.
  355. |===
  356. [[ltw-specialcases]]
  357. == Special cases
  358. The following classes are not exposed to the LTW infrastructure
  359. regardless of the `aop.xml` file(s) used:
  360. * All `org.aspectj.*` classes (and subpackages) - as those are needed by
  361. the infrastructure itself
  362. * All `java.*` and `javax.*` classes (and subpackages)
  363. * All `sun.reflect.*` classes - as those are JDK specific classes used
  364. when reflective calls occurs
  365. Despite these restrictions, it is perfectly possible to match call join
  366. points for calls to these types providing the calling class is exposed
  367. to the weaver. Subtypes of these excluded types that are exposed to the
  368. weaver may of course be woven.
  369. Note that dynamic proxy representations are exposed to the LTW
  370. infrastructure and are not considered a special case.
  371. Some lint options behave differently when used under load-time weaving.
  372. The `adviceDidNotMatch` won't be handled as a warn (as during compile
  373. time) but as an info message.
  374. [[ltw-packaging]]
  375. == Runtime Requirements for Load-time Weaving
  376. To use LTW the `aspectjweaver.jar` library must be added to the
  377. classpath. This contains the AspectJ 5 runtime, weaver, weaving class
  378. loader and weaving agents. It also contains the DTD for parsing XML
  379. weaving configuration files.
  380. [[ltw-agents]]
  381. == Supported Agents
  382. === JVMTI
  383. When using Java 5 the JVMTI agent can be used by starting the JVM with
  384. the following option (adapt according to the path to aspectjweaver.jar):
  385. [source, text]
  386. ....
  387. -javaagent:pathto/aspectjweaver.jar
  388. ....
  389. [[jrockit]]
  390. === JRockit with Java 1.3/1.4 (use JVMTI on Java 5)
  391. Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no longer
  392. part of AspectJ. JRockit JDK never supported Java versions higher than
  393. 1.6. Several JRockit JVM features are now part of HotSpot and tools like
  394. Mission Control available for OpenJDK and Oracle JDK.