Constructor Execution Pointcut Causing ArrayOutOfBounds
nwhitehead Oct 1, 2010 5:30 PM==================================
==============Update==============
==================================
I noticed that some older beans that did not have the private ctors did not have this problem, so I updated my newer one to use public ctors and the issue went away. This is problematic though, and it is preferable in this case to have them be private.
My conjecture is that this is a bug in the advisor. The synthetic ctors are introduced to provide the advisor with access to the private natural ctors, but the resolveConstructorPointcut method does not take this into account when iterating through the array of constructors and referencing the constructorInfos at the same array index.
=====================================
Hello;
Java 1.6
JBoss AOP 2.1.8.GA
I have been wrestling with this for a while now. I have defined a pointcut for the execution of private constructors on classes annotated with @EntityTXAttribute. However, while the weaving is going on, an ArrayOutOfBounds exception occurs, and having run it through the debugger, it seems to make sense why, but I am noit sure how to fix it.
The pointcut expression is:
execution(public !static * @entitypojo.annotations.EntityTXAttribute->*(..))
OR execution(protected !static * @entitypojo.annotations.EntityTXAttribute->*(..))
OR execution(private @entitypojo.annotations.EntityTXAttribute->new(..))
or all public non-static methods in annotated classes, and all private constructors.
The method invocation interceptions work perfectly, btw.
My bean has 2 ctors, on parameterized and one not. I set a debugger break point on org.jboss.aop.Advisor line 1870 where the error occurs.
What I see is this:
The instance has an array called constructors which has 4 constructors in it, 2 of which I defined and 2 of which appear to be synthetic. They broadly look like this:
- private Bean() (mine)
- Bean(javassist.runtime.Inner) (synthetic)
- private Bean(String, String) (mine)
- Bean(String, String, javassist.runtime.Inner) (synthetic)
However, the array of constructorInfos only has 2 entries in it which are
- private Bean() (mine)
- private Bean(String, String) (mine)
The method code looks like this:
protected void resolveConstructorPointcut(AdviceBinding binding)
{
for (int i = 0; i < constructors.length; i++)
{
Constructor<?> constructor = constructors[i];
if (binding.getPointcut().matchesExecution(this, constructor))
{
if (AspectManager.verbose) logger.debug("constructor matched binding: " + constructor);
adviceBindings.add(binding);
binding.addAdvisor(this);
// this is where the error occurs. Line 1870.
pointcutResolved(constructorInfos[i], binding, new ConstructorJoinpoint(constructor));
// if we must keep track of deprecated fields and the field is already initialized
if (AspectManager.maintainAdvisorMethodInterceptors && constructorInterceptors != null)
{
constructorInterceptors[i] = constructorInfos[i].getInterceptors();
}
}
}
}
This code assumes the number of constructorInfos is at least the same as the number of constructors, but since it is not, it throws an array out of bounds exception.
Am I doing something wrong here, or is it a bug ?
Much appreciated.
//Nicholas