java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查

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

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值