Deep Spring Boot: How to troubleshoot Java.lang.ArrayStoreException

Source: Internet
Author: User
Tags throwable

java.lang.ArrayStoreException Analysis

This demo shows you how to troubleshoot a Spring boot 1 application that might appear when you upgrade to spring Boot 2 o'clock java.lang.ArrayStoreException .

Demo Address: Https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-ArrayStoreException

There are two modules in the demo, springboot1-starter and springboot2-demo .

In the springboot1-starter module, it's a simple HealthIndicator implementation.

 Public class extends abstracthealthindicator {    @Override    protectedvoidthrows  Exception {        builder.status (status.up);        Builder.withdetail ("Hello", "World");}    }
@Configuration @autoconfigurebefore (endpointautoconfiguration.class) @AutoConfigureAfter (healthindicatorautoconfiguration.class) @ConditionalOnClass (value= {Healthindicator.class }) Public classmyhealthindicatorautoconfiguration {@Bean @ConditionalOnMissingBean (myhealthindicator.class) @ConditionalOnEnabledHealthIndicator ("My")     Publicmyhealthindicator Myhealthindicator () {return NewMyhealthindicator (); }}

springboot2-demois a simple spring boot2 application that references the springboot1-starter module.

Import the project into the IDE, execute springboot2-demo in ArrayStoreExceptionDemoApplication , throw the exception is

caused by:java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy at Sun.reflect.annotation.AnnotationParser.parseClassArray (Annotationparser.java:724) ~[na:1.8. 0_112] at Sun.reflect.annotation.AnnotationParser.parseArray (Annotationparser.java:531) ~[na:1.8. 0_112] at Sun.reflect.annotation.AnnotationParser.parseMemberValue (Annotationparser.java:355) ~[na:1.8. 0_112] at Sun.reflect.annotation.AnnotationParser.parseAnnotation2 (Annotationparser.java:286) ~[na:1.8. 0_112] at Sun.reflect.annotation.AnnotationParser.parseAnnotations2 (Annotationparser.java:~[na:1.8). 0_112] at Sun.reflect.annotation.AnnotationParser.parseAnnotations (Annotationparser.java:~[na:1.8). 0_112] at Java.lang.Class.createAnnotationData (Class.java:3521) ~[na:1.8. 0_112] at Java.lang.Class.annotationData (Class.java:3510) ~[na:1.8. 0_112] at Java.lang.Class.createAnnotationData (Class.java:3526) ~[na:1.8. 0_112] at Java.lang.Class.annotationData (Class.java:3510) ~[na:1.8. 0_112] at java.lang.Class.getAnnotation (Class.java:3415) ~[na:1.8. 0_112] at Java.lang.reflect.AnnotatedElement.isAnnotationPresent (Annotatedelement.java:258) ~[na:1.8. 0_112] at Java.lang.Class.isAnnotationPresent (Class.java:3425) ~[na:1.8. 0_112] at Org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation ( Annotatedelementutils.java:575) ~[spring-core-5.0.4.release.jar:5.0.4. RELEASE] at Org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.isHandler ( Requestmappinghandlermapping.java:177) ~[spring-webmvc-5.0.4.release.jar:5.0.4. RELEASE] at Org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods ( Abstracthandlermethodmapping.java:217) ~[spring-webmvc-5.0.4.release.jar:5.0.4. RELEASE] at Org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet ( Abstracthandlermethodmapping.java:188) ~[spring-webmvc-5.0.4.release.jar:5.0.4. RELEASE] At Org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet ( Requestmappinghandlermapping.java:129) ~[spring-webmvc-5.0.4.release.jar:5.0.4. RELEASE] at Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods ( Abstractautowirecapablebeanfactory.java:1769) ~[spring-beans-5.0.4.release.jar:5.0.4. RELEASE] at Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean ( Abstractautowirecapablebeanfactory.java:1706) ~[spring-beans-5.0.4.release.jar:5.0.4. RELEASE] ...Common frames omitted
Using Java Exception Breakpoint

Below to troubleshoot this problem.

In the IDE, create a new breakpoint, the type is Java Exception Breakpoint (if you do not know how to add, you can search for the corresponding IDE's use of the document), the exception class is thrown above java.lang.ArrayStoreException .

When the breakpoint is working, look at AnnotationUtils.findAnnotation(Class<?>, Class<A>, Set<Annotation>) line: 686 the parameters of the function.

can find

    • Clazz isclass com.example.springboot1starter.MyHealthIndicatorAutoConfiguration$$EnhancerBySpringCGLIB$$945c1f
    • Annotationtype isinterface org.springframework.boot.actuate.endpoint.annotation.Endpoint

The description is an MyHealthIndicatorAutoConfiguration error when trying to find information from inside @Endpoint .

MyHealthIndicatorAutoConfigurationNot really @Endpoint , but why throw java.lang.ArrayStoreException ?

Try to reproduce the exception with a simple example

First try the direct new myhealthindicatorautoconfiguration:

 Public Static void Main (string[] args) {    new  myhealthindicatorautoconfiguration ();}

I thought I was going to throw an exception, but I found it normal.

If you look at the exception stack carefully, you can see that the at java.lang.Class.getDeclaredAnnotation(Class.java:3458) exception is thrown, then try the following code:

 Public Static void Main (string[] args) {    myhealthindicatorautoconfiguration. class. getdeclaredannotation (Endpoint.  Class);}

Found to be able to reproduce the exception:

Exception in thread "main"Java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy at Sun.reflect.annotation.AnnotationParser.parseClassArray (Annotationparser.java:724) at Sun.reflect.annotation.AnnotationParser.parseArray (Annotationparser.java:531) at Sun.reflect.annotation.AnnotationParser.parseMemberValue (Annotationparser.java:355) at Sun.reflect.annotation.AnnotationParser.parseAnnotation2 (Annotationparser.java:286) at Sun.reflect.annotation.AnnotationParser.parseAnnotations2 (Annotationparser.java:120) at Sun.reflect.annotation.AnnotationParser.parseAnnotations (Annotationparser.java:72) at Java.lang.Class.createAnnotationData (Class.java:3521) at Java.lang.Class.annotationData (Class.java:3510) at Java.lang.Class.getDeclaredAnnotation (Class.java:3458)
Why would it be java.lang.ArrayStoreException?

Look at the exception information again: Java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy

ArrayStoreExceptionis an array of out-of-bounds exceptions, it has only one string message, and it does not cause .

Then we try to sun.reflect.annotation.TypeNotPresentExceptionProxy break the point in the constructor.

 Public class extends exceptionproxy {    privatestaticfinallong serialversionuid = 5565925172427947573L;    String TypeName;    Throwable cause;       Public Typenotpresentexceptionproxy (String typeName, throwable cause) {        this. TypeName=  TypeName;         this. Cause = cause;    }

In the breakpoint, we can find:

    • TypeName isorg.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration
    • Cause isjava.lang.ClassNotFoundException: org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration

Finally the truth, is not found org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration this class.

So how does it turn out ArrayStoreException to be?

Take a closer look at the code, and you'll find that AnnotationParser.parseClassValue wrapping the exceptionObject

//Sun.reflect.annotation.AnnotationParser.parseClassValue (Bytebuffer, Constantpool, class<?>)    Private StaticObject Parseclassvalue (bytebuffer buf, Constantpool Constpool, Class<?>container) {        intClassindex = Buf.getshort () & 0xFFFF; Try {            Try{String sig=Constpool.getutf8at (Classindex); returnParsesig (sig, Container); } Catch(IllegalArgumentException ex) {//Support obsolete early jsr175 format class files                returnConstpool.getclassat (Classindex); }        } Catch(Noclassdeffounderror e) {return NewTypenotpresentexceptionproxy ("[Unknown]", E); }        Catch(typenotpresentexception e) {return NewTypenotpresentexceptionproxy (E.typename (), E.getcause ()); }    }

And then sun.reflect.annotation.AnnotationParser.parseClassArray(int, ByteBuffer, ConstantPool, Class<?>) try to set it directly into the array.

// sun.reflect.annotation.AnnotationParser.parseClassArray (int, bytebuffer, Constantpool, class<?>) Result[i] = Parseclassvalue (buf, Constpool, container);

And here the array is out of bounds, ArrayStoreException only the Object type information, which is above

Java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy
Solve the problem

Found Yes java.lang.ClassNotFoundException: org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration , then add @ConditionalOnClass the check to be able to:

@Configuration @autoconfigurebefore (endpointautoconfiguration. class ) @AutoConfigureAfter (healthindicatorautoconfiguration. class  = {healthindicator.  Class, Endpointautoconfiguration. class })publicclass Myhealthindicatorautoconfiguration {

The spring boot2, to be precise, changed some classes of the package:

The spring Boot 1 class name is:

    • Org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration

The Spring Boot 2 class name is:

    • Org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration
Summarize
    • When the class is loaded, it is not loaded by the annotation field referenced by it Class<?> , when the call Class.getDeclaredAnnotation(Class<A>) is loaded

      In the example above, it's @AutoConfigureBefore(EndpointAutoConfiguration.class) EndpointAutoConfiguration not going to MyHealthIndicatorAutoConfiguration be loaded together.

    • The code for parsing bytecode inside the JDK is unreasonable, and the ClassNotFoundException exception is eaten.
    • Troubleshooting a problem requires a step-deep debug

Deep Spring Boot: How to troubleshoot Java.lang.ArrayStoreException

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.