Scenario
Let’s say you are building a spring-boot library and would like to tap into spring-boot auto-configuration feature. You create class MyAutoConfiguration
and annotate it with the spring @Configuration
annotation. Then, in you application, you use this library as a dependency, run the application and get the following exception
Caused by: java.lang.IllegalStateException: Unable to read meta-data for class com.mylib.autoconfigure.MyAutoConfiguration at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.getAnnotationMetadata (AutoConfigurationSorter.java:233) at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.getOrder (AutoConfigurationSorter.java:204) at org.springframework.boot.autoconfigure.AutoConfigurationSorter$AutoConfigurationClass.access$000 (AutoConfigurationSorter.java:150) at org.springframework.boot.autoconfigure.AutoConfigurationSorter.lambda$getInPriorityOrder$0 (AutoConfigurationSorter.java:63)
Steps to Reproduce
Create spring-boot project and add the following class
@Configuration public class MyAutoConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(MyAutoConfiguration.class); @PostConstruct public void printConfigurationMessage() { LOGGER.info("Configuration for My Lib is complete..."); } }
Do not forget to add spring.factories
file to resources -> META-INF -> spring.factories
spring.factories file looks like this:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.mylib.autoconfigure.MyAutoConfiguration
maven file for this project may look something like this:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.6.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <!-- Spring --> <dependencies> ... </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
Finally, you add your library as a dependency to your application, run it and get the runtime error mentioned above.
Diagnostic
Online search suggests that either spring.factories file is missing, or the name of the class is not correct, … Everything is checked out and fine. To make sure MyAutoConfiguration
class is in fact included I start looking into my library jar:
jar tvf target/mylib.jar | grep MyAutoConfiguration
BOOT-INF/classes/com/mylib/autoconfigure/MyAutoConfiguration.class
Here, I can see that the class is under BOOT-INF/classes
root.
Solution
Apparently, auto configuration classes cannot be found under BOOT-INF/classes
root. The main issue with my setup was the fact that I used spring-boot-maven-plugin
to build the library module. After removing the plugin and rebuilding the library jar tvf target/mylib.jar | grep MyAutoConfiguration
is showing this:
com/mylib/autoconfigure/MyAutoConfiguration.class
Now, spring-boot application builds fine and MyAutoConfiguration
class is found and ready to be used to configure library.