java.lang.ArrayStoreException 阐明
这个demo来说明奈何排查一个spring boot 1应用进级到spring boot 2时大概呈现的java.lang.ArrayStoreException
。
demo地点:https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-ArrayStoreException
demo里有两个模块,springboot1-starter
和springboot2-demo
。
在springboot1-starter
模块里,是一个简朴的HealthIndicator
实现
public class MyHealthIndicator extends AbstractHealthIndicator { @Override protected void doHealthCheck(Builder builder) throws Exception { builder.status(Status.UP); builder.withDetail("hello", "world"); } }
@Configuration @AutoConfigureBefore(EndpointAutoConfiguration.class) @AutoConfigureAfter(HealthIndicatorAutoConfiguration.class) @ConditionalOnClass(value = { HealthIndicator.class }) public class MyHealthIndicatorAutoConfiguration { @Bean @ConditionalOnMissingBean(MyHealthIndicator.class) @ConditionalOnEnabledHealthIndicator("my") public MyHealthIndicator myHealthIndicator() { return new MyHealthIndicator(); } }
springboot2-demo
则是一个简朴的spring boot2应用,引用了springboot1-starter
模块。
把工程导入IDE,执行springboot2-demo
里的ArrayStoreExceptionDemoApplication
,抛出的异常是
Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724) ~[na:1.8.0_112] at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) ~[na:1.8.0_112] at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) ~[na:1.8.0_112] at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) ~[na:1.8.0_112] at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) ~[na:1.8.0_112] at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[na:1.8.0_112] at java.lang.Class.createAnnotationData(Class.java:3521) ~[na:1.8.0_112] at java.lang.Class.annotationData(Class.java:3510) ~[na:1.8.0_112] at java.lang.Class.createAnnotationData(Class.java:3526) ~[na:1.8.0_112] at java.lang.Class.annotationData(Class.java:3510) ~[na:1.8.0_112] at java.lang.Class.getAnnotation(Class.java:3415) ~[na:1.8.0_112] at java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:258) ~[na:1.8.0_112] at java.lang.Class.isAnnotationPresent(Class.java:3425) ~[na:1.8.0_112] at org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(AnnotatedElementUtils.java:575) ~[spring-core-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.isHandler(RequestMappingHandlerMapping.java:177) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:217) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:188) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:129) ~[spring-webmvc-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1769) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1706) ~[spring-beans-5.0.4.RELEASE.jar:5.0.4.RELEASE] ... 16 common frames omitted
利用 Java Exception Breakpoint
下面来排查这个问题。
在IDE里,新建一个断点,范例是Java Exception Breakpoint
(假如不清楚怎么添加,可以搜索对应IDE的利用文档),异常类是上面抛出来的java.lang.ArrayStoreException
。
当断点起效时,查察AnnotationUtils.findAnnotation(Class<?>, Class<A>, Set<Annotation>) line: 686
函数的参数。
可以发明
class com.example.springboot1starter.MyHealthIndicatorAutoConfiguration$$EnhancerBySpringCGLIB$$945c1f
interface org.springframework.boot.actuate.endpoint.annotation.Endpoint
说明是实验从MyHealthIndicatorAutoConfiguration
里查找@Endpoint
信息时堕落的。