Skip to content

8353185: Introduce the concept of upgradeable files in context of JEP 493 #24388

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

jerboaa
Copy link
Contributor

@jerboaa jerboaa commented Apr 2, 2025

For JEP 493-enabled builds there are no JMODs. Certain files come from the installed JDK image when a user creates a custom run-time from it. This is problematic for example for files that often come from a different package (e.g. cacerts file for Linux distro builds of OpenJDK packaged as RPMs), or more generally when they get updated out-of-band of the JDK build itself like the tzupdater tool.

When that happens the hash sum recorded at JDK build time of those files no longer match, causing jlink to fail. I propose to allow for those files to get "upgraded" should this happen. The way this works is as follows:

  1. The list of upgradeable files is configured by a resource file in jdk.jlink on a per module basis. Right now, only two files from the java.base module will be allowed to be upgraded with a link from the current run-time image.
  2. For those files the hash sum checks are skipped.

Testing

  • GHA
  • jdk/tools/jlink jtreg tests (also on GHA)
  • Some manual tests with updated tzdb.dat and cacerts files.

Thoughts?


Progress

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

Issue

  • JDK-8353185: Introduce the concept of upgradeable files in context of JEP 493 (Enhancement - P3)

Reviewers

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 24388

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

Using diff file

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

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Apr 2, 2025

👋 Welcome back sgehwolf! 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 Apr 2, 2025

@jerboaa This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8353185: Introduce the concept of upgradeable files in context of JEP 493

Reviewed-by: clanger, ihse, alanb

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 162 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the rfr Pull request is ready for review label Apr 2, 2025
@openjdk
Copy link

openjdk bot commented Apr 2, 2025

@jerboaa 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 core-libs core-libs-dev@openjdk.org label Apr 2, 2025
@mlbridge
Copy link

mlbridge bot commented Apr 2, 2025

Webrevs

@jerboaa jerboaa changed the title 8353185: Introduce the concept of upgradeable files in context of JEP493 8353185: Introduce the concept of upgradeable files in context of JEP 493 Apr 2, 2025
@ecki
Copy link
Contributor

ecki commented Apr 3, 2025

What about changes to conf files, especially Java.security (for hardening TLS settings) - or at least pointing to a include?

@AlanBateman
Copy link
Contributor

What about changes to conf files, especially Java.security (for hardening TLS settings) - or at least pointing to a include?

The opposite is where weaker or insecure algorithms are enabled, wouldn't want that copied by jlink into another run-time image.

@ecki
Copy link
Contributor

ecki commented Apr 3, 2025

Well, shipping customized runtimes sounds like a valid usecase, but yes maybe it’s more important for jpackage.

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 3, 2025

What about changes to conf files, especially Java.security (for hardening TLS settings) - or at least pointing to a include?

You can still do that after creating the custom runtime as you do today when linking using JMODs. The point of this fix is to be able to have a way to still run jlink based on the run-time image when you're using cacerts file from an external location (outside the JDKs control) or have updated tzdata (also outside the JDK build). I wouldn't expect for this to be needed in many (most?) cases.

@AlanBateman
Copy link
Contributor

Part of me is concerned that the hidden option is a bit of an attractive nuisance. What would you think about just having a fixed list in a properties file in the repo, thus a resource in the jlink module. This would avoid the list in JRTArchive too. It wouldn't rule out introducing something more in the future.

Right now the only examples we have are in java.base. In time it might be that some other modules might need something.

I've like to know more about cacerts. Are the distros swapping this to a link after the run-time image is created or is it that the sym link is there from the startup and the hashing has followed the link?

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 3, 2025

Part of me is concerned that the hidden option is a bit of an attractive nuisance. What would you think about just having a fixed list in a properties file in the repo, thus a resource in the jlink module. This would avoid the list in JRTArchive too. It wouldn't rule out introducing something more in the future.

I'm not entirely sure what you are suggesting. Is it keeping a list of "upgradeable" files in a properties file. Files listed in that properties file aren't checked for hash sums (i.e. even if it's not modified)? That is, the explicit opt-in is not needed? Fine by me, but it's a weaker check. If we don't need the explicit opt-in, the patch becomes simpler as well.

Right now the only examples we have are in java.base. In time it might be that some other modules might need something.

Sure. I've considered that. The java.base specific check can go away and it should work for any module as long as we have a list of what's considered an upgradable file (wherever it comes from).

I've like to know more about cacerts. Are the distros swapping this to a link after the run-time image is created or is it that the sym link is there from the startup and the hashing has followed the link?

Yes, that's one case. For example Fedora/RHEL distros have a ca-certificates package which also provides a cacerts file consumable from the JDK (/etc/pki/java/cacerts). This can be a build-time option, or replaced with a symlink after the JDK has been built.

Another use case is amending the cacerts store. For example with an enterprise internal CA, in a container. It's really not different to tzdb.dat. That too, can be a symlink to a system package or get updated with an external tool after a build.

The option of not following symlinks, isn't an option, though, as certain distro packaging standards require one to install, say man pages - in a specific directory. To keep the JDK image whole, that is usually fixed by placing a symlink back in the JDK image directory.

@AlanBateman
Copy link
Contributor

I'm not entirely sure what you are suggesting. Is it keeping a list of "upgradeable" files in a properties file. Files listed in that properties file aren't checked for hash sums (i.e. even if it's not modified)? That is, the explicit opt-in is not needed? Fine by me, but it's a weaker check. If we don't need the explicit opt-in, the patch becomes simpler as well.

Yes, I think keep simple. We always want to allow tzdb.dat be upgraded by the TZ updater tool. I think treating cacerts the same way is okay. As you note, it has to be kept up to date too. I was thinking keytool import and wasn't sure if the Linux distros configure with -with-cacerts-file or did something else. Thanks for the clarification on this point.

Starting with a simple list of two files won't preclude us from re-visiting it again in the future.

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 4, 2025

I'm not entirely sure what you are suggesting. Is it keeping a list of "upgradeable" files in a properties file. Files listed in that properties file aren't checked for hash sums (i.e. even if it's not modified)? That is, the explicit opt-in is not needed? Fine by me, but it's a weaker check. If we don't need the explicit opt-in, the patch becomes simpler as well.

Yes, I think keep simple. We always want to allow tzdb.dat be upgraded by the TZ updater tool. I think treating cacerts the same way is okay. As you note, it has to be kept up to date too. I was thinking keytool import and wasn't sure if the Linux distros configure with -with-cacerts-file or did something else. Thanks for the clarification on this point.

Starting with a simple list of two files won't preclude us from re-visiting it again in the future.

OK. Thanks. I'll update it then.

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 4, 2025

@AlanBateman Updated the patch. Please take another look. Thanks!

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 4, 2025

/label add build-dev

@openjdk openjdk bot added the build build-dev@openjdk.org label Apr 4, 2025
@openjdk
Copy link

openjdk bot commented Apr 4, 2025

@jerboaa
The build label was successfully added.

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 4, 2025

It took me a while to find the magic trick to get the jlink resource file copied, so adding build-dev for their input too.

Copy link
Contributor

@RealCLanger RealCLanger left a comment

Choose a reason for hiding this comment

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

Just a few fly-by findings, no full review.

I see that you're actively on the upgradeable files. What about #24190? (@AlanBateman, what are your thoughts, how could we progress there?)

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 7, 2025

I see that you're actively on the upgradeable files. What about #24190?

Let's keep the discussion on #24190, please.

@@ -62,7 +68,38 @@ public static boolean isLinkableRuntime() {

private static InputStream getDiffInputStream(String module) throws IOException {
String resourceName = String.format(DIFF_PATTERN, module);
return LinkableRuntimeImage.class.getModule().getResourceAsStream(resourceName);
return JDK_JLINK_MOD.getResourceAsStream(resourceName);
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI you can use LinkableRuntimeImage.class.getResourceAsStream here as the resource is in the current module.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's very odd, but when I attempt this then the resource is not found. It seems to fail on the module name verification. For example: jlink --help | tail -n2 shows as disabled for an enabled linkable runtime image.

Copy link
Contributor

Choose a reason for hiding this comment

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

Without reproducing, I can't immediately say why Class.getResourceAsStream would fail here. This is a good API for locating resources in the caller's module.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try to find a reproducer outside this PR and will let you know if I find anything.

Copy link
Member

@magicus magicus left a comment

Choose a reason for hiding this comment

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

Build changes look good now. Thanks!

/reviewers 2

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Apr 9, 2025
@openjdk
Copy link

openjdk bot commented Apr 9, 2025

@magicus
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Apr 9, 2025
@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 10, 2025

@AlanBateman Any more thoughts on this? Thanks!

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Apr 10, 2025
@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 10, 2025

@RealCLanger Are you OK with the latest patch (as far as your comments are concerned)?

@RealCLanger
Copy link
Contributor

@RealCLanger Are you OK with the latest patch (as far as your comments are concerned)?

Yes, looks good. 😄

@jerboaa
Copy link
Contributor Author

jerboaa commented Apr 15, 2025

/integrate

@openjdk
Copy link

openjdk bot commented Apr 15, 2025

Going to push as commit 4e24dc0.
Since your change was applied there have been 208 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Apr 15, 2025
@openjdk openjdk bot closed this Apr 15, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Apr 15, 2025
@openjdk
Copy link

openjdk bot commented Apr 15, 2025

@jerboaa Pushed as commit 4e24dc0.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build build-dev@openjdk.org core-libs core-libs-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

5 participants