Use Java version and vendor from pipeline properties.
Ensure that we use always the specified Java version. See #193
This commit is contained in:
@@ -16,11 +16,16 @@
|
||||
package org.springframework.data.release.build;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -35,11 +40,12 @@ import javax.annotation.PreDestroy;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import org.springframework.data.release.model.JavaVersionAware;
|
||||
import org.springframework.data.release.dependency.InfrastructureOperations;
|
||||
import org.springframework.data.release.io.Workspace;
|
||||
import org.springframework.data.release.model.JavaVersion;
|
||||
import org.springframework.data.release.model.Project;
|
||||
import org.springframework.data.release.model.ProjectAware;
|
||||
import org.springframework.data.release.utils.ListWrapperCollector;
|
||||
import org.springframework.data.release.utils.Logger;
|
||||
import org.springframework.data.util.Streamable;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -51,19 +57,13 @@ import org.springframework.util.Assert;
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
class BuildExecutor {
|
||||
|
||||
private final @NonNull PluginRegistry<BuildSystem, Project> buildSystems;
|
||||
private final MavenProperties mavenProperties;
|
||||
private final ExecutorService executor;
|
||||
|
||||
public BuildExecutor(PluginRegistry<BuildSystem, Project> buildSystems, Logger logger,
|
||||
MavenProperties mavenProperties, ExecutorService buildExecutor) {
|
||||
|
||||
this.buildSystems = buildSystems;
|
||||
this.mavenProperties = mavenProperties;
|
||||
this.executor = buildExecutor;
|
||||
}
|
||||
private final Workspace workspace;
|
||||
|
||||
@PreDestroy
|
||||
public void shutdown() {
|
||||
@@ -162,20 +162,14 @@ class BuildExecutor {
|
||||
Supplier<IllegalStateException> exception = () -> new IllegalStateException(
|
||||
String.format("No build system plugin found for project %s!", module.getProject()));
|
||||
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getProject(), exception);
|
||||
BuildSystem buildSystemToUse;
|
||||
|
||||
if (module instanceof JavaVersionAware) {
|
||||
buildSystemToUse = buildSystem.withJavaVersion(((JavaVersionAware) module).getJavaVersion());
|
||||
} else {
|
||||
buildSystemToUse = buildSystem;
|
||||
}
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getProject(), exception)
|
||||
.withJavaVersion(detectJavaVersion(module.getProject()));
|
||||
|
||||
Runnable runnable = () -> {
|
||||
|
||||
try {
|
||||
|
||||
result.complete(function.apply(buildSystemToUse, module));
|
||||
result.complete(function.apply(buildSystem, module));
|
||||
} catch (Exception e) {
|
||||
result.completeExceptionally(e);
|
||||
}
|
||||
@@ -186,6 +180,24 @@ class BuildExecutor {
|
||||
return result;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public JavaVersion detectJavaVersion(Project project) {
|
||||
|
||||
File ciProperties = workspace.getFile(InfrastructureOperations.CI_PROPERTIES, project);
|
||||
|
||||
if (!ciProperties.exists()) {
|
||||
throw new IllegalStateException(String.format("Cannot find %s for project %s", ciProperties, project));
|
||||
}
|
||||
|
||||
Properties properties = new Properties();
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(ciProperties)) {
|
||||
properties.load(fis);
|
||||
}
|
||||
|
||||
return JavaVersion.fromDockerTag(properties.getProperty("java.main.tag"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new collector to toSummaryCollector {@link ExecutionResult} as {@link Summary} using the {@link Stream}
|
||||
* API.
|
||||
|
||||
@@ -222,7 +222,7 @@ public class BuildOperations {
|
||||
|
||||
BuildSystem buildSystem = buildSystems.getPluginFor(module.getProject(), exception);
|
||||
|
||||
return function.apply(buildSystem.withJavaVersion(module.getJavaVersion()), module);
|
||||
return function.apply(buildSystem.withJavaVersion(executor.detectJavaVersion(module.getProject())), module);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -91,6 +91,10 @@ public class JavaRuntimes {
|
||||
.orElseThrow(() -> new NoSuchElementException(String.format("%s%nAvailable JDK: %s", message.get(), jdks)));
|
||||
}
|
||||
|
||||
public static List<JdkInstallation> getJdks() {
|
||||
return JDKS.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* JDK detection strategy.
|
||||
*/
|
||||
@@ -125,7 +129,10 @@ public class JavaRuntimes {
|
||||
}
|
||||
|
||||
public static Selector from(JavaVersion javaVersion) {
|
||||
return builder().and(it -> javaVersion.getVersionDetector().test(it.getVersion()))
|
||||
|
||||
return builder()
|
||||
.and(it -> javaVersion.getVersionDetector().test(it.getVersion())
|
||||
&& javaVersion.getImplementor().test(it.getImplementor()))
|
||||
.message("Cannot find Java " + javaVersion.getName());
|
||||
}
|
||||
|
||||
@@ -184,10 +191,29 @@ public class JavaRuntimes {
|
||||
version = Version.parse(candidateVersion);
|
||||
}
|
||||
|
||||
return new JdkInstallation(version, it.getName(), it);
|
||||
String implementor = normalizeImplementor(parseImplementor(it));
|
||||
|
||||
return new JdkInstallation(version, toDisplayName(implementor, candidateVersion), implementor, it);
|
||||
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String parseImplementor(File candidateHome) {
|
||||
|
||||
List<String> release = FileUtils.readLines(new File(candidateHome, "release"));
|
||||
|
||||
for (String line : release) {
|
||||
|
||||
if (line.startsWith("IMPLEMENTOR=")) {
|
||||
String substring = line.substring(line.indexOf("=\""));
|
||||
substring = substring.substring(2, substring.length() - 1);
|
||||
return substring;
|
||||
}
|
||||
}
|
||||
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +234,8 @@ public class JavaRuntimes {
|
||||
public List<JdkInstallation> detect() {
|
||||
|
||||
return Collections
|
||||
.singletonList(new JdkInstallation(JavaVersion.parse(javaVersion), javaVendor + " " + javaVersion, javaHome));
|
||||
.singletonList(new JdkInstallation(JavaVersion.parse(javaVersion), toDisplayName(javaVendor, javaVersion),
|
||||
normalizeImplementor(javaVendor), javaHome));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,6 +279,7 @@ public class JavaRuntimes {
|
||||
String jvmHomePath = dict.get("JVMHomePath").toJavaObject(String.class);
|
||||
String name = dict.get("JVMName").toJavaObject(String.class);
|
||||
String version = dict.get("JVMVersion").toJavaObject(String.class);
|
||||
String vendor = dict.get("JVMVendor").toJavaObject(String.class);
|
||||
|
||||
Matcher matcher = VERSION.matcher(version);
|
||||
if (!matcher.find()) {
|
||||
@@ -259,7 +287,9 @@ public class JavaRuntimes {
|
||||
+ ". This should not happen in an ideal world, check the VERSION regex.");
|
||||
}
|
||||
|
||||
return new JdkInstallation(JavaVersion.parse(matcher.group(1)), name, new File(jvmHomePath));
|
||||
String implementor = normalizeImplementor(vendor);
|
||||
return new JdkInstallation(JavaVersion.parse(matcher.group(1)), toDisplayName(implementor, version),
|
||||
implementor, new File(jvmHomePath));
|
||||
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
@@ -270,6 +300,7 @@ public class JavaRuntimes {
|
||||
|
||||
Version version;
|
||||
String name;
|
||||
String implementor;
|
||||
File home;
|
||||
|
||||
@Override
|
||||
@@ -277,4 +308,26 @@ public class JavaRuntimes {
|
||||
return this.version.compareTo(o.version);
|
||||
}
|
||||
}
|
||||
|
||||
static String normalizeImplementor(String implementor) {
|
||||
|
||||
if (implementor.equals("Eclipse Adoptium")) {
|
||||
return "Eclipse Temurin";
|
||||
}
|
||||
|
||||
if (implementor.equals("Eclipse Foundation")) {
|
||||
return "Eclipse Temurin";
|
||||
}
|
||||
|
||||
return implementor;
|
||||
}
|
||||
|
||||
static String toDisplayName(String implementor, String version) {
|
||||
|
||||
if (implementor.startsWith("Oracle")) {
|
||||
implementor = "Oracle Java";
|
||||
}
|
||||
|
||||
return implementor + " " + version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.data.release.model;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Value object representing a Java version.
|
||||
@@ -27,20 +29,49 @@ import java.util.function.Predicate;
|
||||
@Value(staticConstructor = "of")
|
||||
public class JavaVersion {
|
||||
|
||||
private static final Pattern DOCKER_TAG_PATTERN = Pattern.compile("((:?\\d+(:?u\\d+)?(:?\\.\\d+)*)).*");
|
||||
|
||||
public static final JavaVersion JAVA_8 = of("1.8.0_312");
|
||||
|
||||
public static final JavaVersion JAVA_17 = of("Java 17", version -> version.getMajor() == 17);
|
||||
public static final JavaVersion JAVA_17 = of("Java 17", version -> version.getMajor() == 17, it -> true);
|
||||
|
||||
String name;
|
||||
Predicate<Version> versionDetector;
|
||||
Predicate<String> implementor;
|
||||
|
||||
public static JavaVersion of(String version) {
|
||||
Version expectedVersion = parse(version);
|
||||
return of("Java " + version, candidate -> candidate.is(expectedVersion));
|
||||
return of("Java " + version, candidate -> candidate.is(expectedVersion), it -> true);
|
||||
}
|
||||
|
||||
public static Version parse(String version) {
|
||||
return Version.parse(version.replace('_', '.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a docker tag into a Java version using {@code eclipse-temurin} conventions.
|
||||
*
|
||||
* @param tagName
|
||||
* @return
|
||||
*/
|
||||
public static JavaVersion fromDockerTag(String tagName) {
|
||||
|
||||
Pattern versionExtractor = Pattern.compile("(:?\\d+(:?u\\d+)?(:?\\.\\d+)*).*");
|
||||
Matcher matcher = versionExtractor.matcher(tagName);
|
||||
if (!matcher.find()) {
|
||||
throw new IllegalStateException(String.format("Cannot parse Java version '%s'", tagName));
|
||||
}
|
||||
|
||||
String plainVersion = matcher.group(1);
|
||||
|
||||
if (plainVersion.startsWith("8u")) {
|
||||
return of("1.8.0_" + plainVersion.substring(2));
|
||||
}
|
||||
|
||||
return of(plainVersion).withImplementor("Temurin");
|
||||
}
|
||||
|
||||
public JavaVersion withImplementor(String implementor) {
|
||||
return of(String.format("%s (%s)", name, implementor), versionDetector, it -> it.contains(implementor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface JavaVersionAware {
|
||||
|
||||
JavaVersion getJavaVersion();
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.release.model;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -28,31 +27,25 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
@Value
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Module implements VersionAware, ProjectAware, JavaVersionAware, Comparable<Module> {
|
||||
public class Module implements VersionAware, ProjectAware, Comparable<Module> {
|
||||
|
||||
Project project;
|
||||
Version version;
|
||||
Iteration customFirstIteration;
|
||||
@With JavaVersion javaVersion;
|
||||
|
||||
public Module(Project project, String version) {
|
||||
this(project, version, null, JavaVersion.JAVA_8);
|
||||
this(project, version, null);
|
||||
}
|
||||
|
||||
|
||||
Module(Project project, String version, String customFirstIteration) {
|
||||
this(project, version, customFirstIteration, JavaVersion.JAVA_8);
|
||||
}
|
||||
|
||||
Module(Project project, String version, String customFirstIteration, JavaVersion javaVersion) {
|
||||
|
||||
Assert.notNull(project, "Project must not be null!");
|
||||
Assert.notNull(javaVersion, "JavaVersion must not be null!");
|
||||
|
||||
this.project = project;
|
||||
this.version = Version.parse(version);
|
||||
this.customFirstIteration = customFirstIteration == null ? null
|
||||
: new Iteration(customFirstIteration, Iteration.RC1);
|
||||
this.javaVersion = javaVersion;
|
||||
}
|
||||
|
||||
public boolean hasName(String name) {
|
||||
@@ -97,8 +90,4 @@ public class Module implements VersionAware, ProjectAware, JavaVersionAware, Com
|
||||
return String.format("Spring Data %s %s - %s", project.getName(), version, project.getKey());
|
||||
}
|
||||
|
||||
public Module withJavaVersion(JavaVersion javaVersion) {
|
||||
return this.javaVersion == javaVersion ? this
|
||||
: new Module(this.project, this.version, this.customFirstIteration, javaVersion);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import lombok.RequiredArgsConstructor;
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class ModuleIteration implements IterationVersion, ProjectAware, JavaVersionAware {
|
||||
public class ModuleIteration implements IterationVersion, ProjectAware {
|
||||
|
||||
private final @Getter Module module;
|
||||
private final @Getter TrainIteration trainIteration;
|
||||
@@ -46,11 +46,6 @@ public class ModuleIteration implements IterationVersion, ProjectAware, JavaVers
|
||||
return module.getProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaVersion getJavaVersion() {
|
||||
return trainIteration.getTrain().getJavaVersion();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.release.model.IterationVersion#getVersion()
|
||||
|
||||
@@ -77,7 +77,6 @@ public class ReleaseTrains {
|
||||
TURING = PASCAL.next("Turing", Transition.MAJOR, //
|
||||
new Module(R2DBC, "3.0")) //
|
||||
.withCalver("2022.0") //
|
||||
.withJavaVersion(JavaVersion.JAVA_17)
|
||||
.filterModules(module -> !module.getProject().equals(ENVERS))
|
||||
.withAlwaysUseBranch(true)
|
||||
.withIterations(new Train.Iterations(M1, M2, M3, M4, M5, RC1, RC2, GA, SR1, SR2, SR3, SR4, SR5));
|
||||
|
||||
@@ -185,15 +185,6 @@ public class Train implements Streamable<Module> {
|
||||
return new Train(name, Modules.of(modules), calver, iterations, alwaysUseBranch, javaVersion);
|
||||
}
|
||||
|
||||
public Train withJavaVersion(JavaVersion javaVersion) {
|
||||
|
||||
Set<Module> modules = this.modules.stream().map(it -> {
|
||||
return it.withJavaVersion(javaVersion);
|
||||
}).collect(Collectors.toSet());
|
||||
|
||||
return new Train(name, Modules.of(modules), calver, iterations, alwaysUseBranch, javaVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this train comes before {@link Train other}.
|
||||
*
|
||||
|
||||
@@ -37,4 +37,5 @@ class JavaRuntimesUnitTests {
|
||||
assertThat(jdk).isNotNull();
|
||||
assertThat(System.getProperty("java.home")).contains(jdk.getHome().getPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.release.model;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link JavaVersion}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class JavaVersionUnitTests {
|
||||
|
||||
@Test
|
||||
void shouldParseDockerTag() {
|
||||
|
||||
assertThat(JavaVersion.fromDockerTag("8u312-b07-jdk").getName()).isEqualTo("Java 1.8.0_312");
|
||||
assertThat(JavaVersion.fromDockerTag("8u322-b06-jre-focal").getName()).isEqualTo("Java 1.8.0_322");
|
||||
assertThat(JavaVersion.fromDockerTag("11.0.13_8-jdk").getName()).isEqualTo("Java 11.0.13");
|
||||
assertThat(JavaVersion.fromDockerTag("17.0.1_12").getName()).isEqualTo("Java 17.0.1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldConsiderImplementor() {
|
||||
|
||||
assertThat(JavaVersion.fromDockerTag("8u312-b07-jdk").withImplementor("Temurin").getName())
|
||||
.isEqualTo("Java 1.8.0_312 (Temurin)");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user