Skip to content

Conversation

@sashamatveev
Copy link
Member

@sashamatveev sashamatveev commented Oct 29, 2025

  • Added JDK specific keys/values to Info.plist of embedded runtime.
  • Modified setFakeRuntime() not to include bin folder. By default it was always included, but generated embedded runtime by default does not have bin folder. As a result CustomInfoPListTest failed.
  • Updated CustomInfoPListTest to test Info.plist with bin folder.

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8363980: [macos] Add JDK specific keys/values to Info.plist of embedded runtime (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28033/head:pull/28033
$ git checkout pull/28033

Update a local copy of the PR:
$ git checkout pull/28033
$ git pull https://git.openjdk.org/jdk.git pull/28033/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28033

View PR using the GUI difftool:
$ git pr show -t 28033

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28033.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 29, 2025

👋 Welcome back almatvee! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Oct 29, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the core-libs core-libs-dev@openjdk.org label Oct 29, 2025
@openjdk
Copy link

openjdk bot commented Oct 29, 2025

@sashamatveev The following label will be automatically applied to this pull request:

  • core-libs

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 29, 2025
@sashamatveev
Copy link
Member Author

@alexeysemenyukoracle Please review.

@mlbridge
Copy link

mlbridge bot commented Oct 29, 2025

Webrevs


final var app = env.app();

// We should use full runtime info plist for standalone runtime and for

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the comment explains why jpackage should use the same info plist template for a runtime if it has the "bin" subdirectory. But what is the "full" runtime?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"full" runtime info plist -> refers to info plist from standalone runtime. I will re-write it to:

 // We should use info plist from standalone runtime for embedded runtime // if embedded runtime contains "bin" folder, so embedded runtime // can act as standalone runtime. Standalone runtime always uses same // info plist which has "JavaVM" dictionary. 
Copy link
Member

@alexeysemenyukoracle alexeysemenyukoracle Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so embedded runtime can act as standalone runtime

This can imply many things. I suggest more specific wording:

If the embedded runtime contains executable(s) in the "bin" subdirectory, we should use the standalone runtime info plist template. Otherwise, the user may be unable to run the "java" or other executables in the "bin" subdirectory of the embedded runtime.

@alexeysemenyukoracle
Copy link
Member

How do we test the defaults? We need a new test that will verify that if the runtime has a "bin" subdirectory, the runtime plist file has "standalone runtime"-specific properties and vice versa.
The test should be used with the followign runtimes:

  • A runtime with "bin" subdirectory created by jpackage.
  • A runtime without "bin" subdirectory created by jpackage.
  • A runtime with "bin" subdirectory passed to jpackage through --runtime-image.
  • A runtime without "bin" subdirectory passed to jpackage through --runtime-image.
// Need to make the code in rpm spec happy as it assumes there is
// always something in application image.
fakeRuntimeDir.resolve("bin").toFile().mkdir();
createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk")));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes the above fakeRuntimeDir.resolve("bin").toFile().mkdir(); redundant. Overall, the whole

if (TKit.isLinux()) { // Need to make the code in rpm spec happy as it assumes there is // always something in application image. fakeRuntimeDir.resolve("bin").toFile().mkdir(); } 

construction is redundant and can be replaced with:

if (includeBin) { createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk"))); } 
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need to add file to "bin" for Linux. I will change it to:

 // Need to make the code in rpm spec happy as it assumes there is // always something in application image. includeBin |= TKit.isLinux(); if (includeBin) { createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk"))); } 

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need to add file to "bin" for Linux. I will change it to:

I simplified the body of the setFakeRuntime() function as follows:

 addPrerequisiteAction(cmd -> { Path fakeRuntimeDir = TKit.createTempDirectory("fake_runtime"); TKit.trace(String.format("Init fake runtime in [%s] directory", fakeRuntimeDir)); if (TKit.isOSX()) { // Make MacAppImageBuilder happy createBulkFile.accept(fakeRuntimeDir.resolve(Path.of( "lib/jli/libjli.dylib"))); } // Make sure fake runtime takes some disk space. // Package bundles with 0KB size are unexpected and considered // an error by PackageTest. createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("lib", "bulk"))); cmd.setArgumentValue("--runtime-image", fakeRuntimeDir); }); 

And ran Windows and Linux tests that use it. All passed.

WinOSConditionTest:

[18:44:19.893] TRACE: assertStringListEquals(): Check jpackage didn't modify ${RUNTIME_IMAGE}=[C:\jpackage-tests\WinOSConditionTest\test\fake_runtime-0] [18:44:19.893] TRACE: assertStringListEquals(1, #) [18:44:19.894] TRACE: assertStringListEquals(2, lib#) [18:44:19.894] TRACE: assertStringListEquals(3, lib\bulk#2025-10-30T22:44:17.6191874Z) [18:44:19.894] TRACE: assertTrue(): Check [WinOSConditionTest\test\output\WinOSConditionTest-1.0.msi] path exists 

AppAboutUrlTest.testDefaults (DEB):

[18:49:22.115] TRACE: assertStringListEquals(): Check jpackage didn't modify ${RUNTIME_IMAGE}=[/jpackage-tests/AppAboutUrlTest/testDefaults/fake_runtime] [18:49:22.120] TRACE: assertStringListEquals(1, #) [18:49:22.120] TRACE: assertStringListEquals(2, lib#) [18:49:22.120] TRACE: assertStringListEquals(3, lib/bulk#2025-10-30T22:49:20.128409727Z) [18:49:22.120] TRACE: assertTrue(): Check [AppAboutUrlTest/testDefaults/output/defaultsappabouturltest_1.0_amd64.deb] path exists 

AppAboutUrlTest.testDefaults (RPM):

[18:56:37.897] TRACE: assertStringListEquals(): Check jpackage didn't modify ${RUNTIME_IMAGE}=[/jpackage-tests/AppAboutUrlTest/testDefaults/fake_runtime] [18:56:37.898] TRACE: assertStringListEquals(1, #) [18:56:37.898] TRACE: assertStringListEquals(2, lib#) [18:56:37.898] TRACE: assertStringListEquals(3, lib/bulk#2025-10-30T22:56:37.204554597Z) [18:56:37.898] TRACE: assertTrue(): Check [AppAboutUrlTest/testDefaults/output/defaultsappabouturltest-1.0-1.x86_64.rpm] path exists 
Copy link
Member

@alexeysemenyukoracle alexeysemenyukoracle Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff:

diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index fcd940e725e..73af859b6ac 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -307,24 +307,16 @@ public JPackageCommand setFakeRuntime() { TKit.trace(String.format("Init fake runtime in [%s] directory", fakeRuntimeDir)); - Files.createDirectories(fakeRuntimeDir); - - if (TKit.isLinux()) { - // Need to make the code in rpm spec happy as it assumes there is - // always something in application image. - fakeRuntimeDir.resolve("bin").toFile().mkdir(); - } - if (TKit.isOSX()) { // Make MacAppImageBuilder happy createBulkFile.accept(fakeRuntimeDir.resolve(Path.of( "lib/jli/libjli.dylib"))); } - // Mak sure fake runtime takes some disk space. + // Make sure fake runtime takes some disk space. // Package bundles with 0KB size are unexpected and considered // an error by PackageTest. - createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("bin", "bulk"))); + createBulkFile.accept(fakeRuntimeDir.resolve(Path.of("lib", "bulk"))); cmd.setArgumentValue("--runtime-image", fakeRuntimeDir); }); 
@alexeysemenyukoracle
Copy link
Member

Updated CustomInfoPListTest to test Info.plist with bin folder.

Why? jpackage picks the same file from the resource directory regardless of whether the "bin" subdirectory is present in the runtime. The "bin" subdirectory in the runtime only affects the default plist resource that jpackage uses.

Comment on lines +366 to +369
final var useRuntimeInfoPlist =
Files.isDirectory(env.resolvedLayout().runtimeDirectory().resolve("bin")) ||
app.isRuntime();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The writeRuntimeInfoPlist() action is executed for the MacBuildApplicationTaskID.RUNTIME_INFO_PLIST and MacBuildApplicationTaskID.COPY_RUNTIME_INFO_PLIST tasks. MacBuildApplicationTaskID.RUNTIME_INFO_PLIST doesn't have dependencies. This means it can be executed before the runtime files are available in the output app image. Currently, this is not a problem because jpackage executes tasks synchronously, but eventually it will run them asynchronously, and the Files.isDirectory(...) test will fail.

The plist template should be selected at the configuration phase, not the bundling phase. However, this will require knowing/guessing if jlink will create native commands in the "bin" directory from its command line. It is straightforward if it boils down to testing whether it has the "--strip-native-commands" option. This is what we do when we test if jlink options are correct for the Apple App Store, right? Test for "--strip-native-commands" in DeployParams.java

I'd suggest adding boolean jdk.jpackage.internal.model.RuntimeBuilder.withNativeCommands() method. Then the code will be:

final var useRuntimeInfoPlist = app.isRuntime() || app.runtimeBuilder().orElseThrow().withNativeCommands(); 

Alternatively, you may add the BuildApplicationTaskID.RUNTIME task as a dependency for the MacBuildApplicationTaskID.RUNTIME_INFO_PLIST task. However, this is a less preferable solution.

@sashamatveev
Copy link
Member Author

Why? jpackage picks the same file from the resource directory regardless of whether the "bin" subdirectory is present in the runtime. The "bin" subdirectory in the runtime only affects the default plist resource that jpackage uses.

Not sure. I agree we should not mix testing this fix with CustomInfoPListTest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core-libs core-libs-dev@openjdk.org rfr Pull request is ready for review

2 participants