Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AOT compilation broken for Spring Boot #4010

Open
cromefire opened this issue Dec 23, 2024 · 8 comments
Open

AOT compilation broken for Spring Boot #4010

cromefire opened this issue Dec 23, 2024 · 8 comments
Labels
Platform: Java Type: Bug Something isn't working

Comments

@cromefire
Copy link

cromefire commented Dec 23, 2024

Integration

unknown (gradle plugin)

Java Version

21

Version

4.14.1

Steps to Reproduce

  1. Use the sentry gradle plugin as recommended, I don't know which integration exactly it pulls in as it seems to do all that automatically.
  2. Add the spring gradle AOT plugin (io.springframework.boot.aot)
  3. Compile the app

Expected Result

It compiles fine.

Actual Result

It fails to compile with the following exception:

Exception in thread "main" org.springframework.beans.factory.aot.AotBeanProcessingException: Error processing bean with name 'sentryOptions': failed to generate code for bean definition
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.lambda$generateRegisterBeanDefinitionMethods$2(BeanRegistrationsAotContribution.java:217)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateRegisterBeanDefinitionMethods(BeanRegistrationsAotContribution.java:207)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.lambda$generateRegisterBeanDefinitionsMethod$0(BeanRegistrationsAotContribution.java:171)
	at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateRegisterBeanDefinitionsMethod(BeanRegistrationsAotContribution.java:166)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:77)
	at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:96)
	at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
	at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
	at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
	at org.springframework.context.aot.ContextAotProcessor.performAotProcessing(ContextAotProcessor.java:106)
	at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:84)
	at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:49)
	at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
	at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:80)
Caused by: org.springframework.aot.generate.ValueCodeGenerationException: Failed to generate code for 'io.sentry.protocol.SdkVersion@84ca9ab3' with type class io.sentry.protocol.SdkVersion
	at org.springframework.aot.generate.ValueCodeGenerator.generateCode(ValueCodeGenerator.java:121)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateValue(BeanDefinitionPropertiesCodeGenerator.java:280)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addPropertyValues(BeanDefinitionPropertiesCodeGenerator.java:239)
	at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:145)
Caused by: org.springframework.aot.generate.ValueCodeGenerationException: Failed to generate code for 'io.sentry.protocol.SdkVersion@84ca9ab3' with type class io.sentry.protocol.SdkVersion

	at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:176)
	at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:81)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$generateBeanDefinitionMethod$3(BeanDefinitionMethodGenerator.java:176)
	at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
	at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:169)
	at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:89)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.generateBeanRegistration(BeanRegistrationsAotContribution.java:226)
	at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution$BeanDefinitionsRegistrationGenerator.lambda$generateRegisterBeanDefinitionMethods$2(BeanRegistrationsAotContribution.java:209)
	... 17 more
Caused by: org.springframework.aot.generate.UnsupportedTypeValueCodeGenerationException: Code generation does not support io.sentry.protocol.SdkVersion
	at org.springframework.aot.generate.ValueCodeGenerator.generateCode(ValueCodeGenerator.java:118)
Caused by: org.springframework.aot.generate.UnsupportedTypeValueCodeGenerationException: Code generation does not support io.sentry.protocol.SdkVersion

	... 30 more
@cromefire
Copy link
Author

When starting the app without AOT with a DSN set I also get this:

org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'sentryHub' defined in class path resource [io/sentry/spring/boot/jakarta/SentryAutoConfiguration$HubConfiguration.class]: @Bean definition illegally overridden by existing bean definition: Generic bean: class=io.sentry.HubAdapter; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; fallback=false; factoryBeanName=null; factoryMethodName=null; initMethodNames=[getInstance]; destroyMethodNames=null
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.isOverriddenByExistingDefinition(ConfigurationClassBeanDefinitionReader.java:333) ~[spring-context-6.2.0.jar:6.2.0]
 	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:205) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:121) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:430) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.0.jar:6.2.0]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.4.0.jar:3.4.0]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.4.0.jar:3.4.0]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.4.0.jar:3.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.4.0.jar:3.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.4.0.jar:3.4.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.4.0.jar:3.4.0]
	at de.hkga.galb.backend.api.BackendApplicationKt.main(BackendApplication.kt:14) ~[classes/:0.0.0-08b423c]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Unknown Source) ~[na:na]
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:102) ~[workspace/:na]
 	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64) ~[workspace/:na]
 	at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40) ~[workspace/:na]

Is the gradle plugin maybe not pulling in the right thing or something?

@adinauer
Copy link
Member

Hey, thanks for opening this issue. Can you please give more details on how you're using Spring.

  1. Can you please share a build.gradle file so we see how that AOT plugin is applied. Does the io.springframework.boot.aot plugin require adding another repo so it can be found?
  2. What kind of application are you starting? Can you please describe your Spring setup?
  3. How are you setting up Sentry (besides using the gradle plugin)?

@cromefire
Copy link
Author

cromefire commented Dec 27, 2024

1., 2. & 3. I just use a normal Spring Boot MVC app, with the aot plugin just applied as a normal gradle plugin.

For a demo you can just a new app from Spring Initializr using this configuration. Then apply the following diff:

diff --git a/build.gradle.kts b/build.gradle.kts
index 4a5c49d..4fb2e58 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,6 +2,8 @@ plugins {
     kotlin("jvm") version "1.9.25"
     kotlin("plugin.spring") version "1.9.25"
     id("org.springframework.boot") version "3.4.1"
+    id("org.springframework.boot.aot") version "3.4.1"
+    id("io.sentry.jvm.gradle") version "4.14.1"
     id("io.spring.dependency-management") version "1.1.7"
 }

diff --git a/src/main/kotlin/com/example/springdemo/SpringDemoApplication.kt b/src/main/kotlin/com/example/springdemo/SpringDemoApplication.kt
index 32b61dc..23fc2f9 100644
--- a/src/main/kotlin/com/example/springdemo/SpringDemoApplication.kt
+++ b/src/main/kotlin/com/example/springdemo/SpringDemoApplication.kt
@@ -1,11 +1,17 @@
 package com.example.springdemo
 
+import io.sentry.spring.jakarta.EnableSentry
 import org.springframework.boot.autoconfigure.SpringBootApplication
 import org.springframework.boot.runApplication
+import org.springframework.core.Ordered
 
 @SpringBootApplication
+@EnableSentry(
+    exceptionResolverOrder = Ordered.LOWEST_PRECEDENCE
+)
 class SpringDemoApplication
 
 fun main(args: Array<String>) {
     runApplication<SpringDemoApplication>(*args)
 }

And start it using (the example DNS alone is sufficient it doesn't seem to have to be valid to reproduce):

./gradlew :bootJar
SENTRY_DSN=https://[email protected]/0 java -jar build/libs/spring-demo-0.0.1-SNAPSHOT.jar

That should reproduce the error just fine and it may be small enough to be an integration test as well.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Dec 27, 2024
@adinauer
Copy link
Member

@cromefire can you retest without the @EnableSentry annotation please?

@cromefire
Copy link
Author

cromefire commented Dec 27, 2024

Without the annotation it's fine (and also still seems to send error reports). I enabled it because of the in-app instructions:

Image

In the online docs I couldn't find any reference except in the Spring Framework docs. Maybe this is just an issue with wrong/outdated instructions?

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Dec 27, 2024
@adinauer
Copy link
Member

Thanks for bringing this up, we're about to change the onboarding docs and will replace this part for Spring Boot. It is only intended for Spring (not boot). Sorry for the troubles caused.

I haven't gotten around to testing the Gradle plugin yet.

@cromefire
Copy link
Author

The plugin itself seems to be working fine as it seems to be adding the correct dependency

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Dec 30, 2024
@adinauer
Copy link
Member

adinauer commented Jan 3, 2025

Quick update, there was a bug in onboarding docs where docs for Spring were shown for Spring Boot as well. This has been fixed in getsentry/sentry#82805 and should now show correct docs for v7.

We'll update the onboarding docs for v8 soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Platform: Java Type: Bug Something isn't working
Projects
Status: No status
Status: Needs Discussion
Development

No branches or pull requests

2 participants