先看异常:
nested exception is java.lang.ArrayIndexOutOfBoundsException: 9578
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:76)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.importBeanDefinitionResource(DefaultBeanDefinitionDocumentReader.java:182)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:147)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:132)
at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:92)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:507)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:398)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:342)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:310)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:92)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:123)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:423)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:353)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
由于工程中配置了 扫描jar包,类比较多,不好定位,我在本地实现的测试,代码如下:
public class MyMetadataReader implements MetadataReader {
private final ClassReader classReader;
private final ClassLoader classLoader;
public MyMetadataReader(ClassReader classReader, ClassLoader classLoader) {
this.classReader = classReader;
this.classLoader = classLoader;
}
public ClassMetadata getClassMetadata() {
ClassMetadataReadingVisitor visitor = new ClassMetadataReadingVisitor();
this.classReader.accept(visitor, true);
return visitor;
}
public AnnotationMetadata getAnnotationMetadata() {
AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(this.classLoader);
this.classReader.accept(visitor, true);
return visitor;
}
}
测试:
ClassReader reader = new ClassReader(in);
MetadataReader metadataReader = new MyMetadataReader( reader, classLoader);
metadataReader.getAnnotationMetadata();
最终获取了 这个读取错误的class文件,发现,里面使用了java8的 lambda表达式特性
firstElements.forEach(e -> root.add(e.addAttribute("class","1").detach()));
secondElements.forEach(e -> root.add(e.addAttribute("class","2").detach()));
thirdElements.forEach(e -> root.add(e.addAttribute("class","3").detach()));
ClassReader 这个类在spring4.X中重写了,不禁要问,如果spring不升级到4.x,难道真的无法使用java8 新特性?如果是这样的话,真是个好大的坑!
经过测试,在Spring 2.5.5 使用注解扫描时,会使用到 类ComponentScanBeanDefinitionParser中的方法,进而会调用 ClassReader中的方法,则Spring无法正常初始化。