Bug description
The OpenAI autoconfiguration relies on an import of the restclient autoconfiguration or a webclient autoconfiguration. Commit 377b5ff attempts to fix it but fails to handle the situation when either is null. An @nullable
annotation on both followed by a later check might be ideal.
Environment Spring-AI: 1.0.0-M1 Java: 21
Steps to reproduce
Initiate chatClient in a reactive setup with no non-reactive dependency inclusions.
Comment From: tzolov
Can you please share the complete error stack trace?
Comment From: Adakole2020
Does this suffice?
Unsatisfied dependency expressed through constructor parameter 0:
Error creating bean with name 'chatClientBuilder' defined in class path resource [org/springframework/ai/autoconfigure/chat/client/ChatClientAutoConfiguration.class]: Unsatisfied dependency expressed through method 'chatClientBuilder' parameter 1:
Error creating bean with name 'openAiChatModel' defined in class path resource [org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.class]: Unsatisfied dependency expressed through method 'openAiChatModel' parameter 2:
No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Comment From: wilkinsona
I think this is a bug rather than an enhancement.
The failure occurs when trying to use spring-boot-starter-webflux
. For example, the following two dependencies will trigger the problem:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Here's a start.spring.io link that will generate a project that reproduces the problem: https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.3.4&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=spring-ai-with-webflux&name=spring-ai-with-webflux&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.spring-ai-with-webflux&dependencies=spring-ai-openai,webflux.
Generate the project, unzip, and run ./mvnw spring-boot:run
:
[INFO] --- spring-boot:3.3.4:run (default-cli) @ spring-ai-with-webflux ---
[INFO] Attaching agents: []
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.4)
2024-09-23T09:09:50.860+01:00 INFO 48009 --- [spring-ai-with-webflux] [ main] c.e.s.SpringAiWithWebfluxApplication : Starting SpringAiWithWebfluxApplication using Java 17.0.12 with PID 48009 (/Users/awilkinson/Downloads/spring-ai-with-webflux/target/classes started by awilkinson in /Users/awilkinson/Downloads/spring-ai-with-webflux)
2024-09-23T09:09:50.863+01:00 INFO 48009 --- [spring-ai-with-webflux] [ main] c.e.s.SpringAiWithWebfluxApplication : No active profile set, falling back to 1 default profile: "default"
2024-09-23T09:09:52.072+01:00 WARN 48009 --- [spring-ai-with-webflux] [ main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'openAiChatModel' defined in class path resource [org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.class]: Unsatisfied dependency expressed through method 'openAiChatModel' parameter 2: No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2024-09-23T09:09:52.081+01:00 INFO 48009 --- [spring-ai-with-webflux] [ main] .s.b.a.l.ConditionEvaluationReportLogger :
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-09-23T09:09:52.104+01:00 ERROR 48009 --- [spring-ai-with-webflux] [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 2 of method openAiChatModel in org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.
Action:
Consider defining a bean of type 'org.springframework.web.client.RestClient$Builder' in your configuration.
Comment From: axymthr
@tzolov Just faced this myself. Is this something only the core team can fix or can anyone submit a patch for it?
Comment From: markpollack
related to https://github.com/spring-projects/spring-ai/issues/524
Comment From: markpollack
I've experimented a bit with this and am not quite sure how to handle it. If one adds
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
or the actuator dependency to the sample app, then we get a RestClientBuilder autoconfigured.
However, in the spring-ai-openai
module I didn't want to pull in spring-boot-starter-web
as someone may want to create a console application. A console app wouldn't need to have dependencies such as embedded tomcat pulled in and would then need to set the spring.main.web-application-type=none
or exclude the tomcat-ebmed deps?
[INFO] | +- org.springframework.boot:spring-boot-starter-web:jar:3.3.4:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.3.4:compile
[INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.30:compile
[INFO] | | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.30:compile
[INFO] | | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.30:compile
[INFO] | | \- org.springframework:spring-webmvc:jar:6.1.13:compile
I'm ok to live with that compromise if there isn't another way to just pick up the autoconfig for RestClient.
Thoughts @wilkinsona ?
Comment From: wilkinsona
I think I'd use a dependency on spring-web
rather than spring-boot-starter-web
as I agree that the latter's much too broad in this situation. I'd also update the injection points for RestClient.Builder
and WebClient.Builder
to use ObjectProvider
and only require one or the other (you could guard this with a custom AnyNestedCondition
that nests classes that are @ConditionalOnBean(RestClient.Builder.class)
and @ConditionalOnBean(WebClient.Builder.class)
). That should give you something that works when someone is building a console app or build a web app using either spring-boot-starter-web
or spring-boot-starter-webflux
.
Comment From: tzolov
1550 should help resolving this issue.
Comment From: fedecompa
I can't use spring-ai latest release 1.0.0-M3 with spring.main.web-application-type=reactive. Application failed to start:
Parameter 2 of method openAiEmbeddingModel in org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.
In this case it should use WebClient with spring webflux.
Comment From: tzolov
@fedecompa could you please test with 1.0.0-SNAPSHOT well (you will have to add the snapshot repository to your pom)? Also can you share, which spring boot starers have enabled in your POM?
Comment From: fedecompa
@tzolov this is my pom:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
</parent>
<properties>
<java.version>17</java.version>
<spring.ai.bom.version>1.0.0-M3</spring.ai.bom.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring.ai.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
</dependency>
</dependencies>
Comment From: fedecompa
@tzolov with the 1.0.0-SNAPSHOT version it works! When will the fix be released? Thanks