springspring-bootspring-autoconfiguration

My SpringBoot autoconfiguration library isn't loaded automatically


I am creating an autoconfiguration library for SpringBoot 3.1.0. The source code can by found here https://github.com/ugwun/spring-boot-starter-openai

I am following this documentation for creating autoconfiguration libraries: https://docs.spring.io/spring-boot/docs/2.1.13.RELEASE/reference/html/boot-features-developing-auto-configuration.html

I created:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  io.github.ugwun.springbootstarteropenai.configuration.OpenAIAutoconfiguration
@Configuration
public class OpenAIAutoconfiguration {

    @Value("${openai.api.key}")
    private String apiKey;

    @Bean
    @ConditionalOnMissingBean
    public AiApiClient openAIApiClient() {
        return new OpenAiApiClient(apiKey);
    }

}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>io.github.ugwun</groupId>
    <artifactId>springbootstarteropenai</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>${project.groupId}:${project.artifactId}</name>
    
    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.15.2</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

However, when I try to use the autoconfiguration library in a different project, the bean isn't created.

Example usage from a different SpringBoot app:

@SpringBootApplication
public class SpringboottestingApplication {

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

}

@RestController
class HelloController {

    private final AiApiClient client;

    HelloController(AiApiClient client) {
        this.client = client;
    }

    @GetMapping("/")
    String hello() {
        Map<String, String>[] messages = new Map[]{
                Map.of("role", "system", "content", "You are a helpful assistant."),
                Map.of("role", "user", "content", "Who won the world series in 2020?")
        };

        try {
            return client.generateChatMessage("gpt-3.5-turbo", messages);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

I get this error:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-06-27T18:14:14.224+02:00 ERROR 3352 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.example.springboottesting.HelloController required a bean of type 'io.github.ugwun.springbootstarteropenai.client.AiApiClient' that could not be found.


Action:

Consider defining a bean of type 'io.github.ugwun.springbootstarteropenai.client.AiApiClient' in your configuration.


Process finished with exit code 1


The only way how I was able to get the SpringBoot app to load the AiApiClient bean was by using the scanBasePackages:

@SpringBootApplication(scanBasePackages = {"com.example", "io.github.ugwun.springbootstarteropenai"})

If I understand the autoconfiguration correctly, this isn't something that I have to be doing. Autoconfigured beans should be loaded out of the box.

Help or a pointer would be very appreciated.


Solution

  • Your starter project uses spring-boot version 3.1.x and you follow a 2.x tutorial.

    Here is the correct documentation features.developing-auto-configuration

    in short: don't use META-INF/spring.factories but META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports