8379431: [macos] jpackage issues unexpected warning when bundling an unsigned runtime package from the signed predefined runtime bundle

Reviewed-by: almatvee
This commit is contained in:
Alexey Semenyuk 2026-03-20 03:01:03 +00:00
parent 3c09c2cd2d
commit b79449f093
5 changed files with 62 additions and 23 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -65,7 +65,7 @@ final class MacPackageBuilder {
}
private static void validatePredefinedAppImage(MacPackage pkg) {
if (pkg.predefinedAppImageSigned().orElse(false)) {
if (pkg.predefinedAppImageSigned().orElse(false) && !pkg.isRuntimeInstaller()) {
pkg.predefinedAppImage().ifPresent(predefinedAppImage -> {
var thePackageFile = PackageFile.getPathInAppImage(APPLICATION_LAYOUT);
if (!Files.exists(predefinedAppImage.resolve(thePackageFile))) {

View File

@ -43,7 +43,7 @@ public final class JPackageOutputValidator {
}
public JPackageOutputValidator(JPackageOutputValidator other) {
stdout = other.stdout;
stream = other.stream;
match = other.match;
matchTimestamps = other.matchTimestamps;
stripTimestamps = other.stripTimestamps;
@ -59,7 +59,7 @@ public final class JPackageOutputValidator {
* @return this
*/
public JPackageOutputValidator stdout() {
stdout = true;
stream = StdStream.OUT;
return this;
}
@ -68,7 +68,16 @@ public final class JPackageOutputValidator {
* @return this
*/
public JPackageOutputValidator stderr() {
stdout = false;
stream = StdStream.ERR;
return this;
}
/**
* Configures this validator to validate both stdout and stderr.
* @return this
*/
public JPackageOutputValidator stdoutAndStderr() {
stream = StdStream.OUT_AND_ERR;
return this;
}
@ -171,7 +180,7 @@ public final class JPackageOutputValidator {
}
public JPackageOutputValidator compose(JPackageOutputValidator other) {
if (stdout != other.stdout) {
if (stream != other.stream) {
throw new IllegalArgumentException();
}
if (match != other.match) {
@ -188,7 +197,7 @@ public final class JPackageOutputValidator {
private Optional<Consumer<Executor.Result>> toResultConsumer(JPackageCommand cmd) {
return toStringIteratorConsumer(cmd).map(validator -> {
return toResultConsumer(validator, stdout, match, label());
return toResultConsumer(validator, stream, match, label());
});
}
@ -244,7 +253,11 @@ public final class JPackageOutputValidator {
}
private String label() {
return stdout ? "'stdout'" : "'stderr'";
return switch (stream) {
case OUT -> "'stdout'";
case ERR -> "'stderr'";
case OUT_AND_ERR -> "'stdout+stderr'";
};
}
private Consumer<Iterator<String>> decorate(TKit.TextStreamVerifier validator) {
@ -256,17 +269,16 @@ public final class JPackageOutputValidator {
}
private static Consumer<Executor.Result> toResultConsumer(
Consumer<Iterator<String>> validator, boolean stdout, boolean match, String label) {
Consumer<Iterator<String>> validator, StdStream stream, boolean match, String label) {
Objects.requireNonNull(validator);
Objects.requireNonNull(label);
return result -> {
List<String> content;
if (stdout) {
content = result.stdout();
} else {
content = result.stderr();
}
List<String> content = switch (stream) {
case OUT -> result.stdout();
case ERR -> result.stderr();
case OUT_AND_ERR -> result.getOutput();
};
if (match) {
TKit.trace(String.format("Checking %s for exact match against defined validators...", label));
@ -371,7 +383,14 @@ public final class JPackageOutputValidator {
}
}
boolean stdout = true;
private enum StdStream {
OUT,
ERR,
OUT_AND_ERR,
;
}
StdStream stream = StdStream.OUT;
boolean match;
boolean matchTimestamps;
boolean stripTimestamps;

View File

@ -78,6 +78,10 @@ public enum JPackageStringBundle {
});
}
public Pattern cannedFormattedStringAsPattern(String key, Object ... args) {
return cannedFormattedStringAsPattern(key, MATCH_ANY, args);
}
static Pattern toPattern(MessageFormat mf, Function<Object, Pattern> formatArgMapper, Object ... args) {
Objects.requireNonNull(mf);
Objects.requireNonNull(formatArgMapper);
@ -154,4 +158,14 @@ public enum JPackageStringBundle {
private final Class<?> i18nClass;
private final Method i18nClass_getString;
private final BiFunction<String, Object[], String> formatter;
private static final Function<Object, Pattern> MATCH_ANY = new Function<>() {
@Override
public Pattern apply(Object v) {
return PATTERN;
}
private static final Pattern PATTERN = Pattern.compile(".*");
};
}

View File

@ -37,6 +37,8 @@ import jdk.jpackage.internal.util.Slot;
import jdk.jpackage.test.Annotations.ParameterSupplier;
import jdk.jpackage.test.Annotations.Test;
import jdk.jpackage.test.JPackageCommand;
import jdk.jpackage.test.JPackageOutputValidator;
import jdk.jpackage.test.JPackageStringBundle;
import jdk.jpackage.test.MacHelper;
import jdk.jpackage.test.MacHelper.ResolvableCertificateRequest;
import jdk.jpackage.test.MacHelper.SignKeyOption;
@ -98,6 +100,13 @@ public class SigningRuntimeImagePackageTest {
cmd.ignoreDefaultRuntime(true);
cmd.removeArgumentWithValue("--input");
cmd.setArgumentValue("--runtime-image", predefinedRuntime.get());
// `warning.per.user.app.image.signed` warning doesn't apply to runtime bundling.
// Ensure the warning is not in the output.
new JPackageOutputValidator().add(TKit.assertTextStream(
JPackageStringBundle.MAIN.cannedFormattedStringAsPattern("warning.per.user.app.image.signed", "file")
).negate()).stdoutAndStderr().applyTo(cmd);
}).addInstallVerifier(cmd -> {
MacSignVerify.verifyAppImageSigned(cmd, signRuntime.certRequest());
}).run();

View File

@ -46,7 +46,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import jdk.internal.util.OperatingSystem;
import jdk.jpackage.internal.util.MacBundle;
@ -287,9 +286,7 @@ public final class AppVersionTest {
}
TKit.TextStreamVerifier negateFind() {
var pattern = JPackageStringBundle.MAIN.cannedFormattedStringAsPattern(key, _ -> {
return Pattern.compile(".*");
}, args);
var pattern = JPackageStringBundle.MAIN.cannedFormattedStringAsPattern(key, args);
return TKit.assertTextStream(pattern).negate();
}
@ -400,7 +397,7 @@ public final class AppVersionTest {
Stream.of(Message.values()).filter(message -> {
return !expectMessageKeys.contains(message.key());
}).map(Message::negateFind).forEach(validator -> {
new JPackageOutputValidator().add(validator).applyTo(cmd);
new JPackageOutputValidator().add(validator).stdoutAndStderr().applyTo(cmd);
});
}
@ -760,7 +757,7 @@ public final class AppVersionTest {
private final List<VersionSource> versions = new ArrayList<>();
private final Map<PackageType, Expected> expected = new HashMap<>();
private final static Set<PackageType> ALL_TYPES = Set.of(PackageType.values());
private static final Set<PackageType> ALL_TYPES = Set.of(PackageType.values());
}
}
@ -1019,7 +1016,7 @@ public final class AppVersionTest {
return predefinedRuntimeDir;
}
final static String MAC_PREDEFINED_RUNTIME_BUNDLE_VERSION = "1.22.333";
static final String MAC_PREDEFINED_RUNTIME_BUNDLE_VERSION = "1.22.333";
}
private static Consumer<TestSpec> skipImagePackageType(Consumer<TestSpec> consumer) {