将某个项目从 Spring Boot1 升级 Spring Boot2 之后出现如下报错, 查了很多不同的解决方法都没有解决:
Spring boot2 项目启动时遇到了异常:
- java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
- Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
- at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724) ~[na:1.8.0_65]
- at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) ~[na:1.8.0_65]
- at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) ~[na:1.8.0_65]
- at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) ~[na:1.8.0_65]
- at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) ~[na:1.8.0_65]
- at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[na:1.8.0_65]
- at java.lang.Class.createAnnotationData(Class.java:3521) ~[na:1.8.0_65]
- at java.lang.Class.annotationData(Class.java:3510) ~[na:1.8.0_65]
- at java.lang.Class.createAnnotationData(Class.java:3526) ~[na:1.8.0_65]
- at java.lang.Class.annotationData(Class.java:3510) ~[na:1.8.0_65]
- at java.lang.Class.getAnnotation(Class.java:3415) ~[na:1.8.0_65]
- at java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:258) ~[na:1.8.0_65]
- at java.lang.Class.isAnnotationPresent(Class.java:3425) ~[na:1.8.0_65]
- at org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(AnnotatedElementUtils.java:570) ~[spring-core-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.isHandler(RequestMappingHandlerMapping.java:177) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.Web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:218) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.Web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:189) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.Web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:136) ~[spring-webmvc-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-5.0.9.RELEASE.jar:5.0.9.RELEASE]
- ... 16 common frames omitted
经过简单排查后, 怀疑是因为 jar 版本冲突引起的异常, 使用异常断点:
然后在
应该是从 class org.activiti.spring.boot.SecurityAutoConfiguration 出错, 然后报错 java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
尝试复现异常:
SecurityAutoConfiguration securityAutoConfiguration=new SecurityAutoConfiguration();
正常
SecurityAutoConfiguration.class.getDeclaredAnnotation(Aspect.class);
异常复现.
然后找到 TypeNotPresentExceptionProxy 类, 使用 Ctrl+N/Ctrl+N+N
然后在构造方法中打断点, 发现:
发现是 cause:DefaultAuthenticationEventPublisher 找不到引发的报错.
实际报错是 ClassNotFound.
仔细看下代码, 可以发现 AnnotationParser.parseClassValue 把异常包装成为 Object.
- private static Object parseClassValue(ByteBuffer buf,
- ConstantPool constPool,
- Class<?> container) {
- int classIndex = buf.getShort() & 0xFFFF;
- try {
- try {
- String sig = constPool.getUTF8At(classIndex);
- return parseSig(sig, container);
- } catch (IllegalArgumentException ex) {
- // support obsolete early jsr175 format class files
- return constPool.getClassAt(classIndex);
- }
- } catch (NoClassDefFoundError e) {
- return new TypeNotPresentExceptionProxy("[unknown]", e);
- }
- catch (TypeNotPresentException e) {
- return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
- }
- }
然后在 sun.reflect.annotation.AnnotationParser.parseClassArray(int, ByteBuffer, ConstantPool, Class<?>) 里尝试直接设置到数组里.
而这里数组越界了, ArrayStoreException 只有越界的 Object 的类型信息, 也就是上面的.
解决:
1: 将 springboot2.0 降级为原来的 1.X 版本
2: 在 springboot 启动类上添加
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
3: 修改源码的集成问题, 重新编译
总结:
具体问题还要具体分析, 不同的代码引发该问题的原因也不相同.
我的问题是:
springboot2.0 不能与 activiti6.0.0 直接集成使用, 因为 activiti6.0.0 出来的时候 springboot2.0 还没有出来, activiti6.0.0 支持 springboot1.2.6 以上, 2.0.0 以下的版本.
这里实际报错是 ClassNotFound.
来源: https://www.cnblogs.com/jiangwz/p/9711998.html