Differences with ajc
The reference implementation of AspectJ is ajc. We have attempted to stay very close to ajc, in particular by adopting the same test suite, and by actively seeking out "corner" cases in the language on which to compare the two compilers. In a number of minor ways, however, the abc team has deliberately chosen to deviate from the standard set by ajc. This page describes the language differences between abc 1.1.0 and ajc 1.2.1. There are more recent releases of ajc, leading up to 1.5.0, which supports Java 5 features. At this moment abc does not support any Java 5 features: no annotations, no generics.- abc does not support separate compilation of aspects. All aspects must be provided in source form; normal Java code may be supplied either as source or bytecode.
- abc does not support load-time weaving.
- abc does not give any warnings about changes in the serial version UIDs of compiled classses caused by introduced members.
- abc takes a different approach to the new
keywords introduced
in AspectJ. In ajc the AspectJ-specific
keywords are also
allowed to be used as identifiers. In abc we
follow the
design of Java in that we clearly distinguish between identifiers
and keywords. Specifically, in abc the set of
new keywords depends on the context:
- in Java classes: normal Java keywords, plus aspect, privileged and pointcut.
- in aspects, we have all the keywords of Java classes, plus after, around, before, declare, issingleton, percflow, percflowbelow, pertarget, perthis, proceed
- in pointcuts, none of the above. The new keyword set is adviceexecution, args, call, cflow, cflowbelow, error, execution, error, execution, get, handler, if, initialization, parents, precedence, preinitialization, returning, set, soft, staticinitialization, target, this, throwing, warning, within, withincode.
- ajc allows the parentheses around IOException in
declare soft: (IOException): module();However, even ajc only allows a type in that position, and there is no other place in Java where types may be parenthesised. abc therefore forbids these parentheses. - abc generally gives a range of line numbers for errors and warnings where appropriate. Also, for errors or warnings regarding staticinitialization join points, abc reports the entire class whereas ajc reports the first line of any static blocks or static field initializations if, or the line of the class declaration otherwise. This affects both declare warning/declare error and static join point information.
- abc does not support compiling the class foo.Bar from a file Bar.java; you must make sure Bar resides in a directory that matches the package name, so foo/Bar.java (or some deeper path such as a/foo/Bar.java).
- In situations where a particular kind of advice is not supported, abc always reports it as a warning. ajc's behaviour is somewhat inconsistent - it considers after advice on handlers as warnings, but around advice on interface static initializers as errors.
- If a name pattern says OuterClass.*, in abc it will just match all member classes of OuterClass, whereas in ajc it will also match anonymous classes whose immediate enclosing class is OuterClass. This is somewhat related to ajc bug 73050.
- abc always takes shadowing of class names (an inner class hiding the definition of a class defined further out) into account when doing name pattern matching. ajc only does this for name patterns that are simple names. This is described in detail in ajc bug 73073.
- abc is a little more liberal than ajc in handling intertype declarations. It only requires that the final result of overriding is unambiguous. For example, if I1 and I2 are interfaces, and we introduce a member of the same signature into I1 and I2, and also onto a class C that implements both these interfaces, then the introduction on C overrides both interface introductions, and the result is unambiguous. ajc reports an error in these circumstances.
- abc always reports an error if a program contains recursively defined named pointcuts. ajc only reports an error if such a pointcut is actually used.
- In abc, the initialization join point of an interface (which occurs in constructors of classes implementing that interface) encloses the initialisers of fields introduced to that interface by intertype declarations. In ajc, the join point seems to be always empty.
- In abc, when a type reference in a pointcut declaration is not found, an error message is issued and compilation is terminated. ajc on the other hand would simply issue a warning message for that matter. This behavior is described in abc bug report #75.
Additional features
abc has a number of features that are not supported by ajc. Among these are the following:- abc can optionally give warnings when the precedence between multiple pieces of advice at a given shadow is ambiguous. To turn this on, use the option -debug warnPrecAmbiguity=true. Often this is very useful in debugging systems that involve a large number of aspects.
- abc has optional support for nested comments (things like /* ... /* ... */ */). To enable this, use the -nested-comments command-line switch (alternatively, specify the long form of -nested-comments:on or -nested-comments:true). You can explicitly disable nested comments by specifying -nested-comments:off or -nested-comments:false, if several of these options are specified, the last one takes effect.
- Unlike ajc, abc supports around advice on initialization. We would be interested to hear of situations where this leads to problems such as unverifiable code. We have removed the support we previously had for around advice on preinitialization as this definitely can lead to unverifiable code (see bug 30).
- abc allows alternative argument bindings in
pointcuts, as in
(args(x,..) || args(..,x)) && if(x==0)
The semantics of such bindings is defined by rewriting to disjunctive normal form (by distributing atomic conjuncts leftwards). The first disjunct in the normal form that succeeds is the binding passed to the advice body. This is supported with all forms of advice, including around. ajc does not currently support alternative argument bindings (see ajc bug 61568). - Contrary to its documentation, ajc insists on the parentheses in issingleton() (rather than issingleton). abc allows both.
- abc supports using declare parents on classes supplied as bytecode, which is not supported by the current ajc implementation.
Bugs
The following is a list of differences with ajc that we consider bugs in abc. Contrary to the above differences (which are by design), we aim to resolve these when possible. If you would like us to increase the priority we give to fixing a particular problem, please let us know on the mailing lists, or by using Bugzilla to vote for the appropriate bug, if any.
One of the items relates to options supported by ajc but not abc. There are many other options that we also do not support, but do not currently plan to ever support. If one of these is important to you, let us know and we will consider adding it.
Please also see the Bugzilla database for a more comprehensive list of known bugs.
- ajc flags an error when an intertype declaration attempts to override an existing private class member in the target. abc implements the behaviour that ajc used to have (up to including version 1.2), namely to silently replace the existing private member. The correct behaviour would be to rename the private member (see bug 6).
- abc does not yet support the -deprecation option.
- abc does not yet support string concatenation in the message for declare warning or declare error.