I have a hierarchy with the following dependencies:
Base(Timer timer)
Timer(PublisherService service, BaseDao userDao, DataProcessor processor)
There are additional dependencies within DataProcessor
but I will not go that far because it seems my error occurs a lot earlier. In correspondence with that dependency graph, I have the following Spring configuration:
<bean id="base" class="com.apps.consumer.Base">
<constructor-arg name="timer" ref="consumerTimerTask"/>
</bean>
<bean id="consumerTimerTask" class="com.apps.consumer.ConsumerTimerTask">
<constructor-arg name="service" ref="tradePublisherService"/>
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="consumerDataProcessor" ref="consumerDataProcessor"/>
</bean>
<bean id="tradePublisherService" class="com.apps.consumer.common.TradePublisherService"/>
<bean id="userDao" class="com.apps.dao.UserDao"/>
<bean id="consumerDataProcessor" class="com.apps.consumer.ConsumerDataProcessor">
<!-- Additional constructor-args here for this guy -->
</bean>
At the top level of my application, I will run:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-configuration.xml");
Base consumerBase = context.getBean("base", Base.class);
As I follow the debugging I find that the Timer
is initialized successfully. . .somewhat. Before the Timer
is fully resolved and injected into the Base
I get back the following:
java.lang.ArrayIndexOutOfBoundsException: 3145
at org.springframework.asm.ClassReader.readClass(Unknown Source)
at org.springframework.asm.ClassReader.accept(Unknown Source)
at org.springframework.asm.ClassReader.accept(Unknown Source)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.visitConstructor(LocalVariableTableParameterNameDiscoverer.java:123)
at org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:89)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:984)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:886)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:600)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:140)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:984)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:886)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:290)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:287)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:842)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:416)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.apps.Main.contextInitialized(Main.java:39)
I'm tracing it back as far as Main
which is the only class in the stack trace that is mine.
Removing all three constructor parameters in both Java and XML resolves the issue however introducing any one of the 3 constructor arguments brings it back. The dependency graph does go a little deeper for DataProcessor
for example, but even if I just use BaseDao
as the constructor args, which itself has no dependencies, I will get this error.
Any idea what is going on here? I have tried various permutations of constructor args, creating new interface implementations in case something in my existing ones was causing the issue to bubble up, pretty much everything shy of just rewriting this from scratch more carefully.
EDIT:
public class Base {
private TimerTask consumerTimerTask;
private static Logger logger = LoggerFactory.getLogger(Base.class);
public Base(TimerTask timer) {
this.consumerTimerTask = timer;
}
/**
* Initialize the timer.
* @throws Exception
*/
public void initialize() throws Exception {
final int updateFrequency = 10000;
// Once all fields have been generated and prefs read, initialize the update process every number of seconds.
final Timer updateTimer = new Timer();
updateTimer.scheduleAtFixedRate(this.consumerTimerTask, 0, updateFrequency);
logger.info("Base initialized successfully!");
}
}