ClassNotFoundException: org.springframework.boot.autoconfigure.condition.OnPropertyCondition

版本

springboot 版本 2.6.8

springcloud版本 2021.0.3

springcloud-alibaba版本 2021.1

JDK版本11

背景

gateway网关做权限验证的时候 在过滤器 注入 LoadBalancerClient 去调用权限认证微服务判断

用户是否有权限,但是在 LoadBalancerClient。choose的时候报错了

@Resource
private LoadBalancerClient loadBalancerClient;

private String buildAuthAddress(String token) {
    //这边报错了
    ServiceInstance instance = loadBalancerClient.choose("服务名称");
    ......
}

异常信息

2022-07-14 18:44:01.605  ForkJoinPool.commonPool-worker-3 WARN  org.springframework.context.annotation.AnnotationConfigApplicationContext Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration]; nested exception is java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.condition.OnPropertyCondition]
2022-07-14 18:44:01.609  reactor-http-nio-3 ERROR org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler [3252ac01-4]  500 Server Error for HTTP GET "/message/message/enums"
java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration]; nested exception is java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.condition.OnPropertyCondition]
        at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
        Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
        *__checkpoint ⇢ springfox.boot.starter.autoconfigure.SwaggerUiWebFluxConfiguration$CustomWebFilter [DefaultWebFilterChain]
        *__checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
        *__checkpoint ⇢ com.cndinfo.eblink.gateway.filter.EbliknSentinelAuthorityFilter [DefaultWebFilterChain]
        *__checkpoint ⇢ com.cndinfo.eblink.gateway.filter.AEblinkParamsFilter [DefaultWebFilterChain]
        *__checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
        *__checkpoint ⇢ HTTP GET "/message/message/enums" [ExceptionHandlingWebHandler]
Original Stack Trace:
                at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
                at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
                at com.cndinfo.gateway.filter.AuthFilter.filter(AuthFilter.java:92)
                at org.springframework.cloud.gateway.handler.FilteringWebHandler$GatewayFilterAdapter.filter(FilteringWebHandler.java:137)
                at org.springframework.cloud.gateway.filter.OrderedGatewayFilter.filter(OrderedGatewayFilter.java:44)
                at org.springframework.cloud.gateway.handler.FilteringWebHandler$DefaultGatewayFilterChain.lambda$filter$0(FilteringWebHandler.java:117)
                at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44)
                at reactor.core.publisher.Mono.subscribe(Mono.java:4400)
                at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263)
                at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51)
                at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
                at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:240)
                at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
                at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onComplete(FluxContextWrite.java:126)
                at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:148)
                at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:74)
                at reactor.core.publisher.Operators$MonoInnerProducerBase.complete(Operators.java:2664)
                at reactor.core.publisher.MonoSingle$SingleSubscriber.onComplete(MonoSingle.java:180)
                at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onComplete(FluxMapFuseable.java:152)
                at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1817)
                at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151)
                at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
                at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
                at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
                at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
                at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299)
                at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337)
                at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)
                at reactor.core.publisher.MonoCollect$CollectSubscriber.onComplete(MonoCollect.java:159)
                at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)
                at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:260)
                at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:144)
                at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:400)
                at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:419)
                at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:600)
                at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:93)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
                at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
                at reactor.netty.http.server.HttpTrafficHandler.channelRead(HttpTrafficHandler.java:266)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
                at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
                at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
                at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327)
                at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299)
                at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
                at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
                at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
                at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
                at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
                at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
                at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722)
                at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:658)
                at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:584)
                at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496)
                at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:995)
                at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
                at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
                at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration]; nested exception is java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.condition.OnPropertyCondition]
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:189)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311)
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112)
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
        at org.springframework.cloud.context.named.NamedContextFactory.createContext(NamedContextFactory.java:155)
        at org.springframework.cloud.context.named.NamedContextFactory.getContext(NamedContextFactory.java:108)
        at org.springframework.cloud.context.named.NamedContextFactory.getInstance(NamedContextFactory.java:164)
        at org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory.getInstance(LoadBalancerClientFactory.java:78)
        at org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.choose(BlockingLoadBalancerClient.java:171)
        at org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient.choose(BlockingLoadBalancerClient.java:166)
        at com.cndinfo.gateway.AuthClientService.buildAuthAddress(AuthClientService.java:48)
        at com.cndinfo.gateway.AuthClientService.verify(AuthClientService.java:34)
        at com.cndinfo.gateway.filter.AuthFilter.lambda$filter$0(AuthFilter.java:89)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.condition.OnPropertyCondition]
        at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:334)
        at org.springframework.context.annotation.ConditionEvaluator.getCondition(ConditionEvaluator.java:124)
        at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:96)
        at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:226)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:207)
        at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:175)
        ... 22 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.autoconfigure.condition.OnPropertyCondition
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        at org.springframework.util.ClassUtils.forName(ClassUtils.java:284)
        at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:324)
        ... 27 common frames omitted

很诡异的现象说是类找不到,但是排查了下包依赖是有的,而且本地环境没问题,开发环境有问题,测试环境也没问题,但是因为用的是docker方式打包,开发环境和测试环境的JDK 代码都是一样的。

百度查半天查不到,把开发环境docker  镜像的jar搞下来断点调试

docker inspect {容器名字}

 找到对应的目录,去拿包

 然后idea配置远程调试

项目启动

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005  -jar app.jar

断点到spring源码

 好家伙,原来这货是懒加载的,在这边容器获取不到需要去生成一个,恍然大悟,难道是注入错容器里?怀疑是父子容器问题?继续跟代码

 跟到最底层发现是通过App ClassLoader 去加载 class的时候抛出的异常,卧槽,难不成是jdk 加载类的机制问题,问题定位到了,那么怎么解决呢?因为网关用的是响应式编程,网上资料不多

经过同事的提示,在github上找到了解决方法

Feign client lazy initialization fails when using CompletableFuture.supplyAsync() to call the Feign client initially · Issue #475 · spring-cloud/spring-cloud-openfeign · GitHub

贴上国外大佬的描述

大概的意思就是说懒加载机制在Spring Boot Build Image插件环境下用ForkJoinWorkerThread 有问题。要么换成fixedSizeThreadExecutor或者newWorkStealingExecutor,要么用用饿汉模式去处理(英语好的自己看原文把,哈哈哈哈)

解决方案贴上:

给容器指定classloader



import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @Author: chenweida
 * @Date: 2022/7/14 18:37
 */
@Configuration
public class LoadBalanceConfig {

    @Bean
    @ConditionalOnMissingBean
    public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) {
        return new LoadBalancerClientFactory(properties) {
            @Override
            protected AnnotationConfigApplicationContext createContext(String name) {
                // FIXME: temporary switch classloader to use the correct one when creating the context
                ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
                Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
                AnnotationConfigApplicationContext context = super.createContext(name);
                Thread.currentThread().setContextClassLoader(originalClassLoader);
                return context;
            }
        };
    }
}

下班,下班.............

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

white......

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值