Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Erro ao tentar executar o projeto com Sprint AI

Bom dia, boa tarde e boa noite.
Estou seguindo no curso, tentando executar a controller de categorização de produtos após ter configurado o modelo específico do chat GPT, porém, está apresentando o erro abaixo e não consigo uma solução. Estou utilizando o Spring Boot 3.5.10 e o Sprint AI 1.1.2, que são as versões que inicialmente possuem compatibilidade.

Erro:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2026-02-02T07:17:26.884-03:00 ERROR 8250 --- [economart] [  restartedMain] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Failed to generate bean name for imported class 'org.springframework.ai.model.openai.autoconfigure.OpenAiAudioSpeechAutoConfiguration'
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.registerBeanDefinitionForImportedConfigurationClass(ConfigurationClassBeanDefinitionReader.java:172) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:124) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:458) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:310) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:794) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:602) ~[spring-context-7.0.3.jar:7.0.3]
    at org.springframework.boot.web.server.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-web-server-4.0.2.jar:4.0.2]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:756) ~[spring-boot-4.0.2.jar:4.0.2]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:445) ~[spring-boot-4.0.2.jar:4.0.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) ~[spring-boot-4.0.2.jar:4.0.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1365) ~[spring-boot-4.0.2.jar:4.0.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-4.0.2.jar:4.0.2]
    at br.com.alura.ronanluiz.ecomart.EcomartApplication.main(EcomartApplication.java:11) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:52) ~[spring-boot-devtools-4.0.2.jar:4.0.2]
Caused by: java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration]
    at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:353) ~[spring-core-7.0.3.jar:7.0.3]
    at org.springframework.core.annotation.TypeMappedAnnotation.adapt(TypeMappedAnnotation.java:451) ~[spring-core-7.0.3.jar:7.0.3]
    at org.springframework.core.annotation.TypeMappedAnnotation.getValue(TypeMappedAnnotation.java:384) ~[spring-core-7.0.3.jar:7.0.3]
    at org.springframework.core.annotation.TypeMappedAnnotation.asMap(TypeMappedAnnotation.java:273) ~[spring-core-7.0.3.jar:7.0.3]
    at org.springframework.core.annotation.AbstractMergedAnnotation.asAnnotationAttributes(AbstractMergedAnnotation.java:191) ~[spring-core-7.0.3.jar:7.0.3]
    at 
2 respostas

Segue a classe que estou tentando implementar:

package br.com.alura.ronanluiz.ecomart.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("categorizador")
public class CategorizadorDeProdutosController {

    private final ChatClient chatClient;

    public CategorizadorDeProdutosController(ChatClient.Builder chatClientBuilder) {
        OpenAiChatOptions defaultOptions = OpenAiChatOptions.builder()
                .model("gpt-4o-mini")
                .build();
        this.chatClient = chatClientBuilder.defaultOptions(defaultOptions).build();
    }

    @GetMapping
    public String categorizar(String produto){
        var system = """
                Você é um categorizador de produtos e deve responder apenas o nome da categoria do produto informado
                
                Escolha uma categoria dentro da lista abaixo:
                1. Higiene pessoal
                2. Eletrônicos
                3. Esportes
                4. Outros
            
                ###### exemplo de uso:
            
                Pergunta: Bola de futebol
                Resposta: Esportes
                """;
        return this.chatClient.prompt()
                    .system(system)
                    .user(produto)
                    .options(OpenAiChatOptions.builder()
                            .temperature(0.85)
                            .build())
                    .call()
                    .content();
    }

}

E abaixo o arquivo pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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.5.10</version>
    </parent>
    <groupId>br.com.alura.ronanluiz</groupId>
    <artifactId>economart</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>economart</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>21</java.version>
        <spring-ai.version>1.1.2</spring-ai.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId> 
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>
solução!

Oi, Ronan! Como vai?

O erro acontece porque, na prática, sua aplicação está iniciando com Spring Boot 4.0.2 / Spring Framework 7.0.3. Dá para perceber isso pelos jars spring-boot-4.0.2.jar e spring-context-7.0.3.jar que aparecem no stacktrace.

Nesse cenário, o Spring AI 1.1.2 tenta carregar a classe:

org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration

O problema aqui é que, no Spring Boot 4, essa auto-configuração foi movida de pacote. Como o Spring AI 1.x ainda espera a estrutura do Spring Boot 3.x, a classe não é encontrada e o contexto falha ao subir.

Opção recomendada: manter Spring Boot 3.5.x com Spring AI 1.1.2

Essa é a opção mais simples e alinhada com o curso. O Spring AI 1.x foi pensado exatamente para trabalhar com Spring Boot 3.4.x e 3.5.x.

Siga esses passos para resolver:

  1. Primeiro, confirme quem está puxando o Spring Boot 4 no projeto:

    
    mvn -q dependency:tree | grep spring-boot
    
  2. Verifique se não existe nenhum spring-boot-dependencies ou outro BOM forçando a versão 4.0.x.

  3. Remova o repositório spring-milestones. Para o Spring AI 1.x, ele não é necessário, pois tudo já está disponível no Maven Central.

Exemplo de pom.xml ajustado:


<properties>
  <java.version>21</java.version>
  <spring-ai.version>1.1.2</spring-ai.version>
</properties>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.ai</groupId>
      <artifactId>spring-ai-bom</artifactId>
      <version>${spring-ai.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

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

  <dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
  </dependency>
</dependencies>

O que esse código faz: deixa o BOM do Spring Boot e o BOM do Spring AI alinhados, garantindo compatibilidade entre as bibliotecas e evitando que o Boot 4 seja usado sem querer.

Nota: se a ideia quiser trabalhar com Spring Boot 4.x, aí sim é necessário migrar para o Spring AI da linha 2.x. Fora isso, para o curso, manter tudo na linha 3.x é o caminho mais tranquilo.

Detalhe extra no controller (parâmetro do GET)


@GetMapping
public String categorizar(@RequestParam String produto) {
  // ...
}

O que esse código faz: garante que o Spring leia corretamente o parâmetro produto pela URL, por exemplo:
/categorizador?produto=Bola%20de%20futebol

Espero ter ajudado. Conte com o apoio do Fórum na sua jornada. Fico à disposição.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado