Skip to content

Commit ddda65e

Browse files
authored
Merge branch 'spring-projects:main' into log4j2-rolling-policy
2 parents b98d74f + 4be3dc2 commit ddda65e

File tree

57 files changed

+233
-118
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+233
-118
lines changed

buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ private void dataPrefixes(Config config) {
130130
config.accept("spring.ldap");
131131
config.accept("spring.mongodb");
132132
config.accept("spring.neo4j");
133-
config.accept("spring.dao");
133+
config.accept("spring.persistence");
134134
config.accept("spring.data");
135135
config.accept("spring.datasource");
136136
config.accept("spring.jooq");

core/spring-boot-autoconfigure/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ dependencies {
3030

3131
optional("com.github.ben-manes.caffeine:caffeine")
3232
optional("org.aspectj:aspectjweaver")
33-
optional("jakarta.persistence:jakarta.persistence-api")
3433
optional("jakarta.servlet:jakarta.servlet-api")
3534
optional("javax.money:money-api")
3635
optional("org.springframework:spring-web")

core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutionProperties.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ public void setThreadNamePrefix(String threadNamePrefix) {
7979

8080
public static class Simple {
8181

82+
/**
83+
* Whether to cancel remaining tasks on close. Only recommended if threads are
84+
* commonly expected to be stuck.
85+
*/
86+
private boolean cancelRemainingTasksOnClose;
87+
8288
/**
8389
* Whether to reject tasks when the concurrency limit has been reached.
8490
*/
@@ -90,6 +96,14 @@ public static class Simple {
9096
*/
9197
private @Nullable Integer concurrencyLimit;
9298

99+
public boolean isCancelRemainingTasksOnClose() {
100+
return this.cancelRemainingTasksOnClose;
101+
}
102+
103+
public void setCancelRemainingTasksOnClose(boolean cancelRemainingTasksOnClose) {
104+
this.cancelRemainingTasksOnClose = cancelRemainingTasksOnClose;
105+
}
106+
93107
public boolean isRejectTasksWhenLimitReached() {
94108
return this.rejectTasksWhenLimitReached;
95109
}

core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/task/TaskExecutorConfigurations.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ private SimpleAsyncTaskExecutorBuilder builder() {
148148
builder = builder.customizers(this.taskExecutorCustomizers.orderedStream()::iterator);
149149
builder = builder.taskDecorator(getTaskDecorator(this.taskDecorator));
150150
TaskExecutionProperties.Simple simple = this.properties.getSimple();
151+
builder = builder.cancelRemainingTasksOnClose(simple.isCancelRemainingTasksOnClose());
151152
builder = builder.rejectTasksWhenLimitReached(simple.isRejectTasksWhenLimitReached());
152153
builder = builder.concurrencyLimit(simple.getConcurrencyLimit());
153154
TaskExecutionProperties.Shutdown shutdown = this.properties.getShutdown();

core/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorProperties.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -114,28 +114,6 @@ public Whitelabel getWhitelabel() {
114114
return this.whitelabel;
115115
}
116116

117-
/**
118-
* Include Stacktrace attribute options.
119-
*/
120-
public enum IncludeStacktrace {
121-
122-
/**
123-
* Never add stacktrace information.
124-
*/
125-
NEVER,
126-
127-
/**
128-
* Always add stacktrace information.
129-
*/
130-
ALWAYS,
131-
132-
/**
133-
* Add stacktrace attribute when the appropriate request parameter is not "false".
134-
*/
135-
ON_PARAM
136-
137-
}
138-
139117
/**
140118
* Include error attributes options.
141119
*/

core/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfigurationTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@ void shouldSupplyBeans() {
8383
void simpleAsyncTaskExecutorBuilderShouldReadProperties() {
8484
this.contextRunner
8585
.withPropertyValues("spring.task.execution.thread-name-prefix=mytest-",
86+
"spring.task.execution.simple.cancel-remaining-tasks-on-close=true",
8687
"spring.task.execution.simple.reject-tasks-when-limit-reached=true",
8788
"spring.task.execution.simple.concurrency-limit=1",
8889
"spring.task.execution.shutdown.await-termination=true",
8990
"spring.task.execution.shutdown.await-termination-period=30s")
9091
.run(assertSimpleAsyncTaskExecutor((taskExecutor) -> {
92+
assertThat(taskExecutor).hasFieldOrPropertyWithValue("cancelRemainingTasksOnClose", true);
9193
assertThat(taskExecutor).hasFieldOrPropertyWithValue("rejectTasksWhenLimitReached", true);
9294
assertThat(taskExecutor.getConcurrencyLimit()).isEqualTo(1);
9395
assertThat(taskExecutor.getThreadNamePrefix()).isEqualTo("mytest-");

core/spring-boot/src/main/java/org/springframework/boot/task/SimpleAsyncTaskExecutorBuilder.java

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public class SimpleAsyncTaskExecutorBuilder {
5252

5353
private final @Nullable String threadNamePrefix;
5454

55+
private final boolean cancelRemainingTasksOnClose;
56+
5557
private final boolean rejectTasksWhenLimitReached;
5658

5759
private final @Nullable Integer concurrencyLimit;
@@ -63,15 +65,16 @@ public class SimpleAsyncTaskExecutorBuilder {
6365
private final @Nullable Duration taskTerminationTimeout;
6466

6567
public SimpleAsyncTaskExecutorBuilder() {
66-
this(null, null, false, null, null, null, null);
68+
this(null, null, false, false, null, null, null, null);
6769
}
6870

6971
private SimpleAsyncTaskExecutorBuilder(@Nullable Boolean virtualThreads, @Nullable String threadNamePrefix,
70-
boolean rejectTasksWhenLimitReached, @Nullable Integer concurrencyLimit,
71-
@Nullable TaskDecorator taskDecorator, @Nullable Set<SimpleAsyncTaskExecutorCustomizer> customizers,
72-
@Nullable Duration taskTerminationTimeout) {
72+
boolean cancelRemainingTasksOnClose, boolean rejectTasksWhenLimitReached,
73+
@Nullable Integer concurrencyLimit, @Nullable TaskDecorator taskDecorator,
74+
@Nullable Set<SimpleAsyncTaskExecutorCustomizer> customizers, @Nullable Duration taskTerminationTimeout) {
7375
this.virtualThreads = virtualThreads;
7476
this.threadNamePrefix = threadNamePrefix;
77+
this.cancelRemainingTasksOnClose = cancelRemainingTasksOnClose;
7578
this.rejectTasksWhenLimitReached = rejectTasksWhenLimitReached;
7679
this.concurrencyLimit = concurrencyLimit;
7780
this.taskDecorator = taskDecorator;
@@ -86,8 +89,8 @@ private SimpleAsyncTaskExecutorBuilder(@Nullable Boolean virtualThreads, @Nullab
8689
*/
8790
public SimpleAsyncTaskExecutorBuilder threadNamePrefix(@Nullable String threadNamePrefix) {
8891
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, threadNamePrefix,
89-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator, this.customizers,
90-
this.taskTerminationTimeout);
92+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
93+
this.taskDecorator, this.customizers, this.taskTerminationTimeout);
9194
}
9295

9396
/**
@@ -97,8 +100,26 @@ public SimpleAsyncTaskExecutorBuilder threadNamePrefix(@Nullable String threadNa
97100
*/
98101
public SimpleAsyncTaskExecutorBuilder virtualThreads(@Nullable Boolean virtualThreads) {
99102
return new SimpleAsyncTaskExecutorBuilder(virtualThreads, this.threadNamePrefix,
100-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator, this.customizers,
101-
this.taskTerminationTimeout);
103+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
104+
this.taskDecorator, this.customizers, this.taskTerminationTimeout);
105+
}
106+
107+
/**
108+
* Set whether to cancel remaining tasks on close. By default {@code false} not
109+
* tracking active threads at all or just interrupting any remaining threads that
110+
* still have not finished after the specified {@link #taskTerminationTimeout
111+
* taskTerminationTimeout}. Switch this to {@code true} for immediate interruption on
112+
* close, either in combination with a subsequent termination timeout or without any
113+
* waiting at all, depending on whether a {@code taskTerminationTimeout} has been
114+
* specified as well.
115+
* @param cancelRemainingTasksOnClose whether to cancel remaining tasks on close
116+
* @return a new builder instance
117+
* @since 4.0.0
118+
*/
119+
public SimpleAsyncTaskExecutorBuilder cancelRemainingTasksOnClose(boolean cancelRemainingTasksOnClose) {
120+
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
121+
cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
122+
this.taskDecorator, this.customizers, this.taskTerminationTimeout);
102123
}
103124

104125
/**
@@ -112,8 +133,8 @@ public SimpleAsyncTaskExecutorBuilder virtualThreads(@Nullable Boolean virtualTh
112133
*/
113134
public SimpleAsyncTaskExecutorBuilder rejectTasksWhenLimitReached(boolean rejectTasksWhenLimitReached) {
114135
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
115-
rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator, this.customizers,
116-
this.taskTerminationTimeout);
136+
this.cancelRemainingTasksOnClose, rejectTasksWhenLimitReached, this.concurrencyLimit,
137+
this.taskDecorator, this.customizers, this.taskTerminationTimeout);
117138
}
118139

119140
/**
@@ -123,8 +144,8 @@ public SimpleAsyncTaskExecutorBuilder rejectTasksWhenLimitReached(boolean reject
123144
*/
124145
public SimpleAsyncTaskExecutorBuilder concurrencyLimit(@Nullable Integer concurrencyLimit) {
125146
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
126-
this.rejectTasksWhenLimitReached, concurrencyLimit, this.taskDecorator, this.customizers,
127-
this.taskTerminationTimeout);
147+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, concurrencyLimit,
148+
this.taskDecorator, this.customizers, this.taskTerminationTimeout);
128149
}
129150

130151
/**
@@ -134,8 +155,8 @@ public SimpleAsyncTaskExecutorBuilder concurrencyLimit(@Nullable Integer concurr
134155
*/
135156
public SimpleAsyncTaskExecutorBuilder taskDecorator(@Nullable TaskDecorator taskDecorator) {
136157
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
137-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, taskDecorator, this.customizers,
138-
this.taskTerminationTimeout);
158+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
159+
taskDecorator, this.customizers, this.taskTerminationTimeout);
139160
}
140161

141162
/**
@@ -146,8 +167,8 @@ public SimpleAsyncTaskExecutorBuilder taskDecorator(@Nullable TaskDecorator task
146167
*/
147168
public SimpleAsyncTaskExecutorBuilder taskTerminationTimeout(@Nullable Duration taskTerminationTimeout) {
148169
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
149-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator, this.customizers,
150-
taskTerminationTimeout);
170+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
171+
this.taskDecorator, this.customizers, taskTerminationTimeout);
151172
}
152173

153174
/**
@@ -177,8 +198,8 @@ public SimpleAsyncTaskExecutorBuilder customizers(
177198
Iterable<? extends SimpleAsyncTaskExecutorCustomizer> customizers) {
178199
Assert.notNull(customizers, "'customizers' must not be null");
179200
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
180-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator, append(null, customizers),
181-
this.taskTerminationTimeout);
201+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
202+
this.taskDecorator, append(null, customizers), this.taskTerminationTimeout);
182203
}
183204

184205
/**
@@ -206,8 +227,8 @@ public SimpleAsyncTaskExecutorBuilder additionalCustomizers(
206227
Iterable<? extends SimpleAsyncTaskExecutorCustomizer> customizers) {
207228
Assert.notNull(customizers, "'customizers' must not be null");
208229
return new SimpleAsyncTaskExecutorBuilder(this.virtualThreads, this.threadNamePrefix,
209-
this.rejectTasksWhenLimitReached, this.concurrencyLimit, this.taskDecorator,
210-
append(this.customizers, customizers), this.taskTerminationTimeout);
230+
this.cancelRemainingTasksOnClose, this.rejectTasksWhenLimitReached, this.concurrencyLimit,
231+
this.taskDecorator, append(this.customizers, customizers), this.taskTerminationTimeout);
211232
}
212233

213234
/**
@@ -246,6 +267,7 @@ public <T extends SimpleAsyncTaskExecutor> T configure(T taskExecutor) {
246267
PropertyMapper map = PropertyMapper.get();
247268
map.from(this.virtualThreads).to(taskExecutor::setVirtualThreads);
248269
map.from(this.threadNamePrefix).whenHasText().to(taskExecutor::setThreadNamePrefix);
270+
map.from(this.cancelRemainingTasksOnClose).to(taskExecutor::setCancelRemainingTasksOnClose);
249271
map.from(this.rejectTasksWhenLimitReached).to(taskExecutor::setRejectTasksWhenLimitReached);
250272
map.from(this.concurrencyLimit).to(taskExecutor::setConcurrencyLimit);
251273
map.from(this.taskDecorator).to(taskExecutor::setTaskDecorator);

core/spring-boot/src/test/java/org/springframework/boot/task/SimpleAsyncTaskExecutorBuilderTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ void virtualThreadsShouldApply() {
5959
SimpleAsyncTaskExecutorAssert.assertThat(executor).usesVirtualThreads();
6060
}
6161

62+
@Test
63+
void cancelRemainingTasksOnCloseShouldApply() {
64+
SimpleAsyncTaskExecutor executor = this.builder.cancelRemainingTasksOnClose(true).build();
65+
assertThat(executor).extracting("cancelRemainingTasksOnClose").isEqualTo(true);
66+
}
67+
6268
@Test
6369
void rejectTasksWhenLimitReachedShouldApply() {
6470
SimpleAsyncTaskExecutor executor = this.builder.rejectTasksWhenLimitReached(true).build();

documentation/spring-boot-docs/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ dependencies {
105105
implementation(project(path: ":module:spring-boot-jsonb"))
106106
implementation(project(path: ":module:spring-boot-ldap"))
107107
implementation(project(path: ":module:spring-boot-micrometer-metrics"))
108+
implementation(project(path: ":module:spring-boot-persistence"))
108109
implementation(project(path: ":module:spring-boot-r2dbc"))
109110
implementation(project(path: ":module:spring-boot-reactor-netty"))
110111
implementation(project(path: ":module:spring-boot-restclient"))

documentation/spring-boot-docs/src/docs/antora/modules/ROOT/pages/system-requirements.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[[getting-started.system-requirements]]
22
= System Requirements
33

4-
Spring Boot {version-spring-boot} requires at least https://www.java.com[Java 17] and is compatible with versions up to and including Java 24.
4+
Spring Boot {version-spring-boot} requires at least https://www.java.com[Java 17] and is compatible with versions up to and including Java 25.
55
{url-spring-framework-docs}/[Spring Framework {version-spring-framework}] or above is also required.
66

77
Explicit build support is provided for the following build tools:

0 commit comments

Comments
 (0)