[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-dev] New intertype syntax ...new meaning?

2009/11/26 Ichthyostega <prg@xxxxxxxxxxxxxxx>:
> Now the goal of the change in mangling is to make this introduced field
> a first class citizen within the target class, right? Especially any
> framework which inspects private members (urghs) would get the impression
> that it was an integral part of the target class.

Yes, the idea that it was ITD'd is not apparent in the .class file and
it will look as if natively declared in the source code for the type.
There can be metadata in the class file tagging the field as special,
but only tools looking for that (eg. an aspectj weaver) would
understand it.

> How then would you be able to continue to provide such an error message?

Because the errors come out at compile time, when we are fully aware
of ITDs.  At compilation time the ITD is captured as an ITD field
declaration and not a normal field declaration.  Checking is done by
looking at how members are being referenced throughout the code being
compiled and because there is a distinction between a field and an ITD
field, the checking will remain the same and errors will get reported
as normal.  What will differ is when it comes time to produce the
bytecode for the ITD, we will give it a different name to what it had
before.  We don't check access rules at compile time based on the
bytecode form, because we haven't created the bytecode yet - that
comes last after at least all the visibility rules are satisfied.

> Let's assume we have the joyful enterprise application setup we're fighting
> with at my work job recently. I.e. we have Maven, and build several components,
> with library aspects "crossing the borders" to cover some aspects of
> integration.
>
> - Project Base : provides class A
> - Project Lib  : contains an aspect L to ITD class A with a private field
>
> - Project Int  : consumes the Base.jar processed by Lib. Now it contains a
>                 privileged aspect which tries to access the introduced field.
>                 Maybe it even processes any field of a certain type.

This goes back to my comment earlier today, where I said:

>>> - after the initial compilation, further binary weaves or reweaves may
>>> not be able to tell that ITDs were used (although not 100% thought
>>> this part through yet - it is possible they could with a big
>>> bunch-o-work on my part).

I guess you want me to think 100% through it now.... :)

There are a few options here.  Let's discuss them both in the context
of your project Int

> - Project Int  : consumes the Base.jar processed by Lib. Now it contains a
>                 privileged aspect which tries to access the introduced field.
>                 Maybe it even processes any field of a certain type.

It will likely make a difference whether base.jar is on the inpath or
classpath of Project Int as that may facilitate reweaving.  But let's
discuss the options:

option a:
Suppose I went full steam ahead with the idea that in the new world,
from the entry in the class file, any notion that the ITD came from an
aspect is gone, and there is no reweaving.  (I would like to remove
reweaving but due to how advice is implemented, that makes it very
tricky).

This would mean the privileged aspect in Int can see that private
field with its short name (unless the metadata tagging it is used to
tell us it came from an aspect over there).  This differs from today
where it can see it without even being privileged if it knows the
mangled name.
If the aspect attempted to discover all the private methods on the
target (in order to process them), it would see it.  This differs to
today where it would see it if is asked for the public members (and
the name will be mangled).

option b:
reweaving - what happens today.

If the base.jar is on the inpath (is it? so that the privileged aspect
can add further members to Base.jar contents?) then reweaving can
occur.  In this case the class in base.jar that was originally woven
will be reverted back to its original state prior to the application
of any ITDs or weaving, and they will all be reapplied (those from
project Lib and those from project Int) together  - because they are
all being applied together, AspectJ will check all the rules.  This is
what reweaving does today.  In this situation the privileged aspect
would *not* be able to see the field.

> OK, a privileged aspect can access any field anyway, but my point is that
> I am not sure at all what would be desirable here. And what would be self-evident?

I understand the point you are getting at, and there are a few
testcases to write to explore the space and ensure all bases are
covered and make sense.  I had hoped to start getting rid of reweaving
and lessen the amount of junk (sorry, metadata) we include in the
classfile.  But to support your point about a new privileged aspect
not being able to access a previously ITD'd private field, we would
need one or the other to continue to be used (either reweaving or
maintaining metadata).

> Along the same way of thought, why should the class itself be prevented to
> access a private member, which for all other facilities in the system looks
> as being a completely regular private member of this class?

The only way the class itself could access this private member when it
was compiled is if it was built by the aspectj compiler.  If it was
built by the aspectj compiler then the rules about accessing that
field could be enforced due to having full knowledge that it is an
ITD.

I think the point I'm trying to make is that AspectJ will still be
checking everything and all according to the rules of AspectJ ITD
visibility.  The thing that differs is just the bytecode and it is the
bytecode that impacts the downstream tools (which get either confused
or force the user to use some special annotations on the ITDs that
explicitly name fields for persistent because the ITD field name gets
mangled in the target).

You can see the metadata in the class file today:

class C { }
aspect X {
  int C.i;
}
ajc C.java Xaj -1.5
javap -private -verbose C
...
public int ajc$interField$$i;
  RuntimeVisibleAnnotations: length = 0x15
   00 01 00 10 00 03 00 11 73 00 02 00 12 73 00 13
   00 14 49 00 15
...

The annotation there, attached to the field, tells us it is ITD
introduced and some of the numbers there are constant pool references
which tell us which aspect it came from and how it was originally
declared...  So basically it doesn't matter to AspectJ what the field
is really called or its visibility, as AspectJ can see the metadata
and know what it was originally.

Thank heavens we don't support protected ITDs ;)  default visibility
ITDs are possibly more controversial than private ones, but that's
another thing I need to think through.

I appreciate you posing these kinds of question which make me think!

Andy