Skip to content

Commit

Permalink
Revert "Select Java17 builder image for native when project build wit…
Browse files Browse the repository at this point in the history
…h Java 17"

This reverts commit e2771de and makes
the use of java17-based builder-images the default without taking into
account the JVM version used to build the project.

The motivation for this change is that the builder-image compiles
bytecode to binary files and in theory a Java17-based builder-image
should be able to compile Java bytecode generated by a Java11 compiler
and produce a native executable that behaves the same as a native
executable generated by a Java11-based builder-image.

A key difference between a native executable generated by a Java11-based
builder-image and a native executable generated by a Java17-based
builder-image is that they include (embedded in the native executable)
different implementations of the JDK standard libraries. In theory this
should not be an issue, given that Java is backwards compatible and the
Java11 APIs of the standard libraries should still be implemented and
respected in Java17.

This change will allow us to test this hypothesis in practice as well :)
If things work as expected then we can drop Java11-based builder-images
and only generate/maintain Java17-based ones.
  • Loading branch information
zakkak committed Jun 23, 2022
1 parent 99b8b41 commit 7999502
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 57 deletions.
Expand Up @@ -16,10 +16,8 @@
@ConfigRoot(phase = ConfigPhase.BUILD_TIME)
public class NativeConfig {

public static final String GRAALVM_BUILDER_IMAGE_JAVA_11 = "quay.io/quarkus/ubi-quarkus-native-image:22.1-java11";
public static final String GRAALVM_BUILDER_IMAGE_JAVA_17 = "quay.io/quarkus/ubi-quarkus-native-image:22.1-java17";
public static final String MANDREL_BUILDER_IMAGE_JAVA_11 = "quay.io/quarkus/ubi-quarkus-mandrel:22.1-java11";
public static final String MANDREL_BUILDER_IMAGE_JAVA_17 = "quay.io/quarkus/ubi-quarkus-mandrel:22.1-java17";
public static final String DEFAULT_GRAALVM_BUILDER_IMAGE = "quay.io/quarkus/ubi-quarkus-native-image:22.1-java17";
public static final String DEFAULT_MANDREL_BUILDER_IMAGE = "quay.io/quarkus/ubi-quarkus-mandrel:22.1-java17";

/**
* Comma-separated, additional arguments to pass to the build process.
Expand Down Expand Up @@ -215,12 +213,12 @@ public boolean isContainerBuild() {
@ConfigItem(defaultValue = "${platform.quarkus.native.builder-image}")
public String builderImage;

public String getEffectiveBuilderImage(boolean useJava17Images) {
public String getEffectiveBuilderImage() {
final String builderImageName = this.builderImage.toUpperCase();
if (builderImageName.equals(BuilderImageProvider.GRAALVM.name())) {
return useJava17Images ? GRAALVM_BUILDER_IMAGE_JAVA_17 : GRAALVM_BUILDER_IMAGE_JAVA_11;
return DEFAULT_GRAALVM_BUILDER_IMAGE;
} else if (builderImageName.equals(BuilderImageProvider.MANDREL.name())) {
return useJava17Images ? MANDREL_BUILDER_IMAGE_JAVA_17 : MANDREL_BUILDER_IMAGE_JAVA_11;
return DEFAULT_MANDREL_BUILDER_IMAGE;
} else {
return this.builderImage;
}
Expand Down
Expand Up @@ -40,8 +40,6 @@ enum Status {

final class Unknown implements JavaVersion {

public static final Unknown INSTANCE = new Unknown();

Unknown() {
}

Expand Down
Expand Up @@ -14,7 +14,6 @@
import org.jboss.logging.Logger;

import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;
import io.quarkus.deployment.util.ProcessUtil;
import io.quarkus.runtime.util.ContainerRuntimeUtil;

Expand All @@ -27,10 +26,8 @@ public abstract class NativeImageBuildContainerRunner extends NativeImageBuildRu
String[] baseContainerRuntimeArgs;
protected final String outputPath;
private final String containerName;
private final boolean needJava17Image;

public NativeImageBuildContainerRunner(NativeConfig nativeConfig, Path outputDir,
CompiledJavaVersionBuildItem.JavaVersion javaVersion) {
public NativeImageBuildContainerRunner(NativeConfig nativeConfig, Path outputDir) {
this.nativeConfig = nativeConfig;
containerRuntime = nativeConfig.containerRuntime.orElseGet(ContainerRuntimeUtil::detectContainerRuntime);
log.infof("Using %s to run the native image builder", containerRuntime.getExecutableName());
Expand All @@ -39,7 +36,6 @@ public NativeImageBuildContainerRunner(NativeConfig nativeConfig, Path outputDir

outputPath = outputDir == null ? null : outputDir.toAbsolutePath().toString();
containerName = "build-native-" + RandomStringUtils.random(5, true, false);
this.needJava17Image = javaVersion.isExactlyJava11() == CompiledJavaVersionBuildItem.JavaVersion.Status.FALSE;
}

@Override
Expand All @@ -49,7 +45,7 @@ public void setup(boolean processInheritIODisabled) {
// we pull the docker image in order to give users an indication of which step the process is at
// it's not strictly necessary we do this, however if we don't the subsequent version command
// will appear to block and no output will be shown
String effectiveBuilderImage = nativeConfig.getEffectiveBuilderImage(needJava17Image);
String effectiveBuilderImage = nativeConfig.getEffectiveBuilderImage();
log.info("Checking image status " + effectiveBuilderImage);
Process pullProcess = null;
try {
Expand Down Expand Up @@ -125,8 +121,7 @@ protected List<String> getContainerRuntimeBuildArgs() {
protected String[] buildCommand(String dockerCmd, List<String> containerRuntimeArgs, List<String> command) {
return Stream
.of(Stream.of(containerRuntime.getExecutableName()), Stream.of(dockerCmd), Stream.of(baseContainerRuntimeArgs),
containerRuntimeArgs.stream(), Stream.of(nativeConfig.getEffectiveBuilderImage(needJava17Image)),
command.stream())
containerRuntimeArgs.stream(), Stream.of(nativeConfig.getEffectiveBuilderImage()), command.stream())
.flatMap(Function.identity()).toArray(String[]::new);
}

Expand Down
Expand Up @@ -11,15 +11,13 @@
import org.apache.commons.lang3.SystemUtils;

import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;
import io.quarkus.deployment.util.FileUtil;
import io.quarkus.runtime.util.ContainerRuntimeUtil;

public class NativeImageBuildLocalContainerRunner extends NativeImageBuildContainerRunner {

public NativeImageBuildLocalContainerRunner(NativeConfig nativeConfig, Path outputDir,
CompiledJavaVersionBuildItem.JavaVersion javaVersion) {
super(nativeConfig, outputDir, javaVersion);
public NativeImageBuildLocalContainerRunner(NativeConfig nativeConfig, Path outputDir) {
super(nativeConfig, outputDir);
if (SystemUtils.IS_OS_LINUX) {
ArrayList<String> containerRuntimeArgs = new ArrayList<>(Arrays.asList(baseContainerRuntimeArgs));
String uid = getLinuxID("-ur");
Expand Down
Expand Up @@ -11,7 +11,6 @@
import org.jboss.logging.Logger;

import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;

public class NativeImageBuildRemoteContainerRunner extends NativeImageBuildContainerRunner {

Expand All @@ -26,9 +25,8 @@ public class NativeImageBuildRemoteContainerRunner extends NativeImageBuildConta
private String containerId;

public NativeImageBuildRemoteContainerRunner(NativeConfig nativeConfig, Path outputDir,
CompiledJavaVersionBuildItem.JavaVersion javaVersion,
String nativeImageName, String resultingExecutableName) {
super(nativeConfig, outputDir, javaVersion);
super(nativeConfig, outputDir);
this.nativeImageName = nativeImageName;
this.resultingExecutableName = resultingExecutableName;
}
Expand Down
Expand Up @@ -38,7 +38,6 @@
import io.quarkus.deployment.pkg.PackageConfig;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.BuildSystemTargetBuildItem;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;
import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageSourceJarBuildItem;
Expand Down Expand Up @@ -177,7 +176,6 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon
List<JPMSExportBuildItem> jpmsExportBuildItems,
List<NativeMinimalJavaVersionBuildItem> nativeMinimalJavaVersions,
List<UnsupportedOSBuildItem> unsupportedOses,
CompiledJavaVersionBuildItem compiledJavaVersionBuildItem,
Optional<ProcessInheritIODisabled> processInheritIODisabled,
Optional<ProcessInheritIODisabledBuildItem> processInheritIODisabledBuildItem,
List<NativeImageFeatureBuildItem> nativeImageFeatures) {
Expand Down Expand Up @@ -205,7 +203,6 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, LocalesBuildTimeCon
Path finalExecutablePath = outputTargetBuildItem.getOutputDirectory().resolve(resultingExecutableName);

NativeImageBuildRunner buildRunner = getNativeImageBuildRunner(nativeConfig, outputDir,
compiledJavaVersionBuildItem.getJavaVersion(),
nativeImageName, resultingExecutableName);
buildRunner.setup(processInheritIODisabled.isPresent() || processInheritIODisabledBuildItem.isPresent());
final GraalVM.Version graalVMVersion = buildRunner.getGraalVMVersion();
Expand Down Expand Up @@ -306,7 +303,6 @@ private String getResultingExecutableName(String nativeImageName, boolean isCont
}

private static NativeImageBuildRunner getNativeImageBuildRunner(NativeConfig nativeConfig, Path outputDir,
CompiledJavaVersionBuildItem.JavaVersion javaVersion,
String nativeImageName, String resultingExecutableName) {
if (!nativeConfig.isContainerBuild()) {
NativeImageBuildLocalRunner localRunner = getNativeImageBuildLocalRunner(nativeConfig, outputDir.toFile());
Expand All @@ -322,10 +318,10 @@ private static NativeImageBuildRunner getNativeImageBuildRunner(NativeConfig nat
log.warn(errorMessage + " Attempting to fall back to container build.");
}
if (nativeConfig.remoteContainerBuild) {
return new NativeImageBuildRemoteContainerRunner(nativeConfig, outputDir, javaVersion,
return new NativeImageBuildRemoteContainerRunner(nativeConfig, outputDir,
nativeImageName, resultingExecutableName);
}
return new NativeImageBuildLocalContainerRunner(nativeConfig, outputDir, javaVersion);
return new NativeImageBuildLocalContainerRunner(nativeConfig, outputDir);
}

private void copyJarSourcesToLib(OutputTargetBuildItem outputTargetBuildItem,
Expand Down
Expand Up @@ -18,7 +18,6 @@
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;
import io.quarkus.deployment.pkg.builditem.NativeImageBuildItem;
import io.quarkus.deployment.pkg.builditem.UpxCompressedBuildItem;
import io.quarkus.deployment.util.FileUtil;
Expand All @@ -36,17 +35,14 @@ public class UpxCompressionBuildStep {

@BuildStep(onlyIf = NativeBuild.class)
public void compress(NativeConfig nativeConfig, NativeImageBuildItem image,
CompiledJavaVersionBuildItem compiledJavaVersionBuildItem,
BuildProducer<UpxCompressedBuildItem> upxCompressedProducer,
BuildProducer<ArtifactResultBuildItem> artifactResultProducer) {
if (nativeConfig.compression.level.isEmpty()) {
log.debug("UPX compression disabled");
return;
}

String effectiveBuilderImage = nativeConfig.getEffectiveBuilderImage(
compiledJavaVersionBuildItem.getJavaVersion()
.isExactlyJava11() == CompiledJavaVersionBuildItem.JavaVersion.Status.FALSE);
String effectiveBuilderImage = nativeConfig.getEffectiveBuilderImage();
Optional<File> upxPathFromSystem = getUpxFromSystem();
if (upxPathFromSystem.isPresent()) {
log.debug("Running UPX from system path");
Expand Down
Expand Up @@ -8,27 +8,20 @@ class NativeConfigTest {

@Test
public void testBuilderImageProperlyDetected() {
assertThat(createConfig("graalvm").getEffectiveBuilderImage(false)).contains("ubi-quarkus-native-image")
.contains("java11");
assertThat(createConfig("graalvm").getEffectiveBuilderImage(true)).contains("ubi-quarkus-native-image")
assertThat(createConfig("graalvm").getEffectiveBuilderImage()).contains("ubi-quarkus-native-image")
.contains("java17");
assertThat(createConfig("GraalVM").getEffectiveBuilderImage(true)).contains("ubi-quarkus-native-image")
assertThat(createConfig("GraalVM").getEffectiveBuilderImage()).contains("ubi-quarkus-native-image")
.contains("java17");
assertThat(createConfig("GraalVM").getEffectiveBuilderImage(true)).contains("ubi-quarkus-native-image")
assertThat(createConfig("GraalVM").getEffectiveBuilderImage()).contains("ubi-quarkus-native-image")
.contains("java17");
assertThat(createConfig("GRAALVM").getEffectiveBuilderImage(false)).contains("ubi-quarkus-native-image")
.contains("java11");
assertThat(createConfig("GRAALVM").getEffectiveBuilderImage(true)).contains("ubi-quarkus-native-image")
assertThat(createConfig("GRAALVM").getEffectiveBuilderImage()).contains("ubi-quarkus-native-image")
.contains("java17");

assertThat(createConfig("mandrel").getEffectiveBuilderImage(false)).contains("ubi-quarkus-mandrel").contains("java11");
assertThat(createConfig("mandrel").getEffectiveBuilderImage(true)).contains("ubi-quarkus-mandrel").contains("java17");
assertThat(createConfig("Mandrel").getEffectiveBuilderImage(false)).contains("ubi-quarkus-mandrel").contains("java11");
assertThat(createConfig("Mandrel").getEffectiveBuilderImage(true)).contains("ubi-quarkus-mandrel").contains("java17");
assertThat(createConfig("MANDREL").getEffectiveBuilderImage(false)).contains("ubi-quarkus-mandrel").contains("java11");
assertThat(createConfig("MANDREL").getEffectiveBuilderImage(true)).contains("ubi-quarkus-mandrel").contains("java17");
assertThat(createConfig("mandrel").getEffectiveBuilderImage()).contains("ubi-quarkus-mandrel").contains("java17");
assertThat(createConfig("Mandrel").getEffectiveBuilderImage()).contains("ubi-quarkus-mandrel").contains("java17");
assertThat(createConfig("MANDREL").getEffectiveBuilderImage()).contains("ubi-quarkus-mandrel").contains("java17");

assertThat(createConfig("aRandomString").getEffectiveBuilderImage(false)).isEqualTo("aRandomString");
assertThat(createConfig("aRandomString").getEffectiveBuilderImage()).isEqualTo("aRandomString");
}

private NativeConfig createConfig(String configValue) {
Expand Down
Expand Up @@ -10,7 +10,6 @@
import org.junit.jupiter.api.condition.DisabledIfSystemProperty;

import io.quarkus.deployment.pkg.NativeConfig;
import io.quarkus.deployment.pkg.builditem.CompiledJavaVersionBuildItem;

class NativeImageBuildContainerRunnerTest {

Expand All @@ -25,8 +24,7 @@ void testBuilderImageBeingPickedUp() {
String[] command;

nativeConfig.builderImage = "graalvm";
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"),
CompiledJavaVersionBuildItem.JavaVersion.Unknown.INSTANCE);
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
found = false;
for (String part : command) {
Expand All @@ -37,8 +35,7 @@ void testBuilderImageBeingPickedUp() {
assertThat(found).isTrue();

nativeConfig.builderImage = "mandrel";
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"),
CompiledJavaVersionBuildItem.JavaVersion.Unknown.INSTANCE);
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
found = false;
for (String part : command) {
Expand All @@ -49,8 +46,7 @@ void testBuilderImageBeingPickedUp() {
assertThat(found).isTrue();

nativeConfig.builderImage = "RandomString";
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"),
CompiledJavaVersionBuildItem.JavaVersion.Unknown.INSTANCE);
localRunner = new NativeImageBuildLocalContainerRunner(nativeConfig, Path.of("/tmp"));
command = localRunner.buildCommand("docker", Collections.emptyList(), Collections.emptyList());
found = false;
for (String part : command) {
Expand Down

0 comments on commit 7999502

Please sign in to comment.