Azure / AppConfiguration

Questions, feedback and samples for Azure App Configuration service
MIT License
228 stars 69 forks source link

[BUG] Springboot application failing to start due to AppConfigurationRefreshEndpoint final class from azure appconfiguration-web with actuator dependency #917

Closed SriPalla closed 1 month ago

SriPalla commented 4 months ago

Describe the bug Springboot application failing to start due to AppConfigurationRefreshEndpoint final class from azure appconfiguraiton-web when actuator starter is being added to project.

Exception or Stack Trace

2024-05-13 20:46:10,545 INFO - [main] com.demo.DemoApplicationKt:660 : The following 1 profile is active: "local" 2024-05-13 20:46:11,299 WARN - [main] org.springframework.boot.actuate.endpoint.EndpointId:155 : Endpoint ID 'appconfiguration-refresh' contains invalid characters, please migrate to a valid format. 2024-05-13 20:46:11,649 WARN - [main] org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext:632 : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigurationRefreshEndpoint' defined in class path resource [com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationWebAutoConfiguration$AppConfigurationPushRefreshConfiguration.class]: Could not generate CGLIB subclass of class com.azure.spring.cloud.appconfiguration.config.web.implementation.pushrefresh.AppConfigurationRefreshEndpoint: Common causes of this problem include using a final class or a non-visible class 2024-05-13 20:46:11,671 ERROR - [main] org.springframework.boot.SpringApplication:851 : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appConfigurationRefreshEndpoint' defined in class path resource [com/azure/spring/cloud/appconfiguration/config/web/implementation/AppConfigurationWebAutoConfiguration$AppConfigurationPushRefreshConfiguration.class]: Could not generate CGLIB subclass of class com.azure.spring.cloud.appconfiguration.config.web.implementation.pushrefresh.AppConfigurationRefreshEndpoint: Common causes of this problem include using a final class or a non-visible class at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:959) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) at com.demo.DemoApplicationKt.main(DemoApplication.kt:20) Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class com.azure.spring.cloud.appconfiguration.config.web.implementation.pushrefresh.AppConfigurationRefreshEndpoint: Common causes of this problem include using a final class or a non-visible class at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:227) at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:160) at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:110) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.buildProxy(AbstractAutoProxyCreator.java:517) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:464) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:369) at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:318) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:438) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1789) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ... 15 more Caused by: java.lang.IllegalArgumentException: Cannot subclass final class com.azure.spring.cloud.appconfiguration.config.web.implementation.pushrefresh.AppConfigurationRefreshEndpoint at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:653) at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:26) at org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy.generate(ClassLoaderAwareGeneratorStrategy.java:57) at org.springframework.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:366) at org.springframework.cglib.proxy.Enhancer.generate(Enhancer.java:575) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.lambda$new$1(AbstractClassGenerator.java:107) at org.springframework.cglib.core.internal.LoadingCache.lambda$createEntry$1(LoadingCache.java:52) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.springframework.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:57) at org.springframework.cglib.core.internal.LoadingCache.get(LoadingCache.java:34) at org.springframework.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:130) at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:317) at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:562) at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:407) at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:62) at org.springframework.aop.framework.CglibAopProxy.buildProxy(CglibAopProxy.java:218) ... 24 more

Process finished with exit code 1

To Reproduce Adding Springboot actuator along with azure dependencies as listed below implementation("com.azure.spring:spring-cloud-azure-starter-appconfiguration-config-web") implementation("com.azure.spring:spring-cloud-azure-feature-management-web") implementation("org.springframework.boot:spring-boot-starter-actuator") mavenBom("org.springframework.cloud:spring-cloud-dependencies:2023.0.1") plugins { id("org.springframework.boot") version "3.2.3" } Code Snippet

Expected behavior Application should start successfully

mrm9084 commented 4 months ago

@SriPalla, can you clean provider the versions of our Spring libraries you are using. Also, which version of Spring AOP are you using, It seems like it is an issue with Spring AOP and our library not Spring Actuator.

SriPalla commented 4 months ago

@mrm9084 Springboot version: 3.2.3 spring-aop: 6.1.4 The issue is being observed after adding springboot actuator dependency along with spring aop

jimmyca15 commented 4 months ago

It seems like it is an issue with Spring AOP and our library

@mrm9084 were you able to confirm this?

mrm9084 commented 4 months ago

So where I've seen this issue before is when Spring Native gets involved and it tries to Mock out one of our classes that's marked as final. I'm trying to repo, but haven't had any luck yet.

mrm9084 commented 4 months ago

@SriPalla I'm having trouble replicating this, do you have a sample that replicates the issue. Also, the bug states that the application fails to start, but the top of the stack trace says

org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext:632 : Exception encountered during context initialization - cancelling refresh attempt: 

Which would only happen if the original started happened.

mrm9084 commented 4 months ago

@SriPalla, you you take that setup, with minimal app, (plus an empty config for GraphQL):

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

It starts up fine, with App Configuration enabled. I even added an endpoint to trigger refresh and it works fine. Are you doing something extra besides just running the Gradle build?

SriPalla commented 4 months ago

Issue is being observed when you add custom AOP for example loging request and response header around spring web Request mapping and then adding actuator dependency will fail server startup

mrm9084 commented 4 months ago

@SriPalla. Thanks. Was able to replicate. Fix is in PR. I have a workaround below.

Instead use:

com.azure.spring:spring-cloud-azure-appconfiguration-config not starter or web version. This version was created for just Spring Boot libraries and doesn't have the auto refresh feature built in. If you require the refresh feature, you can use it but manually. See: https://learn.microsoft.com/en-us/azure/azure-app-configuration/enable-dynamic-configuration-java-spring-app?tabs=spring-boot-3#use-manual-refresh.

zhenlan commented 1 month ago

@mrm9084 can this issue be closed?

mrm9084 commented 1 month ago

This should be fixed in 5.13.0 or newer.