Skip to content

Commit a10815b

Browse files
Fix NPE caused by uninitialized static variables in interfaces in native images
Signed-off-by: jonghoon park <[email protected]>
1 parent 144ae1e commit a10815b

File tree

7 files changed

+48
-15
lines changed

7 files changed

+48
-15
lines changed

advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.ai.chat.client.ChatClientResponse;
2929
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
3030
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
31+
import org.springframework.ai.chat.client.advisor.api.SchedulerHolder;
3132
import org.springframework.ai.chat.messages.UserMessage;
3233
import org.springframework.ai.chat.model.ChatResponse;
3334
import org.springframework.ai.chat.prompt.PromptTemplate;
@@ -83,8 +84,8 @@ public class QuestionAnswerAdvisor implements BaseAdvisor {
8384
private final int order;
8485

8586
public QuestionAnswerAdvisor(VectorStore vectorStore) {
86-
this(vectorStore, SearchRequest.builder().build(), DEFAULT_PROMPT_TEMPLATE, BaseAdvisor.DEFAULT_SCHEDULER,
87-
DEFAULT_ORDER);
87+
this(vectorStore, SearchRequest.builder().build(), DEFAULT_PROMPT_TEMPLATE,
88+
SchedulerHolder.getDefaultScheduler(), DEFAULT_ORDER);
8889
}
8990

9091
QuestionAnswerAdvisor(VectorStore vectorStore, SearchRequest searchRequest, @Nullable PromptTemplate promptTemplate,
@@ -95,7 +96,7 @@ public QuestionAnswerAdvisor(VectorStore vectorStore) {
9596
this.vectorStore = vectorStore;
9697
this.searchRequest = searchRequest;
9798
this.promptTemplate = promptTemplate != null ? promptTemplate : DEFAULT_PROMPT_TEMPLATE;
98-
this.scheduler = scheduler != null ? scheduler : BaseAdvisor.DEFAULT_SCHEDULER;
99+
this.scheduler = scheduler != null ? scheduler : SchedulerHolder.getDefaultScheduler();
99100
this.order = order;
100101
}
101102

@@ -197,7 +198,7 @@ public Builder searchRequest(SearchRequest searchRequest) {
197198
}
198199

199200
public Builder protectFromBlocking(boolean protectFromBlocking) {
200-
this.scheduler = protectFromBlocking ? BaseAdvisor.DEFAULT_SCHEDULER : Schedulers.immediate();
201+
this.scheduler = protectFromBlocking ? SchedulerHolder.getDefaultScheduler() : Schedulers.immediate();
201202
return this;
202203
}
203204

advisors/spring-ai-advisors-vector-store/src/main/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
import org.springframework.ai.chat.client.ChatClientResponse;
3131
import org.springframework.ai.chat.client.advisor.api.Advisor;
3232
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
33-
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
3433
import org.springframework.ai.chat.client.advisor.api.BaseChatMemoryAdvisor;
34+
import org.springframework.ai.chat.client.advisor.api.SchedulerHolder;
3535
import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
3636
import org.springframework.ai.chat.memory.ChatMemory;
3737
import org.springframework.ai.chat.messages.AssistantMessage;
@@ -223,7 +223,7 @@ public static class Builder {
223223

224224
private String conversationId = ChatMemory.DEFAULT_CONVERSATION_ID;
225225

226-
private Scheduler scheduler = BaseAdvisor.DEFAULT_SCHEDULER;
226+
private Scheduler scheduler = SchedulerHolder.getDefaultScheduler();
227227

228228
private int order = Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER;
229229

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/MessageChatMemoryAdvisor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
import org.springframework.ai.chat.client.ChatClientResponse;
2929
import org.springframework.ai.chat.client.advisor.api.Advisor;
3030
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
31-
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
3231
import org.springframework.ai.chat.client.advisor.api.BaseChatMemoryAdvisor;
32+
import org.springframework.ai.chat.client.advisor.api.SchedulerHolder;
3333
import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
3434
import org.springframework.ai.chat.memory.ChatMemory;
3535
import org.springframework.ai.chat.messages.Message;
@@ -138,7 +138,7 @@ public static final class Builder {
138138

139139
private int order = Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER;
140140

141-
private Scheduler scheduler = BaseAdvisor.DEFAULT_SCHEDULER;
141+
private Scheduler scheduler = SchedulerHolder.getDefaultScheduler();
142142

143143
private ChatMemory chatMemory;
144144

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/PromptChatMemoryAdvisor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import org.springframework.ai.chat.client.ChatClientResponse;
3333
import org.springframework.ai.chat.client.advisor.api.Advisor;
3434
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
35-
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
3635
import org.springframework.ai.chat.client.advisor.api.BaseChatMemoryAdvisor;
36+
import org.springframework.ai.chat.client.advisor.api.SchedulerHolder;
3737
import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
3838
import org.springframework.ai.chat.memory.ChatMemory;
3939
import org.springframework.ai.chat.messages.Message;
@@ -194,7 +194,7 @@ public static final class Builder {
194194

195195
private int order = Advisor.DEFAULT_CHAT_MEMORY_PRECEDENCE_ORDER;
196196

197-
private Scheduler scheduler = BaseAdvisor.DEFAULT_SCHEDULER;
197+
private Scheduler scheduler = SchedulerHolder.getDefaultScheduler();
198198

199199
private ChatMemory chatMemory;
200200

spring-ai-client-chat/src/main/java/org/springframework/ai/chat/client/advisor/api/BaseAdvisor.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import reactor.core.publisher.Flux;
2020
import reactor.core.publisher.Mono;
2121
import reactor.core.scheduler.Scheduler;
22-
import reactor.core.scheduler.Schedulers;
2322

2423
import org.springframework.ai.chat.client.ChatClientRequest;
2524
import org.springframework.ai.chat.client.ChatClientResponse;
@@ -41,8 +40,6 @@
4140
*/
4241
public interface BaseAdvisor extends CallAdvisor, StreamAdvisor {
4342

44-
Scheduler DEFAULT_SCHEDULER = Schedulers.boundedElastic();
45-
4643
@Override
4744
default ChatClientResponse adviseCall(ChatClientRequest chatClientRequest, CallAdvisorChain callAdvisorChain) {
4845
Assert.notNull(chatClientRequest, "chatClientRequest cannot be null");
@@ -92,7 +89,7 @@ default String getName() {
9289
* Scheduler used for processing the advisor logic when streaming.
9390
*/
9491
default Scheduler getScheduler() {
95-
return DEFAULT_SCHEDULER;
92+
return SchedulerHolder.getDefaultScheduler();
9693
}
9794

9895
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.chat.client.advisor.api;
18+
19+
import reactor.core.scheduler.Scheduler;
20+
import reactor.core.scheduler.Schedulers;
21+
22+
/**
23+
* @author Jonghoon Park
24+
* @since 1.0.0
25+
*/
26+
public class SchedulerHolder {
27+
28+
private static final Scheduler DEFAULT_SCHEDULER = Schedulers.boundedElastic();
29+
30+
public static Scheduler getDefaultScheduler() {
31+
return DEFAULT_SCHEDULER;
32+
}
33+
34+
}

spring-ai-rag/src/main/java/org/springframework/ai/rag/advisor/RetrievalAugmentationAdvisor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.ai.chat.client.ChatClientResponse;
3030
import org.springframework.ai.chat.client.advisor.api.AdvisorChain;
3131
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
32+
import org.springframework.ai.chat.client.advisor.api.SchedulerHolder;
3233
import org.springframework.ai.chat.model.ChatResponse;
3334
import org.springframework.ai.document.Document;
3435
import org.springframework.ai.rag.Query;
@@ -95,7 +96,7 @@ private RetrievalAugmentationAdvisor(@Nullable List<QueryTransformer> queryTrans
9596
this.documentPostProcessors = documentPostProcessors != null ? documentPostProcessors : List.of();
9697
this.queryAugmenter = queryAugmenter != null ? queryAugmenter : ContextualQueryAugmenter.builder().build();
9798
this.taskExecutor = taskExecutor != null ? taskExecutor : buildDefaultTaskExecutor();
98-
this.scheduler = scheduler != null ? scheduler : BaseAdvisor.DEFAULT_SCHEDULER;
99+
this.scheduler = scheduler != null ? scheduler : SchedulerHolder.getDefaultScheduler();
99100
this.order = order != null ? order : 0;
100101
}
101102

0 commit comments

Comments
 (0)