-
Bug
-
Resolution: Done
-
Major
-
1.5.1
-
None
An AT ENTRY rule for a constructor may not be injected at the start of the target constructor method because it is not legitimate to make callouts to non-constructor code before performing a call to either a superclass constructor or to a sibling constructor. Unfortunately, there is no easy way to ensure that either a superclass or sibling constructor has been called. The adapter class currently used for injection into constructors AT ENTRY uses a simple heuristic, viz: delay rule code injection until after the first INVOKESPECIAL call. Generally, the first INVOKESPECIAL fits the bill as a super/sibling call. However, in certain circumstances this heuristic fails.
The constructor for the subordinate transaction implementation class is one example where this heuristic leads to a verify error:
public TransactionImple (int timeout)
{ this(new SubordinateAtomicAction(timeout)); }The new operation which constructs a SubordinateAtomicAction results in an INVOKESPECIAL for method SubordinateAtomicAction.<init>(I)V being placed in the bytecode before the INVOKESPECIAL for method TransactionImple.<init>(AtomicAction)V which corresponds to the sibling constructor.
It may appear that a simple check will identify that SubordinateAtomicAction is not a super of TransactionImple, hence that the first INVOKESPECIAL call can simply be discounted as a super constructor call. Clearly, it is not a sibling constructor call. So, it ought to possible to use smarter test and hey presto no bug.
This is not quite so simple as it appears. Checking the super(s) hierarchy using reflection is not possible at injection time – the superclass and, indeed, its super(s) may not actually be loaded before a (sub)class is offered to the agent for transformation. However, it ought to be possible to identify the name of the immmediate super by inspection of the bytecode alone. So, this can probably be fixed as outlined above.