Skip to content

Commit 5cc0e4b

Browse files
committed
Merge branch '4.0.x'
Closes gh-48956
2 parents 27e3ddc + 5f5217d commit 5cc0e4b

File tree

6 files changed

+140
-37
lines changed

6 files changed

+140
-37
lines changed

buildSrc/src/main/java/org/springframework/boot/build/ConventionsPlugin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public void apply(Project project) {
4646
SystemRequirementsExtension systemRequirements = project.getExtensions()
4747
.create("systemRequirements", SystemRequirementsExtension.class);
4848
new NoHttpConventions().apply(project);
49-
new JavaConventions(systemRequirements.getJava()).apply(project);
49+
new JavaConventions(systemRequirements).apply(project);
5050
new MavenPublishingConventions().apply(project);
5151
new AntoraConventions().apply(project);
5252
new KotlinConventions().apply(project);

buildSrc/src/main/java/org/springframework/boot/build/EclipseConventions.java

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@
1616

1717
package org.springframework.boot.build;
1818

19+
import org.gradle.api.DomainObjectCollection;
20+
import org.gradle.api.JavaVersion;
1921
import org.gradle.api.Project;
2022
import org.gradle.api.plugins.JavaBasePlugin;
23+
import org.gradle.api.tasks.TaskProvider;
2124
import org.gradle.plugins.ide.api.XmlFileContentMerger;
2225
import org.gradle.plugins.ide.eclipse.EclipsePlugin;
2326
import org.gradle.plugins.ide.eclipse.model.Classpath;
2427
import org.gradle.plugins.ide.eclipse.model.ClasspathEntry;
2528
import org.gradle.plugins.ide.eclipse.model.EclipseClasspath;
29+
import org.gradle.plugins.ide.eclipse.model.EclipseJdt;
2630
import org.gradle.plugins.ide.eclipse.model.EclipseModel;
2731
import org.gradle.plugins.ide.eclipse.model.Library;
2832

@@ -35,12 +39,35 @@
3539
class EclipseConventions {
3640

3741
void apply(Project project) {
38-
project.getPlugins()
39-
.withType(EclipsePlugin.class,
40-
(eclipse) -> project.getPlugins().withType(JavaBasePlugin.class, (javaBase) -> {
41-
EclipseModel eclipseModel = project.getExtensions().getByType(EclipseModel.class);
42-
eclipseModel.classpath(this::configureClasspath);
43-
}));
42+
project.getPlugins().withType(EclipsePlugin.class, (eclipse) -> configure(project, eclipse));
43+
}
44+
45+
private DomainObjectCollection<JavaBasePlugin> configure(Project project, EclipsePlugin eclipsePlugin) {
46+
TaskProvider<EclipseSynchronizeJdtSettings> eclipseSynchronizeJdtSettings = registerEclipseSynchronizeJdtSettingsTask(
47+
project);
48+
return project.getPlugins().withType(JavaBasePlugin.class, (javaBase) -> {
49+
EclipseModel model = project.getExtensions().getByType(EclipseModel.class);
50+
model.synchronizationTasks(eclipseSynchronizeJdtSettings);
51+
model.jdt(this::configureJdt);
52+
model.classpath(this::configureClasspath);
53+
});
54+
}
55+
56+
private TaskProvider<EclipseSynchronizeJdtSettings> registerEclipseSynchronizeJdtSettingsTask(Project project) {
57+
TaskProvider<EclipseSynchronizeJdtSettings> taskProvider = project.getTasks()
58+
.register("eclipseSynchronizateJdt", EclipseSynchronizeJdtSettings.class);
59+
taskProvider.configure((task) -> {
60+
task.setDescription("Synchronizate the Eclipse JDT settings file from Buildship.");
61+
task.setOutputFile(project.file(".settings/org.eclipse.jdt.core.prefs"));
62+
task.setInputFile(project.file(".settings/org.eclipse.jdt.core.prefs"));
63+
});
64+
return taskProvider;
65+
}
66+
67+
private void configureJdt(EclipseJdt jdt) {
68+
jdt.setSourceCompatibility(JavaVersion.toVersion(JavaConventions.RUNTIME_JAVA_VERSION));
69+
jdt.setTargetCompatibility(JavaVersion.toVersion(JavaConventions.RUNTIME_JAVA_VERSION));
70+
jdt.setJavaRuntimeName("JavaSE-" + JavaConventions.BUILD_JAVA_VERSION);
4471
}
4572

4673
private void configureClasspath(EclipseClasspath classpath) {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 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.boot.build;
18+
19+
import java.util.Properties;
20+
21+
import org.gradle.api.Task;
22+
import org.gradle.api.internal.PropertiesTransformer;
23+
import org.gradle.plugins.ide.api.PropertiesGeneratorTask;
24+
import org.gradle.plugins.ide.internal.generator.PropertiesPersistableConfigurationObject;
25+
26+
import org.springframework.boot.build.EclipseSynchronizeJdtSettings.Configuration;
27+
28+
/**
29+
* {@link Task} to do something.
30+
*
31+
* @author Phillip Webb
32+
*/
33+
public abstract class EclipseSynchronizeJdtSettings extends PropertiesGeneratorTask<Configuration> {
34+
35+
@Override
36+
protected Configuration create() {
37+
return new Configuration(getTransformer());
38+
}
39+
40+
@Override
41+
protected void configure(Configuration configuration) {
42+
}
43+
44+
static class Configuration extends PropertiesPersistableConfigurationObject {
45+
46+
Configuration(PropertiesTransformer transformer) {
47+
super(transformer);
48+
}
49+
50+
@Override
51+
protected String getDefaultResourceName() {
52+
return null;
53+
}
54+
55+
@Override
56+
protected void load(Properties properties) {
57+
}
58+
59+
@Override
60+
protected void store(Properties properties) {
61+
properties.put("org.eclipse.jdt.core.compiler.release", "true");
62+
}
63+
64+
}
65+
66+
}

buildSrc/src/main/java/org/springframework/boot/build/JavaConventions.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616

1717
package org.springframework.boot.build;
1818

19+
import java.util.ArrayList;
1920
import java.util.Arrays;
2021
import java.util.Collections;
22+
import java.util.LinkedHashSet;
2123
import java.util.List;
2224
import java.util.Map;
2325
import java.util.Set;
@@ -32,6 +34,8 @@
3234
import io.spring.javaformat.gradle.SpringJavaFormatPlugin;
3335
import io.spring.javaformat.gradle.tasks.CheckFormat;
3436
import io.spring.javaformat.gradle.tasks.Format;
37+
import org.gradle.api.GradleException;
38+
import org.gradle.api.JavaVersion;
3539
import org.gradle.api.Project;
3640
import org.gradle.api.Task;
3741
import org.gradle.api.artifacts.Configuration;
@@ -52,8 +56,10 @@
5256
import org.gradle.api.tasks.javadoc.Javadoc;
5357
import org.gradle.api.tasks.testing.Test;
5458
import org.gradle.external.javadoc.CoreJavadocOptions;
59+
import org.gradle.jvm.toolchain.JavaCompiler;
60+
import org.gradle.jvm.toolchain.JavaInstallationMetadata;
61+
import org.gradle.jvm.toolchain.JavaLanguageVersion;
5562

56-
import org.springframework.boot.build.SystemRequirementsExtension.JavaSpec;
5763
import org.springframework.boot.build.architecture.ArchitecturePlugin;
5864
import org.springframework.boot.build.classpath.CheckClasspathForProhibitedDependencies;
5965
import org.springframework.boot.build.optional.OptionalDependenciesPlugin;
@@ -127,10 +133,14 @@
127133
*/
128134
class JavaConventions {
129135

130-
private final JavaSpec javaSpec;
136+
public static final int BUILD_JAVA_VERSION = 25;
131137

132-
JavaConventions(JavaSpec javaSpec) {
133-
this.javaSpec = javaSpec;
138+
public static final int RUNTIME_JAVA_VERSION = 17;
139+
140+
private final SystemRequirementsExtension systemRequirements;
141+
142+
JavaConventions(SystemRequirementsExtension systemRequirements) {
143+
this.systemRequirements = systemRequirements;
134144
}
135145

136146
void apply(Project project) {
@@ -169,7 +179,8 @@ private void configureJarManifestConventions(Project project) {
169179
jar.manifest((manifest) -> {
170180
Map<String, Object> attributes = new TreeMap<>();
171181
attributes.put("Automatic-Module-Name", project.getName().replace("-", "."));
172-
attributes.put("Build-Jdk-Spec", this.javaSpec.getVersion());
182+
// Build-Jdk-Spec is used by buildpacks to pick the JRE to install
183+
attributes.put("Build-Jdk-Spec", this.systemRequirements.getJava().getVersion());
173184
attributes.put("Built-By", "Spring");
174185
attributes.put("Implementation-Title",
175186
determineImplementationTitle(project, sourceJarTaskNames, javadocJarTaskNames, jar));
@@ -248,17 +259,30 @@ private void addValuelessOption(CoreJavadocOptions options, String option) {
248259

249260
private void configureJavaConventions(Project project) {
250261
project.getTasks().withType(JavaCompile.class, (compile) -> {
262+
compile.doFirst((task) -> assertCompatible(compile));
251263
compile.getOptions().setEncoding("UTF-8");
252-
compile.getOptions().getRelease().set(this.javaSpec.getVersion());
253-
List<String> args = compile.getOptions().getCompilerArgs();
254-
if (!args.contains("-parameters")) {
255-
args.add("-parameters");
256-
}
257-
args.addAll(Arrays.asList("-Werror", "-Xlint:unchecked", "-Xlint:deprecation", "-Xlint:rawtypes",
264+
compile.getOptions().getRelease().set(RUNTIME_JAVA_VERSION);
265+
Set<String> args = new LinkedHashSet<>(compile.getOptions().getCompilerArgs());
266+
args.addAll(List.of("-parameters", "-Werror", "-Xlint:unchecked", "-Xlint:deprecation", "-Xlint:rawtypes",
258267
"-Xlint:varargs"));
268+
compile.getOptions().setCompilerArgs(new ArrayList<>(args));
259269
});
260270
}
261271

272+
private void assertCompatible(JavaCompile compile) {
273+
JavaVersion requiredVersion = JavaVersion.toVersion(BUILD_JAVA_VERSION);
274+
JavaVersion actualVersion = compile.getJavaCompiler()
275+
.map(JavaCompiler::getMetadata)
276+
.map(JavaInstallationMetadata::getLanguageVersion)
277+
.map(JavaLanguageVersion::asInt)
278+
.map(JavaVersion::toVersion)
279+
.orElse(JavaVersion.current())
280+
.get();
281+
if (!actualVersion.isCompatibleWith(requiredVersion)) {
282+
throw new GradleException("This project should be built with Java %s or above".formatted(requiredVersion));
283+
}
284+
}
285+
262286
private void configureSpringJavaFormat(Project project) {
263287
project.getPlugins().apply(SpringJavaFormatPlugin.class);
264288
project.getTasks().withType(Format.class, (Format) -> Format.setEncoding("UTF-8"));

buildSrc/src/main/java/org/springframework/boot/build/SystemRequirementsExtension.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@
1919
import javax.inject.Inject;
2020

2121
import org.gradle.api.Action;
22-
import org.gradle.api.Project;
2322
import org.gradle.api.model.ObjectFactory;
24-
import org.gradle.api.plugins.JavaPluginExtension;
25-
import org.gradle.jvm.toolchain.JavaLanguageVersion;
2623

2724
/**
2825
* DSL extension for configuring a project's system requirements.
@@ -34,8 +31,8 @@ public class SystemRequirementsExtension {
3431
private final JavaSpec javaSpec;
3532

3633
@Inject
37-
public SystemRequirementsExtension(Project project, ObjectFactory objects) {
38-
this.javaSpec = objects.newInstance(JavaSpec.class, project);
34+
public SystemRequirementsExtension(ObjectFactory objects) {
35+
this.javaSpec = objects.newInstance(JavaSpec.class);
3936
}
4037

4138
public void java(Action<JavaSpec> action) {
@@ -48,24 +45,13 @@ public JavaSpec getJava() {
4845

4946
public abstract static class JavaSpec {
5047

51-
private final Project project;
52-
5348
private int version = 17;
5449

55-
@Inject
56-
public JavaSpec(Project project) {
57-
this.project = project;
58-
}
59-
6050
public int getVersion() {
6151
return this.version;
6252
}
6353

6454
public void setVersion(int version) {
65-
JavaLanguageVersion javaVersion = JavaLanguageVersion.of(version);
66-
JavaPluginExtension javaPluginExtension = this.project.getExtensions().getByType(JavaPluginExtension.class);
67-
javaPluginExtension.setSourceCompatibility(javaVersion);
68-
javaPluginExtension.setTargetCompatibility(javaVersion);
6955
this.version = version;
7056
}
7157

buildSrc/src/main/java/org/springframework/boot/build/toolchain/ToolchainExtension.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.gradle.jvm.toolchain.JavaLanguageVersion;
2323

2424
import org.springframework.boot.build.SystemRequirementsExtension;
25-
import org.springframework.boot.build.SystemRequirementsExtension.JavaSpec;
2625

2726
/**
2827
* DSL extension for {@link ToolchainPlugin}.
@@ -36,9 +35,10 @@ public abstract class ToolchainExtension {
3635
public ToolchainExtension(Project project) {
3736
String toolchainVersion = (String) project.findProperty("toolchainVersion");
3837
this.javaVersion = (toolchainVersion != null) ? JavaLanguageVersion.of(toolchainVersion) : null;
39-
JavaSpec javaSpec = project.getExtensions().getByType(SystemRequirementsExtension.class).getJava();
38+
SystemRequirementsExtension systemRequirements = project.getExtensions()
39+
.getByType(SystemRequirementsExtension.class);
4040
getMinimumCompatibleJavaVersion()
41-
.convention(project.provider(() -> JavaLanguageVersion.of(javaSpec.getVersion())));
41+
.convention(project.provider(() -> JavaLanguageVersion.of(systemRequirements.getJava().getVersion())));
4242
}
4343

4444
public abstract Property<JavaLanguageVersion> getMinimumCompatibleJavaVersion();

0 commit comments

Comments
 (0)