Skip to content

Commit 9ea8201

Browse files
author
Alexander Matveev
committed
8363980: [macos] Add JDK specific keys/values to Info.plist of embedded runtime
Reviewed-by: asemenyuk
1 parent 3949b0f commit 9ea8201

File tree

8 files changed

+80
-21
lines changed

8 files changed

+80
-21
lines changed

src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPackagingPipeline.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,25 +364,40 @@ private static void writeRuntimeInfoPlist(
364364

365365
final var app = env.app();
366366

367+
// If the embedded runtime contains executable(s) in the "bin"
368+
// subdirectory, we should use the standalone runtime info plist
369+
// template. Otherwise, the user may be unable to run the "java"
370+
// or other executables in the "bin" subdirectory of the embedded
371+
// runtime.
372+
final var useRuntimeInfoPlist = app.isRuntime() ||
373+
app.runtimeBuilder().orElseThrow().withNativeCommands() ||
374+
Files.isDirectory(env.resolvedLayout().runtimeDirectory().resolve("bin"));
375+
367376
Map<String, String> data = new HashMap<>();
368377
data.put("CF_BUNDLE_IDENTIFIER", app.bundleIdentifier());
369378
data.put("CF_BUNDLE_NAME", app.bundleName());
370379
data.put("CF_BUNDLE_VERSION", app.version());
371380
data.put("CF_BUNDLE_SHORT_VERSION_STRING", app.shortVersion().toString());
372-
if (app.isRuntime()) {
381+
if (useRuntimeInfoPlist) {
373382
data.put("CF_BUNDLE_VENDOR", app.vendor());
374383
}
375384

376385
final String template;
377386
final String publicName;
378387
final String category;
379388

380-
if (app.isRuntime()) {
389+
if (useRuntimeInfoPlist) {
381390
template = "Runtime-Info.plist.template";
391+
} else {
392+
template = "ApplicationRuntime-Info.plist.template";
393+
}
394+
395+
// Public name and category should be based on standalone runtime vs
396+
// embedded runtime.
397+
if (app.isRuntime()) {
382398
publicName = "Info.plist";
383399
category = "resource.runtime-info-plist";
384400
} else {
385-
template = "ApplicationRuntime-Info.plist.template";
386401
publicName = "Runtime-Info.plist";
387402
category = "resource.app-runtime-info-plist";
388403
}

src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkRuntimeBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ public void create(AppImageLayout appImageLayout) throws PackagerException {
8383
}
8484
}
8585

86+
@Override
87+
public boolean withNativeCommands() {
88+
return !jlinkCmdLine.contains("--strip-native-commands");
89+
}
90+
8691
static ModuleFinder createModuleFinder(Collection<Path> modulePath) {
8792
return ModuleFinder.compose(
8893
ModulePath.of(JarFile.runtimeVersion(), true,

src/jdk.jpackage/share/classes/jdk/jpackage/internal/model/RuntimeBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@ public interface RuntimeBuilder {
4646
*/
4747
void create(AppImageLayout appImageLayout) throws PackagerException;
4848

49+
/**
50+
* Returns {@code true} if "--strip-native-commands" was not used with jlink.
51+
* Default implementation returns {@code false}.
52+
*
53+
* @return {@code true} if "--strip-native-commands" was not used with jlink
54+
*/
55+
default boolean withNativeCommands() {
56+
return false;
57+
}
58+
4959
/**
5060
* Gets the default set of paths where jlink should look up for system Java
5161
* modules.

test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,24 +306,16 @@ public JPackageCommand setFakeRuntime() {
306306
TKit.trace(String.format("Init fake runtime in [%s] directory",
307307
fakeRuntimeDir));
308308

309-
Files.createDirectories(fakeRuntimeDir);
310-
311-
if (TKit.isLinux()) {
312-
// Need to make the code in rpm spec happy as it assumes there is
313-
// always something in application image.
314-
fakeRuntimeDir.resolve("bin").toFile().mkdir();
315-
}
316-
317309
if (TKit.isOSX()) {
318310
// Make MacAppImageBuilder happy
319311
createBulkFile.accept(fakeRuntimeDir.resolve(Path.of(
320312
"lib/jli/libjli.dylib")));
321313
}
322314

323-
// Mak sure fake runtime takes some disk space.
315+
// Make sure fake runtime takes some disk space.
324316
// Package bundles with 0KB size are unexpected and considered
325317
// an error by PackageTest.
326-
createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk")));
318+
createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("lib", "bulk")));
327319

328320
cmd.setArgumentValue("--runtime-image", fakeRuntimeDir);
329321
});
@@ -1227,6 +1219,24 @@ public static enum StandardAssert {
12271219
MacHelper.verifyUnsignedBundleSignature(cmd);
12281220
}
12291221
}),
1222+
MAC_RUNTIME_PLIST_JDK_KEY(cmd -> {
1223+
if (TKit.isOSX()) {
1224+
var appLayout = cmd.appLayout();
1225+
var plistPath = appLayout.runtimeDirectory().resolve("Contents/Info.plist");
1226+
var keyName = "JavaVM";
1227+
var keyValue = MacHelper.readPList(plistPath).findDictValue(keyName);
1228+
if (cmd.isRuntime() || Files.isDirectory(appLayout.runtimeHomeDirectory().resolve("bin"))) {
1229+
// There are native launchers in the runtime
1230+
TKit.assertTrue(keyValue.isPresent(), String.format(
1231+
"Check the runtime plist file [%s] contains '%s' key",
1232+
plistPath, keyName));
1233+
} else {
1234+
TKit.assertTrue(keyValue.isEmpty(), String.format(
1235+
"Check the runtime plist file [%s] contains NO '%s' key",
1236+
plistPath, keyName));
1237+
}
1238+
}
1239+
}),
12301240
PREDEFINED_APP_IMAGE_COPY(cmd -> {
12311241
Optional.ofNullable(cmd.getArgumentValue("--app-image")).filter(_ -> {
12321242
return !TKit.isOSX() || !MacHelper.signPredefinedAppImage(cmd);

test/jdk/tools/jpackage/macosx/CustomInfoPListTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static java.util.Map.entry;
2626
import jdk.jpackage.internal.util.Slot;
2727
import static jdk.jpackage.internal.util.PListWriter.writeDict;
28+
import static jdk.jpackage.internal.util.PListWriter.writeKey;
2829
import static jdk.jpackage.internal.util.PListWriter.writePList;
2930
import static jdk.jpackage.internal.util.PListWriter.writeString;
3031
import static jdk.jpackage.internal.util.XmlUtils.createXml;
@@ -431,6 +432,10 @@ void writeRuntimePlist(JPackageCommand cmd, XMLStreamWriter xml) throws XMLStrea
431432
writeString(xml, "CFBundleShortVersionString", value("CF_BUNDLE_SHORT_VERSION_STRING", cmd.version()));
432433
writeString(xml, "CFBundleVersion", value("CF_BUNDLE_VERSION", cmd.version()));
433434
writeString(xml, "CustomInfoPListFA", "DEPLOY_FILE_ASSOCIATIONS");
435+
writeKey(xml, "JavaVM");
436+
writeDict(xml, toXmlConsumer(() -> {
437+
writeString(xml, "JVMVersion", value("CF_BUNDLE_VERSION", cmd.version()));
438+
}));
434439
}));
435440
}));
436441
}

test/jdk/tools/jpackage/share/AppImagePackageTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public static void testEmpty(boolean withIcon) throws IOException {
120120
StandardAssert.MAIN_JAR_FILE,
121121
StandardAssert.MAIN_LAUNCHER_FILES,
122122
StandardAssert.MAC_BUNDLE_STRUCTURE,
123-
StandardAssert.RUNTIME_DIRECTORY);
123+
StandardAssert.RUNTIME_DIRECTORY,
124+
StandardAssert.MAC_RUNTIME_PLIST_JDK_KEY);
124125
})
125126
.run(Action.CREATE_AND_UNPACK);
126127
}

test/jdk/tools/jpackage/share/CookedRuntimeTest.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@
5151
public final class CookedRuntimeTest {
5252

5353
public CookedRuntimeTest(String javaAppDesc, String jlinkOutputSubdir,
54-
String runtimeSubdir) {
54+
String runtimeSubdir, boolean withNativeCommands) {
5555
this.javaAppDesc = javaAppDesc;
5656
this.jlinkOutputSubdir = Path.of(jlinkOutputSubdir);
5757
this.runtimeSubdir = Path.of(runtimeSubdir);
58+
this.withNativeCommands = withNativeCommands;
5859
}
5960

6061
@Test
@@ -90,6 +91,10 @@ public void test() throws IOException {
9091
"--no-header-files",
9192
"--no-man-pages");
9293

94+
if (!withNativeCommands) {
95+
jlink.addArgument("--strip-native-commands");
96+
}
97+
9398
if (moduleName != null) {
9499
jlink.addArguments("--add-modules", moduleName, "--module-path",
95100
Path.of(cmd.getArgumentValue("--module-path")).resolve(
@@ -127,7 +132,14 @@ public static Collection<?> data() {
127132
List<Object[]> data = new ArrayList<>();
128133
for (var javaAppDesc : javaAppDescs) {
129134
for (var pathCfg : paths) {
130-
data.add(new Object[] { javaAppDesc, pathCfg[0], pathCfg[1] });
135+
if (TKit.isOSX()) {
136+
// On OSX platform we need to test both runtime root and runtime home
137+
// directories with and without "bin" folder.
138+
data.add(new Object[] { javaAppDesc, pathCfg[0], pathCfg[1], true });
139+
data.add(new Object[] { javaAppDesc, pathCfg[0], pathCfg[1], false });
140+
} else {
141+
data.add(new Object[] { javaAppDesc, pathCfg[0], pathCfg[1], true });
142+
}
131143
}
132144
}
133145

@@ -137,4 +149,5 @@ public static Collection<?> data() {
137149
private final String javaAppDesc;
138150
private final Path jlinkOutputSubdir;
139151
private final Path runtimeSubdir;
152+
private final boolean withNativeCommands;
140153
}

test/jdk/tools/jpackage/share/PostImageScriptTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,24 +140,24 @@ PackageTest initTest(PackageTest test) {
140140
runtimeDir = Path.of("");
141141
}
142142

143-
final Path runtimeBinDir = runtimeDir.resolve("bin");
143+
final Path runtimeLibDir = runtimeDir.resolve("lib");
144144

145145
if (TKit.isWindows()) {
146146
final List<String> script = new ArrayList<>();
147147
script.addAll(WinGlobals.JS_SHELL.expr());
148148
script.addAll(WinGlobals.JS_FS.expr());
149149
script.addAll(List.of(
150150
"WScript.Echo('PWD: ' + fs.GetFolder(shell.CurrentDirectory).Path)",
151-
String.format("WScript.Echo('Probe directory: %s')", runtimeBinDir),
152-
String.format("fs.GetFolder('%s')", runtimeBinDir.toString().replace('\\', '/'))
151+
String.format("WScript.Echo('Probe directory: %s')", runtimeLibDir),
152+
String.format("fs.GetFolder('%s')", runtimeLibDir.toString().replace('\\', '/'))
153153
));
154154
JPackageUserScript.POST_IMAGE.create(cmd, script);
155155
} else {
156156
JPackageUserScript.POST_IMAGE.create(cmd, List.of(
157157
"set -e",
158158
"printf 'PWD: %s\\n' \"$PWD\"",
159-
String.format("printf 'Probe directory: %%s\\n' '%s'", runtimeBinDir),
160-
String.format("[ -d '%s' ]", runtimeBinDir)
159+
String.format("printf 'Probe directory: %%s\\n' '%s'", runtimeLibDir),
160+
String.format("[ -d '%s' ]", runtimeLibDir)
161161
));
162162
}
163163
});

0 commit comments

Comments
 (0)