GoogleCloudPlatform / spring-cloud-gcp

New home for Spring Cloud GCP development starting with version 2.0.
Apache License 2.0
415 stars 307 forks source link

Exception on application start with Spring Boot 3.2 and com.google.cloud:spring-cloud-gcp-starter-pubsub:4.8.4` #2379

Closed credmond-git closed 9 months ago

credmond-git commented 10 months ago

Describe the bug My application fails to start with an exception: Error creating bean with name 'com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration': Failed to instantiate [com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration]: Constructor threw exception

I am upgrading my application to spring boot 3.2, with Java 21, and com.google.cloud:spring-cloud-gcp-starter-pubsub:4.8.4

I do not have any other GCP Projects in my application.

I am temporarily able to start myt application by using the following property. management.health.pubsub.enabled = false

Callstack:

Error creating bean with name 'com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration': Failed to instantiate [com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration]: Constructor threw exception
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration': Failed to instantiate [com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration]: Constructor threw exception
    at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:322)
    at app//org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:310)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1193)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:563)
    at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523)
    at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325)
    at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323)
    at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973)
    at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:946)
    at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616)
    at app//org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
    at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753)
    at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455)
    at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:323)
    at app//org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
    at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
    at app//org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
    at app//org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1442)
    at app//org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
    at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
    at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
    at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
    at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
    at app//org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
    at app//org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:141)
    at app//org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:97)
    at app//org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:247)
    at app//org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
    at java.base@21.0.1/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base@21.0.1/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base@21.0.1/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
    at java.base@21.0.1/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base@21.0.1/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base@21.0.1/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
    at java.base@21.0.1/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base@21.0.1/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
    at java.base@21.0.1/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at java.base@21.0.1/java.util.Optional.orElseGet(Optional.java:364)
    at java.base@21.0.1/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base@21.0.1/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration]: Constructor threw exception
    at app//org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223)
    at app//org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:111)
    at app//org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:319)
    ... 42 more
Caused by: java.lang.NoSuchMethodError: org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration: method 'void <init>()' not found
    at com.google.cloud.spring.autoconfigure.pubsub.health.PubSubHealthIndicatorAutoConfiguration.<init>(PubSubHealthIndicatorAutoConfiguration.java:55)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210)
jimshowalter commented 10 months ago

I was just about to report this exact same problem.

burkedavison commented 9 months ago

Spring Boot 3.2 support has not yet been added to Spring Cloud GCP. Parent issue #2301

jimshowalter commented 9 months ago

When do you expect this to be resolved? We are paying customers who use GCP extensively, and this is blocking us from using virtual threads.

meltsufin commented 9 months ago

@jimshowalter Would you mind filing a support case to help us prioritize your request better through the right channels?

jimshowalter commented 9 months ago

@meltsufin, filed a support case.

palhoye commented 9 months ago

I'm also experiencing this issue and it is blocking upgrade to Spring Boot 3.2 which is desirable due to virtual threads. Appreciate if you would prioritize fixing this ASAP.

I'd expect Spring Cloud GCP to be ahead of these issues and test Spring Boot release candidates before they are released so that any incompatibility issues are resolved in advance. It'd be great if you can make that part of the process.

burkedavison commented 9 months ago

Spring Cloud GCP is heavily reliant on Spring Cloud.

As Spring Cloud 2022 is not compatible with Spring Boot 3.2.0, we are waiting for the GA release of Spring Cloud 2023.

jimshowalter commented 9 months ago

2022? Does Spring Cloud not publish quarterly (or more often) releases?

jimshowalter commented 9 months ago

Ugh: https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2023.0-Release-Notes

jimshowalter commented 9 months ago

They're almost out of 2023. Going to need to change the version name!

jimshowalter commented 9 months ago

If they really only release once a year, you need to find some other way to manage dependencies.

burkedavison commented 9 months ago

Spring Cloud 2022 was released in December 2022, and has had 3 patch updates. Spring Cloud 2021 was released in December 2021, and has had 7 patch updates.

We expect Spring Cloud 2023 to follow this pattern. Spring Cloud's 'Supported Versions' documentation provides more information about the release train and their process.

jimshowalter commented 9 months ago

It sounds like you're saying nothing can be done until some time this month.

We have a platform used by a bunch of microservices. We use best-practice CI/CD, where we publish only from the tip of the main branch. We don't have feature branches.

So now we either have to hold back all of our services on 3.1.x, or upgrade our platform and services that don't use pubsub, and hope we don't need to fix a bug in or platform that's needed by the services that use pubsub.

burkedavison commented 9 months ago

Spring Boot 3.2.0 is not compatible with Spring Cloud 2022. If Spring Cloud GCP updates to Spring Boot 3.2.0 right now, it'd have to use the release candidate of Spring Cloud 2023 and would force this same decision on all dependent projects. Our stance is that production projects should not use prerelease versions, so this is not our practice.

Please consider escalating this through the support case you've filed, as this will help us understand your projects' use case and review how we might adjust this policy in the future.

jimshowalter commented 9 months ago

Already escalated.

The use case is simple: consumers of APIs that wrap Spring (or anything else) expect/require to be able to upgrade to newer versions of what is wrapped, in a timely manner, in order to stay compliant with FedRAMP High and other requirements.

We'll wait, but we also will soon post a one-class solution to this problem, so others who don't want to wait don't need to.

It sounds as if there needs to be a closer coupling among the various organizations responsible for Spring, Spring Boot, Spring Cloud, and spring-cloud-gcp.

I realize that's a herding-cats problem, but also, the Spring orgs + Google are pretty big cats.

jimshowalter commented 9 months ago

If you don't want to wait, this seems to fix the problem: PubSubHealthIndicatorAutoConfiguration.txt

burkedavison commented 9 months ago

@jimshowalter : I previously mistyped the issue number in the PR so the linking didn't work. I've opened a PR to pre-emptively backport the changes for Spring Boot 3.2 compatibility to the current main branch. There are a few other classes that need adjustments similar to the PubSubHealthIndicatorAutoConfiguration. This PR should be mergable soon.

Note that once merged, we won't be claiming support for Spring Boot 3.2.x, but it should resolve compiler-specific compatibility issues even as Spring Cloud compatibility is yet to be resolved.

jimshowalter commented 9 months ago

Excellent, thank you!

burkedavison commented 9 months ago

This has been merged into main. The next release of Spring Cloud GCP is expected this week and will contain these updates.

breun commented 9 months ago

Spring Cloud GCP extends Spring Cloud. Spring Cloud 2023.0 will support Spring Boot 3.2, but Spring Cloud 2023.0 hasn’t been released yet, so Spring Cloud GCP can’t support Spring Boot 3.2 yet today.

Spring Boot 3.2.0 was released on November 23, and Spring Cloud 2023.0.0 was originally scheduled to be released on November 28. That got postponed to December 5, but it seems they didn’t make that date either: https://github.com/spring-cloud/spring-cloud-release/milestone/132

I don’t think escalating an issue at Google can speed this up, VMware first needs to finish their Spring Cloud 2023.0.0 release.

Taha-Di-Nero commented 9 months ago

@burkedavison Spring Cloud 2023.0.0 is released

palhoye commented 9 months ago

I see that Spring Cloud 2023.0.0 is released and that it will support Spring Boot 3.2.

What is the version to use for the "com.google.cloud:spring-cloud-gcp-dependencies" dependency? The previous version was "4.8.4".

amynguyen780 commented 9 months ago

@burkedavison Any updates on this? I just tried to use v5.0.0 but I'm still getting the same error message as in the description of this issue

burkedavison commented 9 months ago

@amynguyen780 Can you re-verify that you're using Spring Cloud GCP 5.0.0 or 4.9.0? Otherwise, could you provide an updated stack trace for the error you're seeing?

The OP stack trace shows throws an exception due to PubSubHealthIndicatorAutoConfiguration calling the null constructor for CompositeHealthContributorConfiguration which has been removed.

However, since the backport PR and the 4.9.0 release, the source no longer calls the null constructor.

burkedavison commented 9 months ago

Spring Cloud 2023.0.x and Spring Boot 3.2 is now supported in Spring Cloud GCP 5.x. Closing this issue. @amynguyen780 , please open a new ticket with an updated stack trace if you continue to see an error.

amynguyen780 commented 9 months ago

ah yes i got it to work now. there were some spring cloud gcp dependencies we were pulling in transitively that were still on 4.8.4. thanks