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图。

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查_第1张图片

 

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查_第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类。


            com.sinochem.yunlian.truck
            yunlian-truck-auth-client
            1.0-SNAPSHOT
            
                
                    org.springframework.boot
                    spring-boot-starter-security
                
            
        

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查_第3张图片

该异常在refresh方法中进行了throw出来。

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy排查_第4张图片

 

总结:针对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

 

 

你可能感兴趣的:(java)