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类。
com.sinochem.yunlian.truck
yunlian-truck-auth-client
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-security
该异常在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