> "declare parents" is inherently prone to this kind of errors, cause
it is partially declarative and partially not.
yes. we have more limited control in LTW in the processing order than
we do in straight compilation, so can get into situations where we
can't do the right thing. Ideally a big fat warning should come out
when we get into this situation, if we are able to recognize it.
Also 'call' in a ltw scenario can be a real problem because the target
may or may not have been loaded and processed. (suppose it was
call(@foo * *(..)) with a declare @type: @foo elsewhere). I've half
built infrastructure to cope with this but turned it all off as I
don't see it occur that often in the wild.
There is a lot of work to do on hasMember support, which is why it is
still an experimental option, you might find the bug report relating
to it interesting: https://bugs.eclipse.org/bugs/show_bug.cgi?id=86818
as you'll see in the later comments I noted I had to make large
changes to how these things were dealt with:
- intertype declarations
- declare parents
- declare annotation
Unfortunately the implementation was on a machine whose hard drive got
corrupted (sigh)... and I haven't been able to face doing all that
work again yet !
2009/8/12 Simone Gianni <simoneg@xxxxxxxxxx <mailto:simoneg@xxxxxxxxxx>>
I noticed that, using LTW, there is a difference in how declare
parents is applied depending on the load order. In many many
cases, this can go completely unnoticed or be completely legal,
but in some others it is not. In my case I'm using the
experimental hasmethod, but probably it could happen also using
other kind of type patterns.
The case is when I'm declaring a parent unless the superclasses
already have that parent. If parent classes are loaded before
subclasses, it works perfectly, otherwise it injects the
interface/methods in the subclasses and later also on the
superclasses. This IS valid Java by itself, but it is a problem
when other frameworks (like JPA) use reflection to determine which
methods or interfaces a certain class has, and they mandate that
some of those methods must be present only on the topmost classes
and not be overridden on subclasses.
I can see that AspectJ resolves also superclasses (maybe it does
that only sometimes?) and weaves them in the meanwhile
(GeneratedClassHandler.acceptClass should serve this purpose), so
this should not theoretically happen, unless :
- Not all join points/patterns trigger superclass parsing
- It is dependent on the order of expressions in the pattern, for
example if it first checks for the presence of the interface and
then arrives to an expression requiring parsing of the superclass
- Parsing the parent does not take into account ITDs, the parent
is not weaved or not completely, or something similar happens.
"declare parents" is inherently prone to this kind of errors,
cause it is partially declarative and partially not. Think about
"declare parents : org.something.model.* && !(MyTracingInterface+)
: MyTracingInterface", it is declaratively speaking invalid, or
could apply the interface here and there, or should trigger a
weaving of all superclasses and apply it only to the topmost
weavable classes. It seems like this is driven by load sequence,
or by some other order dependent stuff.
I'm trying to create a test case to demonstrate the problem and
understand better how it happens, but probably in the mean time
you can point me in the right direction or stop me if you already
know the answer :D
Simone Gianni CEO Semeru s.r.l. Apache Committer
aspectj-dev mailing list
aspectj-dev mailing list