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

micronaut-spring-boot:5.4.0 fails with io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [io.micronaut.context.event.ApplicationEventPublisher<io.micronaut.context.event.StartupEvent>] when running a jar file #516

Open
donbeave opened this issue Jan 10, 2024 · 5 comments

Comments

@donbeave
Copy link

Expected Behavior

No response

Actual Behaviour

gradle bootRun works well, but building the application as jar file and running it leads to an startup error:

Exception in thread "main" java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
	at java.base/java.lang.reflect.Method.invoke(Method.java:578)
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
	at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
	at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58)
Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [io.micronaut.context.event.ApplicationEventPublisher<io.micronaut.context.event.StartupEvent>] exists. Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
	at io.micronaut.context.DefaultBeanContext.newNoSuchBeanException(DefaultBeanContext.java:2773)
	at io.micronaut.context.DefaultApplicationContext.newNoSuchBeanException(DefaultApplicationContext.java:304)
	at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2735)
	at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1729)
	at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:856)
	at io.micronaut.context.BeanLocator.getBean(BeanLocator.java:96)
	at io.micronaut.context.DefaultBeanContext.publishEvent(DefaultBeanContext.java:1815)
	at io.micronaut.context.DefaultBeanContext.start(DefaultBeanContext.java:376)
	at io.micronaut.context.DefaultApplicationContext.start(DefaultApplicationContext.java:199)
	at io.micronaut.spring.context.MicronautApplicationContext.start(MicronautApplicationContext.java:458)
	at com.example.demo.DemoApplication.main(DemoApplication.java:14)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
	... 4 more

Steps To Reproduce

  1. Clone micronaut-spring-no-bean-of-type-applicationeventpublisher-exists repository
  2. Build jar
./gradlew bootJar
  1. Run jar
java -jar build/libs/demo-0.0.1-SNAPSHOT.jar

Environment Information

JDK Version:

openjdk 19.0.2 2023-01-17
OpenJDK Runtime Environment Temurin-19.0.2+7 (build 19.0.2+7)
OpenJDK 64-Bit Server VM Temurin-19.0.2+7 (build 19.0.2+7, mixed mode)

Example Application

https://github.com/donbeave/micronaut-spring-no-bean-of-type-applicationeventpublisher-exists

Version

4.2.3

@dstepanov
Copy link
Contributor

You might want to check if it did create a shadow jar and if meta-inf services are merged correctly

@donbeave
Copy link
Author

donbeave commented Jan 11, 2024

You might want to check if it did create a shadow jar and if meta-inf services are merged correctly

There is only one file in services:

java.nio.file.spi.FileSystemProvider

There is no shadow jar, as it normal Spring Boot application created with Spring Initializer (https://start.spring.io) with micronaut-spring-boot dependency. It's not using Micronaut Gradle plugin and Gradle Shadow plugin. It's using Micronaut as parent context for Spring Boot application.

@donbeave
Copy link
Author

@dstepanov I found a related issue in Micronaut Gradle plugin: micronaut-projects/micronaut-gradle-plugin#406, the only difference is that in my case I'm using Micronaut as a parent context without Gradle shadow and Micronaut Gradle plugins, only Spring gradle plugin with micronaut-spring-boot dependency. It worked fine for Micronaut 3, but not for Micronaut 4. Has something changed in 4th version and need to add some extra config?

@andrebrov
Copy link

Looks like there was some change in Spring Boot 3. Config below helps to resolve this issue:

tasks.bootJar { loaderImplementation = org.springframework.boot.loader.tools.LoaderImplementation.CLASSIC }

@asw12
Copy link

asw12 commented Jun 12, 2024

The upstream change in Spring Boot 3.2 is documented in the release notes.

The previous URL format of
jar:file:/dir/myjar.jar:BOOT-INF/lib/nested.jar!/com/example/MyClass.class
has been replaced with
jar:nested:/dir/myjar.jar/!BOOT-INF/lib/nested.jar!/com/example/MyClass.class.

A new NestedFileSystemProvider was added in support of this new scheme.

However, micronaut-spring has code that prepends any jarUri that isn't starting with "file:" with that scheme:
https://github.com/micronaut-projects/micronaut-core/blob/0118db96962eaf7a83abbcb81c1afd73139ff777/core/src/main/java/io/micronaut/core/io/IOUtils.java#L156-L162
So you get something like file:/nested:/dir/myjar.jar/!BOOT-INF/lib/nested.jar!/com/example/MyClass.class

That causes the FileSystemProvider for "file:" to be used instead of Spring's NestedFileSystemProvider, and that former one won't be able to load /nested:.../.

This is then causing the ServiceScanner to be unable to find any META-INF/micronaut/io.micronaut.inject.BeanDefinitionReference files listing out bean definitions, causing those NoSuchBeanException.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants