SpringBoot项目启动报错java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy

news/2025/1/7 11:02:20/文章来源:https://www.cnblogs.com/cdfive2018/p/18653451

问题

今天启动业余学习项目里的某服务A发现启动失败,报错信息如下:

[ ERROR] [2025-01-05 15:41:26,083] [main] com.cdfive.springboot.startup.ApplicationStartupExceptionReporter [30] - error=>
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxyat 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.reflect.Executable.declaredAnnotations(Executable.java:599)at java.lang.reflect.Executable.declaredAnnotations(Executable.java:597)at java.lang.reflect.Executable.getDeclaredAnnotations(Executable.java:588)at java.lang.reflect.Method.getDeclaredAnnotations(Method.java:630)at org.springframework.core.annotation.AnnotationsScanner.getDeclaredAnnotations(AnnotationsScanner.java:454)at org.springframework.core.annotation.AnnotationsScanner.isKnownEmpty(AnnotationsScanner.java:492)at org.springframework.core.annotation.TypeMappedAnnotations.from(TypeMappedAnnotations.java:251)at org.springframework.core.annotation.MergedAnnotations.from(MergedAnnotations.java:351)at org.springframework.core.annotation.MergedAnnotations.from(MergedAnnotations.java:330)at org.springframework.core.annotation.AnnotatedElementUtils.findAnnotations(AnnotatedElementUtils.java:764)at org.springframework.core.annotation.AnnotatedElementUtils.hasAnnotation(AnnotatedElementUtils.java:531)at org.springframework.context.annotation.BeanAnnotationHelper.isBeanAnnotated(BeanAnnotationHelper.java:41)at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.isMatch(ConfigurationClassEnhancer.java:407)at org.springframework.context.annotation.ConfigurationClassEnhancer$ConditionalCallbackFilter.accept(ConfigurationClassEnhancer.java:192)at org.springframework.cglib.proxy.Enhancer.emitMethods(Enhancer.java:1217)at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:726)at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)at org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy.generate(ClassLoaderAwareGeneratorStrategy.java:57)at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:358)at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:585)at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:110)at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:108)at org.springframework.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)at java.util.concurrent.FutureTask.run(FutureTask.java)at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:134)at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:319)at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:572)at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:419)at org.springframework.context.annotation.ConfigurationClassEnhancer.createClass(ConfigurationClassEnhancer.java:137)at org.springframework.context.annotation.ConfigurationClassEnhancer.enhance(ConfigurationClassEnhancer.java:109)at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:433)at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:258)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:291)at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:131)at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533)at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:755)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:402)at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1247)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1236)at com.cdfive.web.WebApplication.main(WebApplication.java:16)

第一次看到这个报错:java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
异常堆栈信息里没有项目模块里相关的东西,初步看不出来哪里的问题。

分析&解决

考虑上周在本机尝试安装新版本IDEA,后面又还原安装了老版本,尝试刷新整个项目Maven依赖,然后mvn clean package重新启动该模块,发现还是启动失败;
尝试启动项目里另一个模块服务B,启动成功。

咦?这什么情况。。

查看Git Log想想自己怎么改了什么,看到最近对对cdfive-sentinelcdfive-demo-mybatis模块有修改和优化,
cdfive-sentinel模块里增加了feign的集成扩展,通过feignCapabilityInvocationHandlerFactorysentinel的API进行集成,
cdfive-demo-mybatis模块里引入knife4j-spring-ui依赖,修复了影响其使用的问题。

其中,cdfive-demo-mybatis是个独立的demo模块,服务A服务B依赖它,而都有对cdfive-sentinel模块的依赖。

为什么服务A启动失败,服务B启动成功呢?

注意到服务A没有feign的依赖,而服务B有,在cdfive-sentinel模块里对feign的依赖<scope>provided

通过搜索找到一些博客分享,尝试在java.lang.ArrayStoreException类的构造函数打断点:

public ArrayStoreException() {super();}public ArrayStoreException(String s) {super(s);
}

在断点的方法调用栈里,看到上一级AnnotationParser#parseClassArray(...)里,找到了有个变量的类型是com.cdfive.sentinel.config.SentinelAutoConfiguration
是扩展sentinel的自动配置类,上周正好修改过。

打开SentinelAutoConfiguration类,查看新添加的代码:

@ConditionalOnClass(Feign.Builder.class)
@Bean
public SentinelBeanPostProcessor sentinelBeanPostProcessor() {SentinelBeanPostProcessor sentinelBeanPostProcessor = new SentinelBeanPostProcessor();return sentinelBeanPostProcessor;
}

新添加1个SentinelBeanPostProcessor的Bean,想通过@ConditionalOnClass注解实现当class包里有Feign.Builder时创建该Bean,
服务A里没有feign的依赖包。

根据@ConditionalOnClass注解字面理解,它是判断class是否存在来决定是否创建Bean,
这里将注解用在方法上,遇到了问题。

查看@ConditionOnClass注解的注释:

*** {@link Conditional @Conditional} that only matches when the specified classes are on* the classpath.* <p>* A {@link #value()} can be safely specified on {@code @Configuration} classes as the* annotation metadata is parsed by using ASM before the class is loaded. Extra care is* required when placed on {@code @Bean} methods, consider isolating the condition in a* separate {@code Configuration} class, in particular if the return type of the method* matches the {@link #value target of the condition}.** @author Phillip Webb* @since 1.0.0*/
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {...
}

根据查询的资料:

`@ConditionalOnClass`如果添加在类的方法里时要格外小心,考虑将条件隔离在单独的Configuration类中,
建议`@ConditionalOnClass`在类级别使用,如果在方法上使用,考虑使用它的name属性来指定。

因此尝试将@ConditionalOnClass(Feign.Builder.class)修改为@ConditionalOnClass(name = "feign.Feign.Builder")
通过名称而不是类型来指定,重新编译项目并启动服务A,启动成功。

参考

  • springboot启动报sun.reflect.annotation.TypeNotPresentExceptionProxy
    https://zhuanlan.zhihu.com/p/462068881

  • ConditionalOnClass not working for Bean methods on Java 8
    https://github.com/spring-projects/spring-boot/issues/27846

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/864450.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《计算机组成及汇编语言原理》读后感

一、 为什么选择这本书? 这本书来自于:https://github.com/codefollower/My-Blog/issues/1。工作之后,个人一直追求的一个方面就是“系统化”,笼统的来说就是从以下两方面进行系统化:“基础”+“专业”。这本书属于基础方面的深化,通过 Java 虚拟机来讲计算机组成。 二、…

Effective Java中文版(原书第3版)PDF、EPUB免费下载

Jolt获奖作品全新升级,与《Java编程思想》和《Java核心技术》齐名,针对Java7、8、9全面更新Effective Java中文版(原书第3版)PDF、EPUB免费下载 适读人群 :本书并非面向Java初学者,而是要求读者有一定的Java编程经验。对于在Java开发方面已经积累一定经验的读者而言,本书…

2024-2025-1 20241301 《计算机基础与程序设计》第十五周学习总结

|这个作业属于哪个课程|2024-2025-1-计算机基础与程序设计| |这个作业要求在哪里|2024-2025-1计算机基础与程序设计第一周作业| |这个作业的目标|<复习知识,巩固基础>| |作业正文|https://www.cnblogs.com/HonJo/p/18653443| 一、教材学习内容 (一)《计算机科学概论》…

剖析Vue2内部运行机制

Vue.js 运行机制全局概览 全局概览 这一节笔者将为大家介绍一下 Vue.js 内部的整个流程,希望能让大家对全局有一个整体的印象,然后我们再来逐个模块进行讲解。从来没有了解过 Vue.js 实现的同学可能会对一些内容感到疑惑,这是很正常的,这一节的目的主要是为了让大家对整个流…

C++前缀和

有一个数组{2,1,3,6,4},询问三次结果: a[5] = {2, 1, 3, 6, 4} 1.数组第1到第2个元素的和是多少? 2. 数组第1到第3个元素的和是多少? 3. 数组第2到第4个元素的和是多少?没有用前缀和的原始用法:1 #include<iostream>2 #include<stdio.h>3 using namespace st…

Verilog6_串行通信协议

Verilog内容总结6_串行通信协议一、通信协议概述 1.串行通信与并行通信串行通信(serial communication):数据通过单根数据线一位一位地传输;成本低但速度慢;适用于远距离传输,用于计算机与外设之间,如UART、\(I^2C\)、SPI并行通信(parallel communication):通过多根数…

二进制码与格雷码之间的转换

二进制码到格雷码的转换 (1)格雷码的最高位(最左边)与二进制码的最高位相同。 (2)从左到右,逐一将二进制码相邻的两位相加(舍去进位),作为格雷码的下一位。格雷码到二进制码的转换 (1)二进制码的最高位(最左边)与格雷码的最高位相同。 (2)将产生的每一位二进制…

20241407《计算机基础与程序设计》课程总结

每周作业链接汇总 第0周作业: 自我介绍第一周作业: 1.基于VirtualBox虚拟机安装Ubuntu和安装Linux系统 2.快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题第二周作业: 数字化 信息安全 *自学教材:计算机科学概论(第七版)第1章…

运算放大器在运算方面的应用

集成运算放大器与外部电阻、电容、半导体器件等构成闭环电路后,能对各种模拟信号进行比例、加法、减法、微分、积分、对数、反对数、乘法和除法等运算。运算放太器工作在线性区时,通常要引入深度负反馈。所以,它的输出电压和输入电压的关系基本决定于反馈电路和输入电路的结…

SpringBoot原理分析-1

SpringBoot原理分析 作为一个javaer,和boot打交道是很常见的吧。熟悉boot的人都会知道,启动一个springboot应用,就是用鼠标点一下启动main方法,然后等着就行了。我们来看看这个main里面。 @SpringBootApplication public class ExampleApplication {public static void mai…

CF补题 950-Div.3

CF补题 950-Div.3-20250102 Dashboard - Codeforces Round 950 (Div. 3) - Codeforces A: 题目大意:给出一个字符串,要求重复的字母必须 \(\ge m\) ,求缺失字母总个数 #include <iostream> #include <map> using namespace std;map<char, int> mp;int ma…

第十五周学习总结

学期2024-2025-1 学号20241414 《计算机基础与程序设计》第十五周学习总结 作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 2024-2025-1计算机基础与程序设计第一周作业这个作业的目标 课程总结作业正文 本博客链接每周作业链接汇总整体评价…