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