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

Source: Internet
Author: User
Tags mongodb postgresql redis throwable
java.lang.ArrayStoreException Analysis


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



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 is a simple healthindicator implementation




public class Myhealthindicator extends Abstracthealthindicator {
    @Override
    protected void Dohealthcheck ( Builder Builder) throws Exception {
        builder.status (status.up);
        Builder.withdetail ("Hello", "World");
    }


@Configuration
@AutoConfigureBefore (endpointautoconfiguration.class)
@AutoConfigureAfter ( Healthindicatorautoconfiguration.class)
@ConditionalOnClass (value = {Healthindicator.class}) public
class myhealthindicatorautoconfiguration {
    @Bean
    @ConditionalOnMissingBean (myhealthindicator.class)
    @ Conditionalonenabledhealthindicator (' my ') public
    myhealthindicator Myhealthindicator () {return
        new Myhealthindicator ();
    }


Springboot2-demo is a simple spring boot2 application that references the Springboot1-starter module.



To import the project into the IDE and execute the arraystoreexceptiondemoapplication in Springboot2-demo, the exception thrown 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:120) ~[na:1.8.0_112]
 at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[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]
 ... 16 common frames omitted

using the Java Exception breakpoint

Here's how 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 IDE's use of documents), the exception class is the above thrown out of the java.lang.ArrayStoreException.



When the breakpoint is valid, view the parameters of the Annotationutils.findannotation (Class<?>, Class<a>, set<annotation>) line:686 function.



You can see that Clazz is class com.example.springboot1starter.myhealthindicatorautoconfiguration$ $EnhancerBySpringCGLIB $$ 945c1f Annotationtype is interface org.springframework.boot.actuate.endpoint.annotation.Endpoint



Indicates an error occurred while trying to find @endpoint information from the myhealthindicatorautoconfiguration.



Myhealthindicatorautoconfiguration really did not @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) {
        myhealthindicatorautoconfiguration cc = new Myhealthindicatorautoconfiguration ();
    }


The exception was thought to be thrown, but the discovery was performed properly.



Looking closely at the exception stack, you can find the exception thrown at the at Java.lang.Class.getDeclaredAnnotation (class.java:3458), and then try the following code:




    public static void Main (string[] args) {
        MyHealthIndicatorAutoConfiguration.class.getDeclaredAnnotation ( Endpoint.class);
    }


Discovery can reproduce an 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?



Take a closer look at the exception information: Java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy



Arraystoreexception is an array-crossed exception, it has only one string message, and there is no cause.



So we try to break the point in the Sun.reflect.annotation.TypeNotPresentExceptionProxy constructor.




public class Typenotpresentexceptionproxy extends Exceptionproxy {
    private static final long Serialversionuid = 55659 25172427947573L;
    String TypeName;
    Throwable cause;

    Public Typenotpresentexceptionproxy (String typeName, throwable cause) {
        this.typename = typeName;
        This.cause = cause;
    }


In the breakpoint, we can find that: TypeName is org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration cause is Java.lang.ClassNotFoundException:org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration



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



So how did it become arraystoreexception?



Looking at the code carefully, you can find that annotationparser.parseclassvalue the exception packaging into object




//sun.reflect.annotation.annotationparser.parseclassvalue (ByteBuffer, ConstantPool, class<?>) private static Object Parseclassvalue (Bytebuffer buf, Consta Ntpool Constpool, class<?> container) {int classindex = Buf.getsh
        ORT () & 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);
        The catch (Noclassdeffounderror e) {return new Typenotpresentexceptionproxy ("[Unknown]", e); catch (Typenotpresentexception e) {return new Typenotpresentexceptionproxy (e.typename), E.getcaus
        E ()); }
    }


Then in Sun.reflect.annotation.AnnotationParser.parseClassArray (int, bytebuffer, Constantpool, class<?>) And 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 type information of the crossed object, which is the




Java.lang.ArrayStoreException:sun.reflect.annotation.TypeNotPresentExceptionProxy

solve the problem



The discovery is java.lang.ClassNotFoundException: Org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration, then add the @conditionalonclass check on it:




@Configuration
@AutoConfigureBefore (endpointautoconfiguration.class)
@AutoConfigureAfter ( Healthindicatorautoconfiguration.class)
@ConditionalOnClass (value = {Healthindicator.class, Endpointautoconfiguration.class}) Public
class Myhealthindicatorautoconfiguration {


The spring Boot2, to be exact, changed some of the package of the classes:



The spring Boot 1 class name is: Org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration



Spring Boot 2 class name is: Org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration 


summary

When a class loads, it does not load the Class<?> referenced by its annotation field, which is loaded when class.getdeclaredannotation (class<a>) is invoked



In the example above, it is @autoconfigurebefore (Endpointautoconfiguration.class) Endpointautoconfiguration will not be loaded with myhealthindicatorautoconfiguration.



The code for parsing bytecode inside the JDK is unreasonable, and the classnotfoundexception is eaten abnormally. Troubleshooting needs to be thoroughly debugged


Alibaba Cloud Hot Products

Elastic Compute Service (ECS) Dedicated Host (DDH) ApsaraDB RDS for MySQL (RDS) ApsaraDB for PolarDB(PolarDB) AnalyticDB for PostgreSQL (ADB for PG)
AnalyticDB for MySQL(ADB for MySQL) Data Transmission Service (DTS) Server Load Balancer (SLB) Global Accelerator (GA) Cloud Enterprise Network (CEN)
Object Storage Service (OSS) Content Delivery Network (CDN) Short Message Service (SMS) Container Service for Kubernetes (ACK) Data Lake Analytics (DLA)

ApsaraDB for Redis (Redis)

ApsaraDB for MongoDB (MongoDB) NAT Gateway VPN Gateway Cloud Firewall
Anti-DDoS Web Application Firewall (WAF) Log Service DataWorks MaxCompute
Elastic MapReduce (EMR) Elasticsearch

Alibaba Cloud Free Trail

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.