赞
踩
1、java.lang.ArrayStoreException这个的debug借助IDEA,添加Java Exception的java.lang.ArrayStoreException断点,这样异常时能够看到具体的报错Class
2、首先进入错误debug的是org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceBootstrapConfiguration
因为这个版本没有使用远程config,所以ConfigServicePropertySourceLocator的类是找不到,所以报了异常。
继续排查是能发现这个是BootstrapApplicationListener中的bootstrapServiceContext方法处理,异常是忽略的。
这个也是误导了自己,耗时有点长。debug可以看下面2图。
3、再次进入的是项目中的GlobalExceptionHandler类,原因也是出在这个类中。
这个类是common模块中的统一异常处理类,其他同事做的权限security,AccessDeniedException在security的jar中。
- @ExceptionHandler(AccessDeniedException.class)
- public ObjectRestResponse accessDeniedrExceptionHandler(HttpServletResponse response, Exception ex) {
- logger.error(ex.getMessage(), ex);
- ObjectRestResponse restResponse = new ObjectRestResponse();
- restResponse.setStatus(CodeStatus.PARAM_ACCESS_FORBIDDEN.getValue());
- restResponse.setMsg(CodeStatus.PARAM_ACCESS_FORBIDDEN.getName());
- return restResponse;
- }
而该module中的pom进行了exclusion,而yunlian-truck-auth-client模块中间接引用common模块,所以导致GlobalExceptionHandler找不到AccessDeniedException类。
- <dependency>
- <groupId>com.sinochem.yunlian.truck</groupId>
- <artifactId>yunlian-truck-auth-client</artifactId>
- <version>1.0-SNAPSHOT</version>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
该异常在refresh方法中进行了throw出来。
总结:针对java.lang.ArrayStoreException这样的异常通过IDEA进行进行debug,以及EurekaDiscoveryClientConfigServiceBootstrapConfiguration中的这个异常处理。
---------------------------------------------------------------
具体是java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy 数组越界的异常,为什么是class不存在导致的,是AnnotationParser.parseClassValue
把异常包装成为Object。
下面解释来自
https://yq.aliyun.com/articles/616541
仔细看下代码,可以发现AnnotationParser.parseClassValue
把异常包装成为Object
- //sun.reflect.annotation.AnnotationParser.parseClassValue(ByteBuffer, ConstantPool, Class<?>)
- 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<?>)
里尝试直接设置到数组里
- // sun.reflect.annotation.AnnotationParser.parseClassArray(int, ByteBuffer, ConstantPool, Class<?>)
- result[i] = parseClassValue(buf, constPool, container);
而这里数组越界了,ArrayStoreException
只有越界的Object
的类型信息,也就是上面的
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。