|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381 |
- [[readme-1_1]]
- = AspectJ 1.1
-
- _© Copyright 2002 Palo Alto Research Center, Incorporated, 2003
- Contributors. All rights reserved._
-
- This is the initial release of AspectJ 1.1. It includes a small number
- of new language features as well as major improvements to the
- functionality of the tools.
-
- This document describes the differences between AspectJ versions 1.1 and
- 1.0.6. Users new to AspectJ need only read the
- link:progguide/index.html[AspectJ Programming Guide] since it describes
- the 1.1 language. Users familiar with AspectJ 1.0 may find this document
- a quicker way to learn what changed in the language and tools, and
- should use it as a guide for porting programs from 1.0 to 1.1.
-
- This document first summarizes changes from the 1.0 release in
-
- * xref:#language[the language],
- * xref:#compiler[the compiler],
- * xref:#tools[the support tools],
- * xref:#runtime[the runtime],
- * xref:#devenv[the development environment support],
- * xref:#sources[the sources], and
- * xref:#distribution[the distribution],
-
- then xref:#details[details] some of the language and compiler changes,
- and finally points readers to the bug database for any
- xref:#knownLimitations[known limitations].
-
- '''''
-
- [[language]]
- == The Language
-
- AspectJ 1.1 is a slightly different language than AspectJ 1.0. In all
- but a few cases, programs written in AspectJ 1.0 should compile
- correctly in AspectJ 1.1. In many cases, there are new or preferred
- forms in AspectJ 1.1. However, some AspectJ 1.0 features have changed in
- 1.1, so some 1.0 programs will not compile or will run differently in
- 1.1. The corresponding features are marked below as compile-time or
- run-time incompatible (_CTI_ or _RTI_, respectively). When the language
- change involves a move in the static shadow effective at run-time but
- also apparent at compile-time (e.g., in declare error or warning
- statements), it is marked _CRTI_. Programs using run-time incompatible
- forms should be verified that they are behaving as expected in 1.1.
-
- Most changes to the language are additions to expressibility requested
- by our users:
-
- * xref:#THROWS_PATTERN[Matching based on throws]: You can now make finer
- discriminations between methods based on declared exceptions.
- * xref:#NEW_PCDS[New kinded pointcut designators]: Now every kind of
- join point has a corresponding kinded pointcut designator.
-
- Some are have different behavior in edge cases but offer improved power
- and clarity:
-
- * xref:#ASPECT_PRECEDENCE[New aspect precedence form]: AspectJ 1.1 has a
- new declare form, `declare precedence`, that replaces the
- "dominates" clause on aspects. (_CTI_)
- * The order of xref:#SUPER_IFACE_INITS[initialization join points for
- super-interfaces] has been clarified. (_RTI_)
-
- But in order to support weaving into bytecode effectively, several
- incompatible changes had to be made to the language:
-
- * A class's default constructor may
- xref:#DEFAULT_CONSTRUCTOR_CONFLICT[conflict] with an inter-type
- constructor. (_CTI_)
- * xref:#NO_CALLEE_SIDE_CALL[No callee-side call join points]: The
- AspectJ 1.1 compiler does not expose call join points unless it is given
- the calling code. (_CRTI_)
- * xref:#SINGLE_INTERCLASS_TARGET[One target for intertype declarations].
- (_CTI_)
- * xref:#UNAVAILABLE_JOIN_POINTS[No initializer execution join points].
- (_RTI_)
- * xref:#AFTER_HANDLER[No after or around advice on handler join points].
- (_CTI_)
- * xref:#CONSTRUCTOR_EXECUTION_IS_BIGGER[Initializers run inside
- constructor execution join points]. (_RTI_)
- * xref:#INTER_TYPE_FIELD_INITIALIZERS[inter-type field initializers] run
- before class-local field initializers. (_RTI_)
- * xref:#WITHIN_MEMBER_TYPES[Small limitations of the within pointcut.]
- (_CRTI_)
- * xref:#WITHIN_CODE[Small limitations of the withincode pointcut.]
- (_CRTI_)
- * xref:#INSTANCEOF_ON_WILD[Can't do instanceof matching on type patterns
- with wildcards]. (_CTI_)
- * xref:#NO_SOURCE_COLUMN[SourceLocation.getColumn() is deprecated and
- will always return 0]. (_RTI_)
- * The interaction between aspect instantiation and advice has been
- xref:#ASPECT_INSTANTIATION_AND_ADVICE[clarified]. (_RTI_)
- * xref:#STRINGBUFFER[The String + operator is now correctly advised].
- (_CRTI_)
-
- [#NEW_LIMITATIONS]#There# are a couple of language limitations for
- things that are rarely used that make the implementation simpler, so we
- have restricted the language accordingly.
-
- * xref:#VOID_FIELD_SET[Field set join points now have a `void` return
- type.] This will require porting of code that uses the `set` PCD in
- conjunction with after-returning or around advice. (_CTI_)
- * 'declare soft: TYPE: POINTCUT;' - AspectJ 1.1 only accepts TYPE rather
- than a TYPE_PATTERN. This limitation makes declare soft much easier to
- implement efficiently. (_CTI_)
- * Inter-type field declarations only allow a single field per line, i.e.
- this is now illegal 'int C.field1, D.field2;' This must instead be, 'int
- C.field1; int D.field2;' (_CTI_)
- * We did not implement the handling of more than one `..` wildcard in
- args PCD's (rarely encountered in the wild) because we didn't have the
- time. This might be available in later releases if there is significant
- outcry. (_CTI_)
-
- We did not implement the long-awaited xref:#PER_TYPE[new pertype aspect
- specifier] in this release, but it may well be in a future release.
-
- '''''
-
- [[compiler]]
- == The Compiler
-
- The compiler for AspectJ 1.1 is different than the compiler for AspectJ
- 1.0. While this document describes the differences in the compiler, it's
- worthwhile noting that much effort has been made to make sure that the
- interface to ajc 1.1 is, as much as possible, the same as the interface
- to ajc 1.0. There are two important changes under the hood, however.
-
- First, the 1.1 compiler is implemented on top of the open-source Eclipse
- compiler. This has two benefits: It allows us to concentrate on the
- AspectJ extensions to Java and let the Eclipse team worry about making
- sure the Java edge cases work, and it allows us to piggyback on
- Eclipse's already mature incremental compilation facilities.
-
- Second, ajc now cleanly delineates compilation of source code from
- assembly (or "weaving") of bytecode. The compiler still accepts source
- code, but internally it transforms it into bytecode format before
- weaving.
-
- This new architecture, and other changes to the compiler, allows us to
- implement some features that were defined in the AspectJ 1.0 language
- but not implementable in the 1.1 compiler. It also makes some new
- features available:
-
- * xref:#SOURCEROOT[The -sourceroots option] takes one or more
- directories, and indicates that all the source files in those
- directories should be passed to the compiler.
- * xref:#BYTECODE_WEAVING[The -injars option] takes one or more jar
- files, and indicates that all the classfiles in the jar files should be
- woven into.
- * xref:#BINARY_ASPECTS[The -aspectpath option] takes one or more jar
- files, and weaves any aspects in .class form into the sources.
- * xref:#OUTJAR[The -outjar option] indicates that the result classfiles
- of compiling and weaving should be placed in the specified jar file.
- * xref:#XLINT[The -Xlint option] allows control over warnings.
- * xref:#OTHER_X_OPTIONS[Various -X options] changed.
- * xref:#INCREMENTAL[The -incremental option] tells the AspectJ 1.1
- compiler to recompile only as necessary.
-
- Some other features we wanted to support for 1.1, but did not make it
- into this release:
-
- * xref:#ERROR_MESSAGES[Error messages will sometimes be scary]
- * xref:#MESSAGE_CONTEXT[Source code context is not shown for errors and
- warnings detected during bytecode weaving]
-
- But some features of the 1.0 compiler are not supported in the 1.1
- compiler:
-
- * xref:#NO_SOURCE[The source-related options] -preprocess, -usejavac,
- -nocomment and -workingdir
- * xref:#NO_STRICT_LENIENT[The -strict and -lenient options]
- * xref:#NO_PORTING[The -porting option]
- * xref:#_13_REQUIRED[J2SE 1.2 is not supported; J2SE 1.3 or later is
- required.]
-
- A short description of the options ajc accepts is available with
- "`ajc -help`". Longer descriptions are available in the
- link:devguide/ajc-ref.html[Development Environment Guide section on
- ajc].
-
- Some changes to the implementation are almost entirely internal:
-
- * The behavior of the compiler in xref:#TARGET_TYPES_MADE_PUBLIC[lifting
- the visibility] of the target types of some declares and pointcuts to
- public has been clarified.
-
- Also, it is worth noting that because AspectJ now works on bytecode, it
- is somewhat sensitive to how different compilers generate bytecode,
- especially when compiling with and without
- xref:#ONE_FOUR_METHOD_SIGNATURES[the -1.4 flag].
-
- '''''
-
- [[tools]]
- == Support Tools
-
- This release includes an Ant task for old-style 1.0 build scripts, a new
- task for all the new compiler options, and a CompilerAdapter to support
- running `ajc` with the Javac task by setting the `build.compiler`
- property. The new task can automatically copy input resources to output
- and work in incremental mode using a "tag" file.
-
- This release does not include `ajdoc`, the documentation tool for
- AspectJ sources. Ajdoc is deeply dependent on the abstract syntax tree
- classes from the old compiler, so it needs a bottom-up rewrite. We think
- it best to use this opportunity to implement more general API's for
- publishing and rendering static structure. Because those API's are last
- to settle in the new architecture, and because the compiler itself is a
- higher priority, we are delaying work on ajdoc until after the 1.1
- release.
-
- AspectJ 1.1 will not include ajdb, the AspectJ stand-alone debugger. It
- is no longer necessary for two reasons. First, the -XnoInline flag will
- tell the compiler to generate code without inlining that should work
- correctly with any Java debugger. For code generated with inlining
- enabled, more third-party debuggers are starting to work according to
- JSR 45, "Debugging support for other languages," which is supported by
- AspectJ 1.0. We aim to support JSR-45 in AspectJ 1.1, but support will
- not be in the initial release. Consider using the -XnoInline flag until
- support is available.
-
- '''''
-
- [[runtime]]
- == The Runtime Library
-
- This release has minor additions to the runtime library classes. As with
- any release, you should compile and run with the runtime library that
- came with your compiler, and you may run with a later version of the
- library without recompiling your code.
-
- In one instance, however, runtime classes behave differently this
- release. Because the AspectJ 1.1 compiler does its weaving through
- bytecode, column numbers of source locations are not available.
- Therefore, `thisJoinPoint.getSourceLocation().getColumn()` is deprecated
- and will always return 0.
-
- '''''
-
- [[devenv]]
- == The AJDE Tools
-
- The AspectJ Browser supports incremental compilation and running
- programs. AJDE for JBuilder, AJDE for NetBeans, and AJDE for Emacs are
- now independent SourceForge projects (to keep their licenses). They use
- the batch-build mode of the new compiler.
-
- '''''
-
- [[sources]]
- == The Sources and the Licenses
-
- The AspectJ tools sources are available under the
- https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt[Eclipse Public
- License v 2.0] in the Git repository at https://eclipse.org/aspectj. For
- more information, see the FAQ entry on building sources.
-
- '''''
-
- [[distribution]]
- == The AspectJ distribution
-
- AspectJ 1.0 had many distributions - for the tools, the documentation,
- each IDE support package, their respective sources, and the Ant tasks -
- because they came under different licenses. All of AspectJ 1.1 is
- licensed under the CPL 1.0, so the tools, Ant tasks, and documentation
- are all in one distribution available from https://eclipse.org/aspectj.
- To retain their MPL 1.1 license, Ajde for
- http://aspectj4emacs.sourceforge.net/[Emacs],
- http://aspectj4netbean.sourceforge.net/[NetBeans] and
- http://aspectj4jbuildr.sourceforge.net/[JBuilder] are now independent
- SourceForge projects.
-
- '''''
-
- '''''
-
- [[details]]
- == Details of some language and compiler changes
-
- [[ASPECT_INSTANTIATION_AND_ADVICE]]
- === Aspect Instantiation and Advice
-
- In AspectJ 1.0.6, we made an effort to hide some complications with
- Aspect instantiation from the user. In particular, the following code
- compiled and ran:
-
- [source, java]
- ....
- public class Client {
- public static void main(String[] args) {
- Client c = new Client();
- }
- }
-
- aspect Watchcall {
- pointcut myConstructor(): execution(new(..));
-
- before(): myConstructor() {
- System.err.println("Entering Constructor");
- }
- }
- ....
-
- But there's a conceptual problem with this code: The before advice
- should run before the execution of all constructors in the system. It
- must run in the context of an instance of the Watchcall aspect. The only
- way to get such an instance is to have Watchcall's default constructor
- execute. But before that executes, we need to run the before advice...
-
- AspectJ 1.0.6 hid this circularity through the ad-hoc mechanism of
- preventing an aspect's advice from matching join points that were within
- the aspect's definition, and occurred before the aspect was initialized.
- But even in AspectJ 1.0.6, this circularity could be exposed:
-
- [source, java]
- ....
- public class Client {
- public static int foo() { return 3; }
- public static void main(String[] args) {
- Client c = new Client();
- }
- }
-
- aspect Watchcall {
- int i = Client.foo();
- pointcut myConstructor():
- execution(new(..)) || execution(int foo());
-
- before(): myConstructor() {
- System.err.println("Entering Constructor");
- }
- }
- ....
-
- This program would throw a NullPointerException when run, since
- Client.foo() was called before the Watchcall instance could be
- instantiated.
-
- In AspectJ 1.1, we have decided that half-hiding the problem just leads
- to trouble, and so we are no longer silently hiding some join points
- before aspect initialization. However, we have provided a better
- exception than a NullPointerException for this case. In AspectJ 1.1,
- both of the above programs will throw
- org.aspectj.lang.NoAspectBoundException.
-
- [[THROWS_PATTERN]]
- === Matching based on throws
-
- Type patterns may now be used to pick out methods and constructors based
- on their throws clauses. This allows the following two kinds of
- extremely wildcarded pointcuts:
-
- [source, java]
- ....
- pointcut throwsMathlike():
- // each call to a method with a throws clause containing at least
- // one exception with "Math" in its name.
- call(* *(..) throws *..*Math*);
-
- pointcut doesNotThrowMathlike():
- // each call to a method with a throws clause containing no
- // exceptions with "Math" in its name.
- call(* *(..) throws !*..*Math*);
- ....
-
- The longwinded rules are that a method or constructor pattern can have a
- "throws clause pattern". Throws clause patterns look like:
-
- [source, text]
- ....
- ThrowsClausePattern:
- ThrowsClausePatternItem ("," ThrowsClausePatternItem)*
-
- ThrowsClausePatternItem:
- ["!"] TypeNamePattern
- ....
-
- A ThrowsClausePattern matches the ThrowsClause of any code member
- signature. To match, each ThrowsClausePatternItem must match the throws
- clause of the member in question. If any item doesn't match, then the
- whole pattern doesn't match. This rule is unchanged from AspectJ 1.0.
-
- If a ThrowsClausePatternItem begins with "!", then it matches a
- particular throws clause if and only if _none_ of the types named in the
- throws clause is matched by the TypeNamePattern.
-
- If a ThrowsClausePatternItem does not begin with "!", then it matches a
- throws clause if and only if _any_ of the types named in the throws
- clause is matched by the TypeNamePattern.
-
- These rules are completely backwards compatible with AspectJ 1.0. The
- rule for "!" matching has one potentially surprising property, in that
- the two PCD's shown below will have different matching rules.
-
- [source, java]
- ....
- /*[1]*/ call(* *(..) throws !IOException)
- /*[2]*/ call(* *(..) throws (!IOException))
-
- void m() throws RuntimeException, IOException {}
- ....
-
- [1] will NOT match the method m(), because method m's throws clause
- declares that it throws IOException. [2] WILL match the method m(),
- because method m's throws clause declares the it throws some exception
- which does not match IOException, i.e. RuntimeException.
-
- [[NEW_PCDS]]
- === New kinded pointcut designators
-
- AspectJ 1.0 does not provide kinded pointcut designators for two (rarely
- used) join points: preinitialization (the code that runs before a super
- constructor call is made) and advice execution. AspectJ 1.1 does not
- change the meaning of the join points, but provides two new pointcut
- designators to pick out these join points, thus making join points and
- pointcut designators more parallel.
-
- `adviceexectuion()` will pick out advice execution join points. You will
- usually want to use `adviceexecution() && within(Aspect)` to
- restrict it to only those pieces of advice defined in a particular
- aspect. +
- `preinitialization(ConstructorPattern)` will pick out pre-initialization
- join points where the initialization process is entered through
- `ConstructorPattern`.
-
- [[PER_TYPE]]
- === New pertype aspect specifier (not in 1.1)
-
- We strongly considered adding a pertype aspect kind to 1.1. This is
- somewhat motivated by the new
- xref:#SINGLE_INTERCLASS_TARGET[restrictions on inter-type declarations]
-
- . This is also motivated by many previous request to support a common
- logging idiom. Here's what pertype would look like:
-
- [source, java]
- ....
- /** One instance of this aspect will be created for each class,
- * interface or aspect in the com.bigboxco packages.
- */
- aspect Logger pertype(com.bigboxco..*) {
- /* This field holds a logger for the class. */
- Log log;
-
- /* This advice will run for every public execution defined by
- * a type for which a Logger aspect has been created, i.e.
- * any type in com.bigboxco..*
- */
- before(): execution(public * *(..)) {
- log.enterMethod(thisJoinPoint.getSignature().getName());
- }
-
- /* We can use a special constructor to initialize the log field */
- public Logger(Class myType) {
- this.log = new Log(myType);
- }
- }
-
- /** External code could use aspectOf to get at the log, i.e. */
- Log l = Logger.aspectOf(com.bigboxco.Foo.class).log;
- ....
-
- The one open question that we see is how this should interact with inner
- types. If a pertype aspect is created for an outer type should advice in
- that aspect run for join points in inner types? That is the behavior of
- the most common uses of this idiom.
-
- In any case, this feature will not be in AspectJ 1.1.
-
- [[SINGLE_INTERCLASS_TARGET]]
- === One target for intertype declarations
-
- Intertype declarations (once called "introductions") in AspectJ 1.1 can
- only have one target type. So the following code intended to declare
- that there is a void doStuff() method on all subtypes of Target is not
- legal AspectJ 1.1 code.
-
- [source, java]
- ....
- aspect A {
- public void Target+.doStuff() { ... }
- }
- ....
-
- The functionality of "multi-intertype declarations" can be recovered by
- using a helper interface.
-
- [source, java]
- ....
- aspect A {
- private interface MyTarget {}
- declare parents: Target+ implements MyTarget;
- public void MyTarget.doStuff() { ... }
- }
- ....
-
- We believe this is better style in AspectJ 1.0 as well, as it makes
- clear the static type of "this" inside the method body.
-
- The one piece of functionality that can not be easily recovered is the
- ability to add static fields to many classes. We believe that the
- xref:#PER_TYPE[pertype proposal] provides this functionality in a much
- more usable form.
-
- [[UNAVAILABLE_JOIN_POINTS]]
- === No initializer execution join points
-
- AspectJ 1.1 does not consider initializer execution a principled join
- point. The collection of initializer code (the code that sets fields
- with initializers and the code in non-static initializer blocks) is
- something that makes sense only in Java source code, not in Java
- bytecode.
-
- [[AFTER_HANDLER]]
- === No after or around advice on handler join points
-
- The end of an exception handler is underdetermined in bytecode, so ajc
- will not implement after or around advice on handler join points,
- instead signaling a compile-time error.
-
- [[CONSTRUCTOR_EXECUTION_IS_BIGGER]]
- === Initializers run inside constructor execution join points
-
- The code generated by the initializers in Java source code now runs
- inside of constructor execution join points. This changes how before
- advice runs on constructor execution join points. Consider:
-
- [source, java]
- ....
- class C {
- C() { }
- String id = "identifier"; // this assignment
- // has to happen sometime
- }
-
- aspect A {
- before(C c) this(c) && execution(C.new()) {
- System.out.println(c.id.length());
- }
- }
- ....
-
- In AspectJ 1.0, this will print "10", since id is assigned its initial
- value prior to the before advice's execution. However, in AspectJ 1.1,
- this will throw a NullPointerExcception, since "id" does not have a
- value prior to the before advice's execution.
-
- Note that the various flavors of after returning advice are unchanged in
- this respect in AspectJ 1.1. Also note that this only matters for the
- execution of constructors that call a super-constructor. Execution of
- constructors that call a this-constructor are the same in AspectJ 1.1 as
- in AspectJ 1.0.
-
- We believe this difference should be minimal to real programs, since
- programmers using before advice on constructor execution must always
- assume incomplete object initialization, since the constructor has not
- yet run.
-
- [[INTER_TYPE_FIELD_INITIALIZERS]]
- === Inter-type field initializers
-
- The initializer, if any, of an inter-type field definition runs before
- the class-local initializers of its target class.
-
- In AspectJ 1.0.6, such an initializer would run after the initializers
- of a class but before the execution of any of its constructor bodies. As
- already discussed in the sections about
- xref:#UNAVAILABLE_JOIN_POINTS[initializer execution join points] and
- xref:#CONSTRUCTOR_EXECUTION_IS_BIGGER[constructor execution], the point
- in code between the initializers of a class and its constructor body is
- not principled in bytecode. So we had a choice of running the
- initializer of an inter-type field definition at the beginning of
- initialization (i.e., before initializers from the target class) or at
- the end (i.e., just before its called constructor exits). We chose the
- former, having this pattern in mind:
-
- [source, java]
- ....
- int C.methodCount = 0;
- before(C c): this(c) && execution(* *(..)) { c.methodCount++; }
- ....
-
- We felt there would be too much surprise if a constructor called a
- method (thus incrementing the method count) and then the field was reset
- to zero after the constructor was done.
-
- [[WITHIN_MEMBER_TYPES]]
- === Small limitations of the within pointcut
-
- Because of the guarantees made (and not made) by the Java classfile
- format, there are cases where AspectJ 1.1 cannot guarantee that the
- within pointcut designator will pick out all code that was originally
- within the source code of a certain type.
-
- The non-guarantee applies to code inside of anonymous and local types
- inside member types. While the within pointcut designator behaves
- exactly as it did in AspectJ 1.0 when given a package-level type (like
- C, below), if given a member-type (like C.InsideC, below), it is not
- guaranteed to capture code in contained local and anonymous types. For
- example:
-
- [source, java]
- ....
- class C {
- Thread t;
- class InsideC {
- void setupOuterThread() {
- t = new Thread(
- new Runnable() {
- public void run() {
- // join points with code here
- // might not be captured by
- // within(C.InsideC), but are
- // captured by within(C)
- System.out.println("hi");
- }
- });
- }
- }
- }
- ....
-
- We believe the non-guarantee is small, and we haven't verified that it
- is a problem in practice.
-
- [[WITHIN_CODE]]
- === Small limitations of the withincode pointcut
-
- The withincode pointcut has similar issues to those described above for
- within.
-
- [[INSTANCEOF_ON_WILD]]
- === Can't do instanceof matching on type patterns with wildcard
-
- The pointcut designators this, target and args specify a dynamic test on
- their argument. These tests can not be performed on type patterns with
- wildcards in them. The following code that compiled under 1.0 will be an
- error in AspectJ-1.1:
-
- [source, java]
- ....
- pointcut oneOfMine(): this(com.bigboxco..*);
- ....
-
- The only way to implement this kind of matching in a modular way would
- be to use the reflection API at runtime on the Class of the object. This
- would have a very high performance cost and possible security issues.
- There are two good work-arounds. If you control the source or bytecode
- to the type you want to match then you can use declare parents, i.e.:
-
- [source, java]
- ....
- private interface OneOfMine {}
- declare parents: com.bigboxco..* implements OneOfMine;
- pointcut oneOfMine(): this(OneOfMine);
- ....
-
- If you want the more dynamic matching and are willing to pay for the
- performance, then you should use the Java reflection API combined with
- if. That would look something like:
-
- [source, java]
- ....
- pointcut oneOfMine(): this(Object) &&
- if(classMatches("com.bigboxco..*",
- thisJoinPoint.getTarget().getClass()));
-
- static boolean classMatches(String pattern, Class _class) {
- if (patternMatches(pattern, _class.getName())) return true;
- ...
- }
- ....
-
- Note: wildcard type matching still works in all other PCD's that match
- based on static types. So, you can use 'within(com.bigboxco..*+)' to
- match any code lexically within one of your classes or a subtype
- thereof. This is often a good choice.
-
- [[NO_SOURCE_COLUMN]]
- === SourceLocation.getColumn()
-
- The Java .class file format contains information about the source file
- and line numbers of its contents; however, it has no information about
- source columns. As a result, we can not effectively support the access
- of column information in the reflection API. So, any calls to
- thisJoinPoint.getSourceLocation().getColumn() will be marked as
- deprecated by the compiler, and will always return 0.
-
- [[ASPECT_PRECEDENCE]]
- === Aspect precedence
-
- AspectJ 1.1 has a new declare form:
-
- [source, java]
- ....
- declare precedence ":" TypePatternList ";"
- ....
-
- This is used to declare advice ordering constraints on join points. For
- example, the constraints that (1) aspects that have Security as part of
- their name should dominate all other aspects, and (2) the Logging aspect
- (and any aspect that extends it) should dominate all non-security
- aspects, can be expressed by:
-
- [source, java]
- ....
- declare precedence: *..*Security*, Logging+, *;
- ....
-
- In the TypePatternList, the wildcard * means "any type not matched by
- another type in the declare precedence".
-
- ==== Various cycles
-
- It is an error for any aspect to be matched by more than one TypePattern
- in a single declare precedence, so:
-
- [source, java]
- ....
- declare precedence: A, B, A ; // error
- ....
-
- However, multiple declare precedence forms may legally have this kind of
- circularity. For example, each of these declare precedence is perfectly
- legal:
-
- [source, java]
- ....
- declare precedence: B, A;
- declare precedence: A, B;
- ....
-
- And a system in which both constraints are active may also be legal, so
- long as advice from A and B don't share a join point. So this is an
- idiom that can be used to enforce that A and B are strongly independent.
-
- ==== Applies to concrete aspects
-
- Consider the following library aspects:
-
- [source, java]
- ....
- abstract aspect Logging {
- abstract pointcut logged();
-
- before(): logged() {
- System.err.println("thisJoinPoint: " + thisJoinPoint);
- }
- }
-
- aspect MyProfiling {
- abstract pointcut profiled();
-
- Object around(): profiled() {
- long beforeTime = System.currentTimeMillis();
- try {
- return proceed();
- } finally {
- long afterTime = System.currentTimeMillis();
- addToProfile(thisJoinPointStaticPart,
- afterTime - beforeTime);
- }
- }
- abstract void addToProfile(
- org.aspectj.JoinPoint.StaticPart jp,
- long elapsed);
- }
- ....
-
- In order to use either aspect, they must be extended with concrete
- aspects, say, MyLogging and MyProfiling. In AspectJ 1.0, it was not
- possible to express that Logging's advice (when concerned with the
- concrete aspect MyLogging) dominated Profiling's advice (when concerned
- with the concrete aspect MyProfiling) without adding a dominates clause
- to Logging itself. In AspectJ 1.1, we can express that constraint with a
- simple:
-
- [source, java]
- ....
- declare precedence: MyLogging, MyProfiling;
- ....
-
- ==== Changing order of advice for sub-aspects
-
- By default, advice in a sub-aspect has more precedence than advice in a
- super-aspect. One use of the AspectJ 1.0 dominates form was to change
- this precedence:
-
- [source, java]
- ....
- abstract aspect SuperA dominates SubA {
- pointcut foo(): ... ;
-
- before(): foo() {
- // in AspectJ 1.0, runs before the advice in SubA
- // because of the dominates clause
- }
- }
-
- aspect SubA extends SuperA {
- before(): foo() {
- // in AspectJ 1.0, runs after the advice in SuperA
- // because of the dominates clause
- }
- }
- ....
-
- This no longer works in AspectJ 1.1, since declare precedence only
- matters for concrete aspects. Thus, if you want to regain this kind of
- precedence change, you will need to refactor your aspects.
-
- [[SOURCEROOT]]
- === The -sourceroots option
-
- The AspectJ 1.1 compiler now accepts a -sourceroots option used to pass
- all .java files in particular directories to the compiler. It takes
- either a single directory name, or a list of directory names separated
- with the CLASSPATH separator character (":" for various Unices, ";" for
- various Windows).
-
- So, if you have your project separated into a gui module and a base
- module, each of which is stored in a directory tree, you might use one
- of
-
- [source, text]
- ....
- ajc -sourceroots /myProject/gui:/myProject/base
- ajc -sourceroots d:\myProject\gui;d:\myProject\base
- ....
-
- This option may be used in conjunction with lst files, listing .java
- files on the command line, and the -injars option.
-
- [[BYTECODE_WEAVING]]
- === The -injars option
-
- The AspectJ 1.1 compiler now accepts an -injars option used to pass all
- .class files in a particular jar file to the compiler. It takes either a
- single directory name, or a list of directory names separated with the
- CLASSPATH separator character (":" for various Unices, ";" for various
- Windows).
-
- So, if MyTracing.java defines a trace aspect that you want to apply to
- all the classes in myBase.jar and myGui.jar, you would use one of:
-
- [source, text]
- ....
- ajc -injars /bin/myBase.jar:/bin/myGui.jar MyTracing.java
- ajc -injars d:\bin\myBase.jar;d:\bin\myGui.jar MyTracing.java
- ....
-
- The class files in the input jars must not have had advice woven into
- them, since AspectJ enforces the requirement that advice is woven into a
- particular classfile only once. So if the classfiles in the jar file are
- to be created with the ajc compiler (as opposed to a pure Java
- compiler), they should not be compiled with any non-abstract aspects.
-
- This option may be used in conjunction with lst files, listing .java
- files on the command line, and the -sourceroots option.
-
- [[OUTJAR]]
- === The -outjar option
-
- The -outjar option takes the name of a jar file into which the results
- of the compilation should be put. For example:
-
- [source, text]
- ....
- ajc -injars myBase.jar MyTracing.java -outjar myTracedBase.jar
- ....
-
- No meta information is placed in the output jar file.
-
- [[INCREMENTAL]]
- === Incremental compilation
-
- The AspectJ 1.1 compiler now supports incremental compilation. When ajc
- is called with the -incremental option, it must also be passed a
- -sourceroots option specifying a directory to incrementally compile.
- Once the initial compile is done, ajc waits for console input. Every
- time it reads a new line (i.e., every time the user hits return) ajc
- recompiles those input files that need recompiling.
-
- ==== Limitations
-
- This new functionality is still only lightly tested.
-
- [[XNOWEAVE]]
- === -XnoWeave, a compiler option to suppress weaving
-
- The -XnoWeave option suppresses weaving, and generates classfiles and
- that can be passed to ajc again (through the -injars option) to generate
- final, woven classfiles.
-
- This option was originally envisioned to be the primary way to generate
- binary aspects that could be linked with other code, and so it was
- previously (in AspectJ 1.1beta1) named `-noweave`. We feel that using
- the `-aspectpath` option is a much better option. There may still be use
- cases for unwoven classfiles, but we've moved the flag to experimental
- status.
-
- [[BINARY_ASPECTS]]
- === -aspectpath, working with aspects in .class/.jar form
-
- When aspects are compiled into classfiles, they include all information
- necessary for the ajc compiler to weave their advice and deal with their
- inter-type declarations. In order for these aspects to have an effect on
- a compilation process, they must be passed to the compiler on the
- -aspectpath. Every .jar file on this path will be searched for aspects
- and any aspects that are found will be enabled during the compilation.
- The binary forms of this aspects will be untouched.
-
- [[NO_CALLEE_SIDE_CALL]]
- === Callee-side call join points
-
- The 1.0 implementation of AspectJ, when given:
-
- [source, java]
- ....
- class MyRunnable implements Runnable {
- public void run() { /*...*/ }
- }
-
- aspect A {
- call(): (void run()) && target(MyRunnable) {
- // do something here
- }
- }
- ....
-
- would cause A's advice to execute even when, say, java.lang.Thread
- called run() on a MyRunnable instance.
-
- With the new compiler, two things have happened in regard to callee-side
- calls:
-
- . because the programmer has access to more code (i.e., bytecode, not
- just source code), callee-side calls are much less important to have.
- . because compilation is more modular, allowing and encouraging separate
- compilation, callee-side calls are much more difficult to implement
-
- With these two points in mind, advice in an aspect will not be applied
- to call join points whose call site is completely unavailable to the
- aspect.
-
- . One reason (though not the only reason) we worked so hard in the
- _implementation_ of 1.0.6 to expose call join points, even if we only
- had access to the callee's code, was that otherwise users couldn't get
- access to call join points where the call was made from bytecode. This
- is no longer the case. In short, the implementation controls much more
- code (or has the capability to) than ever before.
- . The implementation model for the AspectJ 1.1 compiler is to separate
- the compilation of aspects/advice from their weaving/linking. A property
- of the model is that the compilation requires no access to "target"
- code, only the weaving/linking does, and weaving/linking is inherently
- per-class local: No action at weaving/linking time depends on the
- coordinated mangling of multiple classfiles. Rather, all weaving is done
- on a per classfile basis. This is an essential property for the current
- separate compilation model. +
- However, allowing implementation of call advice on either side requires
- simultaneous knowledge of both sides. If we first have access to a call,
- we can't decide to simply put the advice on the call site, since later
- we may decide to implement on the callee.
-
- This implementation decision is completely in the letter and the spirit
- of the AspectJ language. From the semantics guide describing code the
- implementation controls:
-
- ____
- But AspectJ implementations are permitted to deviate from this in a
- well-defined way -- they are permitted to advise only accesses in _code
- the implementation controls_. Each implementation is free within certain
- bounds to provide its own definition of what it means to control code.
- ____
-
- And about a particular decision about the 1.0.6 implementation:
-
- ____
- Different join points have different requirements. Method call join
- points can be advised only if ajc controls _either_ the code for the
- caller or the code for the receiver, and some call pointcut designators
- may require caller context (what the static type of the receiver is, for
- example) to pick out join points.
- ____
-
- The 1.1 implementation makes a different design decision: Method call
- join points can be advised only if ajc (in compiler or linker form)
- controls the code for the caller.
-
- What does 1.1 gain from this?
-
- * a clear (and implemented) separate compilation model (see point 2,
- above)
- * a less confusing interaction between call join points and the
- thisJoinPoint reflective object: We still get bug reports about source
- information sometimes existing and sometimes not existing at call join
- points.
-
- What does 1.1 lose from this?
-
- * The ability to capture all calls to Runnable.run() from anywhere to
- code ajc has access too, even from Thread, even if you don't compile
- java.lang with ajc.
- * The ability to, without access to the caller, capture entry to a
- particular method, but not super calls.
- * A code-size-improvement performance optimization.
-
- What are the possibilities for the future?
-
- * AspectJ 1.1.1 could expand its capture of call join points, possibly
- at the expense of separate compilation clarity, possibly not.
- * AspectJ 1.1.1 could re-introduce reception join points from AspectJ
- 0.7 (what callee-side call join points actually are): though they would
- never ever be taught in a tutorial or entry-level description of the
- model, they may have specialized uses.
-
- How will this affect developers?
-
- * When using the call PCD but only supplying the callee code, supply the
- calling code or use the execution PCD instead.
-
- [[OTHER_X_OPTIONS]]
- === Various -X options
-
- The AspectJ 1.0 compiler supported a number of options that started with
- X, for "experimental". Some of them will not be supported in 1.1, either
- because the "experiment" succeeded (in which case it's part of the
- normal functionality) or failed. Others will be supported as is (or
- nearly so) in 1.1:
-
- * -XOcodeSize: This is no longer necessary because inlining of around
- advice is on by default. We support its inverse,
- xref:#XNOINLINE[`-XnoInline`].
- * xref:#XNOWEAVE[-XnoWeave, a compiler option to suppress weaving]
- * -XtargetNearSource: Not supported in this release.
- * -XserializableAspects: Supported.
- * -XaddSafePrefix: This option will not be supported in 1.1 at all
- because we're now always using (what we believe to be) safe prefixes.
- * -Xlint: Still supported, with xref:#XLINT[various options].
-
- [[ERROR_MESSAGES]]
- === Some confusing error messages
-
- Building on the eclipse compiler has given us access to a very
- sophisticated problem reporting system as well as highly optimized error
- messages for pure Java code. Often this leads to noticeably better error
- messages than from ajc-1.0.6. However, when we don't handle errors
- correctly this can sometimes lead to cascading error messages where a
- single small syntax error will produce dozens of other messages. Please
- report any very confusing error messages as bugs.
-
- [[MESSAGE_CONTEXT]]
- === Source code context is not shown for errors and warnings detected during bytecode weaving
-
- For compiler errors and warnings detected during bytecode weaving,
- source code context will not be displayed. In particular, for declare
- error and declare warning statements, the compiler now only emits the
- file and line. We are investigating ways to overcome this in cases where
- the source code is available; in cases where source code is not
- available, we might specify the signature of the offending code. For
- more information, see bug 31724.
-
- [[XLINT]]
- === The -Xlint option
-
- `-Xlint:ignore,error,warning` will set the level for all Xlint warnings.
- `-Xlint`, alone, is an abbreviation for `-Xlint:warning`.
-
- The `-Xlintfile:lint.properties` allows fine-grained control. In
- tools.jar, see `org/aspectj/weaver/XlintDefault.properties` for the
- default behavior and a template to copy.
-
- More `-Xlint` warnings are supported now, and we may add disabled
- warnings in subsequent bug-fix releases of 1.1. Because the
- configurability allows users to turn off warnings, we will be able to
- warn about more potentially dangerous situations, such as the
- potentially unsafe casts used by very polymorphic uses of proceed in
- around advice.
-
- [[NO_SOURCE]]
- === Source-specific options
-
- Because AspectJ 1.1 does not generate source code after weaving, the
- source-code-specific options -preprocess, -usejavac, -nocomment and
- -workingdir options are meaningless and so not supported.
-
- [[NO_STRICT_LENIENT]]
- === The -strict and -lenient options
-
- Because AspectJ 1.1 uses the Eclipse compiler, which has its own
- mechanism for changing strictness, we no longer support the -strict and
- -lenient options.
-
- [[NO_PORTING]]
- === The -porting option
-
- AspectJ 1.1 does not have a -porting option.
-
- [[_13_REQUIRED]]
- === J2SE 1.3 required
-
- Because we build on Eclipse, the compiler will no longer run under J2SE
- 1.2. You must run the compiler (and all tools based on the compiler)
- using J2SE 1.3 or later. The code generated by the compiler can still
- run on Java 1.1 or later VM's if compiled against the correct runtime
- libraries.
-
- [[DEFAULT_CONSTRUCTOR_CONFLICT]]
- === Default constructors
-
- AspectJ 1.1 does not allow the inter-type definition of a zero-argument
- constructor on a class with a visible default constructor. So this is no
- longer allowed:
-
- [source, java]
- ....
- class C {}
-
- aspect A {
- C.new() {} // was allowed in 1.0.6
- // is a "multiple definitions" conflict in 1.1
- }
- ....
-
- In the Java Programming Language, a class defined without a constructor
- actually has a "default" constructor that takes no arguments and just
- calls `super()`.
-
- This default constructor is a member of the class like any other member,
- and can be referenced by other classes, and has code generated for it in
- classfiles. Therefore, it was an oversight that AspectJ 1.0.6 allowed
- such an "overriding" inter-type constructor definition.
-
- [[SUPER_IFACE_INITS]]
- === Initialization join points for super-interfaces
-
- In AspectJ, interfaces may have non-static members due to inter-type
- declarations. Because of this, the semantics of AspectJ defines the
- order that initializer code for interfaces is run.
-
- In the semantics document for AspectJ 1.0.6, the following promises were
- made about the order of this initialization:
-
- . a supertype is initialized before a subtype
- . initialized code runs only once
- . initializers for supertypes run in left-to-right order
-
- The first two properties are important and are preserved in AspectJ 1.1,
- but the third property is and was ludicrous, and was never properly
- implemented (and never could be) in AspectJ 1.0.6. Consider:
-
- [source, java]
- ....
- interface Top0 {}
- interface Top1 {}
- interface I extends Top0, Top1 {}
- interface J extends Top1, Top0 {}
-
- class C implements I, J {}
- // I says Top0's inits must run before Top1's
- // J says Top1's inits must run before Top0's
-
- aspect A {
- int Top0.i = foo("I'm in Top0");
- int Top1.i = foo("I'm in Top1");
- static int foo(String s) {
- System.out.println(s);
- return 37;
- }
- }
- ....
-
- This was simply a bug in the AspectJ specification. The correct third
- rule is:
-
- ____
- the initializers for a type's superclass are run before the initializers
- for its superinterfaces.
- ____
-
- [[VOID_FIELD_SET]]
- === Field Set Join Points
-
- In AspectJ 1.0.6, the join point for setting a field F had, as a return
- type, F's type. This was "java compatible" because field assignment in
- java, such as "Foo.i = 37", is in fact an expression, and does in fact
- return a value, the value that the field is assigned to.
-
- This was never "java programmer compatible", however, largely because
- programmers have absorbed the good style of rarely using an assignment
- statement in a value context. Programmers typically expect "Foo.i = 37"
- not to return a value, but to simply assign a value.
-
- Thus, programmers typically wanted to write something like:
-
- [source, java]
- ....
- void around(): set(int Foo.i) {
- if (theSetIsAllowed()) {
- proceed();
- }
- }
- ....
-
- And were confused by it being a compile-time error. They weren't
- confused for long, and soon adapted to writing:
-
- [source, java]
- ....
- int around(): set(int Foo.i) {
- if (theSetIsAllowed()) {
- return proceed();
- } else {
- return Foo.i;
- }
- }
- ....
-
- But there was definitely a short disconnect.
-
- On top of that, we were never shown a convincing use-case for returning
- an interesting value from a set join point. When we revisited this
- issue, in fact, we realized we had a long-standing bug in 1.0.6 dealing
- with the return value of pre-increment expressions (such as ++Foo.i)
- that nobody had found because nobody cares about the return value of
- such join points.
-
- So, because it's easier to implement, and because we believe that this
- is the last possibility to make the semantics more useful, we have made
- set join points have a void return type in 1.1.
-
- [[XNOINLINE]]
- === The -XnoInline Option
-
- The `-XnoInline` option to indicate that no inlining of any kind should
- be done. This is purely a compiler pragma: No program semantics (apart
- from stack traces) will be changed by the presence or absence of this
- option.
-
- [[TARGET_TYPES_MADE_PUBLIC]]
- === Target types made public
-
- Even in 1.0.6, the AspectJ compiler has occasionally needed to convert
- the visibility of a package-level class to a public one. This was
- previously done in an ad-hoc basis that took whole-program analysis into
- account. With the incremental compilation model of AspectJ 1.1, we can
- now specify the occasions when the compiler makes these visibility
- changes.
-
- In particular, the types used in the `this`, `target`, and `args`
- pointcuts are made public, as are the super-types from `declare parents`
- and the exception type from `declare soft`.
-
- We believe the visibility changes could be avoided in the future with
- various implementation tricks if they become a serious concern, but did
- not encounter them as such a concern when they were done in the 1.0.6
- implementation.
-
- [[STRINGBUFFER]]
- === String + now advised
-
- In Java, the + operator sometimes results in StringBuffer objects being
- created, appended to, and used to generate a new String. Thus,
-
- [source, java]
- ....
- class Foo {
- String makeEmphatic(String s) {
- return s + "!";
- }
- }
- ....
-
- is approximately the same at runtime as
-
- [source, java]
- ....
- class Foo {
- String makeEmphatic(String s) {
- return new StringBuffer(s).append("!").toString();
- }
- }
- ....
-
- In the design process of AspectJ 1.0.6 we didn't expose those
- StringBuffer methods and constructors as join points (though we did
- discuss it), but in 1.1 we do.
-
- This change is likely to affect highly wildcarded aspects, and can do so
- in surprising ways. In particular:
-
- [source, java]
- ....
- class A {
- before(int i): call(* *(int)) && args(i) {
- System.err.println("entering with " + i);
- }
- }
- ....
-
- may result in a stack overflow error, since the argument to println is
- really
-
- [source, java]
- ....
- new StringBuffer("entering with ").append(i).toString()
- ....
-
- which has a call to StringBuffer.append(int). In such cases, it's worth
- restricting your pointcut, with something like one of:
-
- [source, java]
- ....
- call(* *(int)) && args(i) && !within(A)
- call(* *(int)) && args(i) && !target(StringBuffer)
- ....
-
- [[ONE_FOUR_METHOD_SIGNATURES]]
- === The -1.4 flag and method signatures
-
- Consider the following aspect
-
- [source, java]
- ....
- public aspect SwingCalls {
-
- pointcut callingAnySwing(): call(* javax.swing..*+.*(..));
-
- before(): callingAnySwing() {
- System.out.println("Calling any Swing");
- }
- }
- ....
-
- And then consider the two statements
-
- [source, java]
- ....
- JFrame frame = new JFrame();
- frame.setTitle("Title");
- ....
-
- According to the Java Language Specification version 2, the call to
- `frame.setTitle("Title")` should always produce the bytecode for a call
- to `javax.swing.JFrame.setTitle`. However, older compilers (and eclipse
- when run without the `-1.4` flag) will generate the bytecode for a call
- to `java.awt.Frame.setTitle` instead since this method is not overriden
- by JFrame. The AspectJ weaver depends on the correctly generated
- bytecode in order to match patterns like the one you show correctly.
-
- This is a good example of why the pattern
- `call(* *(..)) && target(JFrame)` is the recommended style. In general,
- OO programmers don't want to care about the static type of an object at
- a call site, but only want to know the dynamic instanceof behavior which
- is what the target matching will handle.
-
- [[knownLimitations]]
- == Known limitations
-
- The AspectJ 1.1.0 release contains a small number of known limitations
- relative to the AspectJ 1.1 language. For the most up-to-date
- information about known limitations in an AspectJ 1.1 release, see the
- bug database at https://bugs.eclipse.org/bugs, especially the open bugs
- for the
- https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Compiler&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[compiler],
- https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=IDE&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[IDE
- support],
- https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Doc&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[documentation],
- and
- https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&component=Ant&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED[Ant
- tasks]. Developers should know about bugs marked with the "info" keyword
- because those bugs reflect failures to implement the 1.1 language
- perfectly. These might be fixed during the 1.1 release cycle; find them
- using the query
- https://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info
- For ajc's 1.1 implementation limitations, see
- link:progguide/implementation.html[Programming Guide Appendix:
- "Implementation Notes"].
|