Hello,
I'm trying to find a way to introduce a member in another type via ITD but
making sure it is safe published. According to the Java Memory Model, all
final fields are guaranteed to be safe published after the constructor
execution ends and everything not final is not guaranteed to ever be seen
by another threads, so if I don't want to make use of synchronization I
better make sure my things are final.. For the use case I have in hand, I'm
trying to make a Runnable keep some information from the thread in which it
was created and make it available to the thread in which it will be later
run, a stub of what I did is this:
Aspect:
privileged public aspect ContextAware {
private final TraceContext MyRunnable.context = TraceContext.current();
}
Runnable (scala code, also tried java and the effects are the same):
class MyRunnable extends Runnable {
def run() {}
}
so far so good, but de-compiling the weaved MyRunnable class showed me
something pretty different to what I was expecting:
public class MyRunnable
implements Runnable
{
public void run()
{
}
public MyRunnable()
{
*
ContextAware.ajc$interFieldInit$kamon_instrumentation_ContextAware$kamon_instrumentation_MyRunnable$context(this);
*
}
public static TraceContext ajc$get$context(MyRunnable myrunnable)
{
return myrunnable.context;
}
public static void ajc$set$context(MyRunnable myrunnable, TraceContext
tracecontext)
{
myrunnable.context = tracecontext;
}
*private TraceContext context;*
}
The "context" member in the weaved class is not final and the delegation on
ajc$... for initializing the field seems unnecessary.. If it is a ITD
member and the weaver is already putting some code inside the constructor
to initialize a field that is supposed to be final, why the weaver is not
just leaving the field as final and putting "context =
TraceContext.current()" instead of "ContextAware.ajc$...." in the
constructor?.. Maybe I'm doing something wrong, or I have wrong assumptions
on how aspectj works.
I also tried using a perthis aspect with the context member in it and even
while in that case the aspect constructor looks exactly how I expected it
to be, I couldn't get to understand if the binding between the aspect
instance and the runnable instance happens in a way that make sure it will
be available to other threads.
The only way in which I managed this to work as I needed was to declare a
parent class for MyRunnable which for this case works fine, but as soon as
the target class extends another class then this is no longer viable...
even the common pattern of declaring a empty interface, introducing members
to it and the declare it as parent produces non-final members.. I hope that
someone can help me with this!
best regards,
Ivan
_______________________________________________
aspectj-users mailing list
[email protected]
https://dev.eclipse.org/mailman/listinfo/aspectj-users