jdk icon indicating copy to clipboard operation
jdk copied to clipboard

8311302: Implement JEP 493: Linking Run-Time Images without JMODs

Open jerboaa opened this issue 1 year ago • 137 comments

Please review this patch which adds a jlink mode to the JDK which doesn't need the packaged modules being present. A.k.a run-time image based jlink. Fundamentally this patch adds an option to use jlink even though your JDK install might not come with the packaged modules (directory jmods). This is particularly useful to further reduce the size of a jlinked runtime. After the removal of the concept of a JRE, a common distribution mechanism is still the full JDK with all modules and packaged modules. However, packaged modules can incur an additional size tax. For example in a container scenario it could be useful to have a base JDK container including all modules, but without also delivering the packaged modules. This comes at a size advantage of ~25%. Such a base JDK container could then be used to jlink application specific runtimes, further reducing the size of the application runtime image (App + JDK runtime; as a single image or separate bundles, depending on the app being modularized).

The basic design of this approach is to add a jlink plugin for tracking non-class and non-resource files of a JDK install. I.e. files which aren't present in the jimage (lib/modules). This enables producing a JRTArchive class which has all the info of what constitutes the final jlinked runtime.

Basic usage example:

$ diff -u <(./bin/java --list-modules --limit-modules java.se) <(../linux-x86_64-server-release/images/jdk/bin/java --list-modules --limit-modules java.se)
$ diff -u <(./bin/java --list-modules --limit-modules jdk.jlink) <(../linux-x86_64-server-release/images/jdk/bin/java --list-modules --limit-modules jdk.jlink)
$ ls ../linux-x86_64-server-release/images/jdk/jmods
java.base.jmod            java.net.http.jmod       java.sql.rowset.jmod      jdk.crypto.ec.jmod         jdk.internal.opt.jmod                     jdk.jdi.jmod         jdk.management.agent.jmod  jdk.security.auth.jmod
java.compiler.jmod        java.prefs.jmod          java.transaction.xa.jmod  jdk.dynalink.jmod          jdk.internal.vm.ci.jmod                   jdk.jdwp.agent.jmod  jdk.management.jfr.jmod    jdk.security.jgss.jmod
java.datatransfer.jmod    java.rmi.jmod            java.xml.crypto.jmod      jdk.editpad.jmod           jdk.internal.vm.compiler.jmod             jdk.jfr.jmod         jdk.management.jmod        jdk.unsupported.desktop.jmod
java.desktop.jmod         java.scripting.jmod      java.xml.jmod             jdk.hotspot.agent.jmod     jdk.internal.vm.compiler.management.jmod  jdk.jlink.jmod       jdk.naming.dns.jmod        jdk.unsupported.jmod
java.instrument.jmod      java.security.jgss.jmod  jdk.accessibility.jmod    jdk.httpserver.jmod        jdk.jartool.jmod                          jdk.jpackage.jmod    jdk.naming.rmi.jmod        jdk.xml.dom.jmod
java.logging.jmod         java.security.sasl.jmod  jdk.attach.jmod           jdk.incubator.vector.jmod  jdk.javadoc.jmod                          jdk.jshell.jmod      jdk.net.jmod               jdk.zipfs.jmod
java.management.jmod      java.se.jmod             jdk.charsets.jmod         jdk.internal.ed.jmod       jdk.jcmd.jmod                             jdk.jsobject.jmod    jdk.nio.mapmode.jmod
java.management.rmi.jmod  java.smartcardio.jmod    jdk.compiler.jmod         jdk.internal.jvmstat.jmod  jdk.jconsole.jmod                         jdk.jstatd.jmod      jdk.random.jmod
java.naming.jmod          java.sql.jmod            jdk.crypto.cryptoki.jmod  jdk.internal.le.jmod       jdk.jdeps.jmod                            jdk.localedata.jmod  jdk.sctp.jmod
$ ls jmods
ls: cannot access 'jmods': No such file or directory
$ ./bin/jlink --version
22-internal
$ ./bin/jlink --add-modules java.se --output ../java.se-runtime --verbose
java.base jrt:/java.base (run-image)
java.compiler jrt:/java.compiler (run-image)
java.datatransfer jrt:/java.datatransfer (run-image)
java.desktop jrt:/java.desktop (run-image)
java.instrument jrt:/java.instrument (run-image)
java.logging jrt:/java.logging (run-image)
java.management jrt:/java.management (run-image)
java.management.rmi jrt:/java.management.rmi (run-image)
java.naming jrt:/java.naming (run-image)
java.net.http jrt:/java.net.http (run-image)
java.prefs jrt:/java.prefs (run-image)
java.rmi jrt:/java.rmi (run-image)
java.scripting jrt:/java.scripting (run-image)
java.se jrt:/java.se (run-image)
java.security.jgss jrt:/java.security.jgss (run-image)
java.security.sasl jrt:/java.security.sasl (run-image)
java.sql jrt:/java.sql (run-image)
java.sql.rowset jrt:/java.sql.rowset (run-image)
java.transaction.xa jrt:/java.transaction.xa (run-image)
java.xml jrt:/java.xml (run-image)
java.xml.crypto jrt:/java.xml.crypto (run-image)

Providers:
  java.desktop provides java.net.ContentHandlerFactory used by java.base
  java.base provides java.nio.file.spi.FileSystemProvider used by java.base
  java.naming provides java.security.Provider used by java.base
  java.security.jgss provides java.security.Provider used by java.base
  java.security.sasl provides java.security.Provider used by java.base
  java.xml.crypto provides java.security.Provider used by java.base
  java.base provides java.util.random.RandomGenerator used by java.base
  java.management.rmi provides javax.management.remote.JMXConnectorProvider used by java.management
  java.management.rmi provides javax.management.remote.JMXConnectorServerProvider used by java.management
  java.desktop provides javax.print.PrintServiceLookup used by java.desktop
  java.desktop provides javax.print.StreamPrintServiceFactory used by java.desktop
  java.management provides javax.security.auth.spi.LoginModule used by java.base
  java.desktop provides javax.sound.midi.spi.MidiDeviceProvider used by java.desktop
  java.desktop provides javax.sound.midi.spi.MidiFileReader used by java.desktop
  java.desktop provides javax.sound.midi.spi.MidiFileWriter used by java.desktop
  java.desktop provides javax.sound.midi.spi.SoundbankReader used by java.desktop
  java.desktop provides javax.sound.sampled.spi.AudioFileReader used by java.desktop
  java.desktop provides javax.sound.sampled.spi.AudioFileWriter used by java.desktop
  java.desktop provides javax.sound.sampled.spi.FormatConversionProvider used by java.desktop
  java.desktop provides javax.sound.sampled.spi.MixerProvider used by java.desktop
  java.logging provides jdk.internal.logger.DefaultLoggerFinder used by java.base
  java.desktop provides sun.datatransfer.DesktopDatatransferService used by java.datatransfer

One nice property of this patch is that it can produce an identical (as in binary identical) java.se JDK image in run-time image based link mode as compared to a regular jlink with packaged modules present. This has been asserted in newly added tests. In order to prevent accidental copy of modified files in the base JDK a checksum mechanism is in place to fail the link if a runtime image file has been modified. This is also asserted in tests.

One limitation of this mode is that there is no way to use it for cross-linking (at least currently). That is, a run-time image based jlink needs to happen on the same runtime platform the resulting image is intended to get deployed on.

Testing:

  • [x] GHA (including jdk/tools/jlink tests and JDKs built with --enable-linkable-runtime). See for example the latest run and here.
  • [x] Some tests on our internal infra. It didn't show any regressions.
  • [x] Added tests as part of the patch (11 of them). All pass on the major platforms.

Thoughts?


Progress

  • [x] Change must not contain extraneous whitespace
  • [x] Commit message must refer to an issue
  • [ ] Change requires a JEP request to be targeted
  • [ ] Change requires CSR request JDK-8317420 to be approved
  • [ ] Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issues

  • JDK-8311302: Implement JEP 493: Linking Run-Time Images without JMODs (Enhancement - P4)
  • JDK-8333799: JEP 493: Linking Run-Time Images without JMODs (JEP)
  • JDK-8317420: Implement JEP 493: Linking Run-Time Images without JMODs (CSR)

Reviewers

Contributors

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 14787

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

Using diff file

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

Webrev

Link to Webrev Comment

jerboaa avatar Jul 06 '23 17:07 jerboaa

:wave: 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.

bridgekeeper[bot] avatar Jul 06 '23 17:07 bridgekeeper[bot]

@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[bot] avatar Jul 06 '23 17:07 openjdk[bot]

@jerboaa This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

bridgekeeper[bot] avatar Aug 04 '23 11:08 bridgekeeper[bot]

Please keep open, bot.

jerboaa avatar Aug 07 '23 14:08 jerboaa

@jerboaa Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. See OpenJDK Developers’ Guide for more information.

openjdk[bot] avatar Aug 08 '23 16:08 openjdk[bot]

/csr needed

jerboaa avatar Aug 10 '23 16:08 jerboaa

@jerboaa has indicated that a compatibility and specification (CSR) request is needed for this pull request.

@jerboaa please create a CSR request for issue JDK-8311302 with the correct fix version. This pull request cannot be integrated until the CSR request is approved.

openjdk[bot] avatar Aug 10 '23 16:08 openjdk[bot]

@AlanBateman Hi! Moving the discusion to this PR now. I've updated this patch to do single-hops only by default now. Looks like this:

$ bin/jlink --add-modules java.base --output ../testme-java-base/ --verbose
java.base jrt:/java.base (run-image)

Providers:
  java.base provides java.nio.file.spi.FileSystemProvider used by java.base
  java.base provides java.util.random.RandomGenerator used by java.base
Error: Run image links only allow single-hop.

I'm not particularly fond of that, though, as there is a need to know what is single hop is and what not. My approach is adding a 0-sized stamp file to the lib/modules jimage, but that has the issue of now breaking comparison between a packaged module jlink vs. a runtime image using one. The same would be true for adding a file or appending the jmod_resources file with some info to know it's multi-hop. Some state needs to be there unless I'm missing something for this. For now an option suppresses creating that file so as to be able to keep asserting packaged vs run-image link and other properties in tests. I'd argue most of the time multi-hop would be OK, but default off and a switch to turn it on seems reasonable to me. Up for discussion...

Also, if a file is modified the link fails unless it's turned off with an option. Looks like this:

$ ./bin/jlink --add-modules java.base --output ../abort-on-mod --verbose
java.base jrt:/java.base (run-image)

Providers:
  java.base provides java.nio.file.spi.FileSystemProvider used by java.base
  java.base provides java.util.random.RandomGenerator used by java.base
Error: java.lang.IllegalArgumentException: /disk/openjdk/upstream-sources/git/jdk-jdk/build/jmodless-copy-jmods-removed/conf/net.properties has been modified. Please double check!
$ echo $?
1

Both things will have CLI options to a) make the exit on mod a warning only and b) allow multi-hop - some tests needed that. Hence, I've marked this PR as needing a CSR for now.

More thoughts?

jerboaa avatar Aug 10 '23 17:08 jerboaa

@AlanBateman Gentle ping.

jerboaa avatar Aug 29 '23 12:08 jerboaa

@AlanBateman Gentle ping.

On my list, it's a lot to get through and a number of aspects to this that I think will require refinement and discussion.

AlanBateman avatar Aug 29 '23 17:08 AlanBateman

@AlanBateman Gentle ping.

On my list, it's a lot to get through and a number of aspects to this that I think will require refinement and discussion.

Thanks for the heads-up! Your input is much appreciated.

jerboaa avatar Aug 30 '23 08:08 jerboaa

I did a pass over this to see where this proposal is currently at. At a high-level I think good progress since the discussion on leyden-dev some time ago. A few comments this from this pass:

If I read it correctly, the default behavior is now to fail if jlink is executed from a run-time image that has been modified from the original and the packaged modules are not observable on the module path (this includes the default module path effectively appended by jlink). That seems the right policy as it avoids modifications by plugins or conf changes silently propagating.

If I read the code correctly, the error when a hash doesn't match is a very terse "Run image links only allow single-hop" so that probably needs to be looked to make sure the message says that the run-time image has been modified and maybe include one of the files/resources that has changed so there is something real to go with the error.

The command line options to override and change the error to a warning or silently ignore seems to be "-run-time-ignore-single-hop" and "--run-image-only-warnings". Maybe it should be reduced to just one option and maybe it should contain the word "clone" to something that makes it more obvious that it's just copying or cloning the contents of the modules in the run-time image (I suspect "single hop" won't be understood).

Adding a new jdk.tools.jlink.internal.Archive implementation where the resources come from the run-time image seems a sensible approach. I don't particularly like the name "JmodLessArchive" because the original module may not have been packaged as a JMOD file, it may have been a modular JAR. Same comment on the BOM file "jmod_resources" added to the top-level directory of each module. I think it's clever to add this to each module in the container image but part of me wonders if it should be hidden in some way to avoid tools depending on it. I don't have a concrete suggestion except to wonder if jrtfs should filter it out, same thing in the SystemModuleReader code as ModuleReader.find("jmod_resources") will find the resource, could be an attractive nuisance.

AlanBateman avatar Sep 19 '23 17:09 AlanBateman

I did a pass over this to see where this proposal is currently at. At a high-level I think good progress since the discussion on leyden-dev some time ago. A few comments this from this pass:

Thanks, Alan!

If I read it correctly, the default behavior is now to fail if jlink is executed from a run-time image that has been modified from the original and the packaged modules are not observable on the module path (this includes the default module path effectively appended by jlink). That seems the right policy as it avoids modifications by plugins or conf changes silently propagating.

Correct.

If I read the code correctly, the error when a hash doesn't match is a very terse "Run image links only allow single-hop" so that probably needs to be looked to make sure the message says that the run-time image has been modified and maybe include one of the files/resources that has changed so there is something real to go with the error.

Not quite. See the example I've added in the previous comment. It already includes that info. It looks like this:

Error: java.lang.IllegalArgumentException: /disk/openjdk/upstream-sources/git/jdk-jdk/build/jmodless-copy-jmods-removed/conf/net.properties has been modified. Please double check!

The message can of course be modified what we think is best.

The command line options to override and change the error to a warning or silently ignore seems to be "-run-time-ignore-single-hop" and "--run-image-only-warnings". Maybe it should be reduced to just one option and maybe it should contain the word "clone" to something that makes it more obvious that it's just copying or cloning the contents of the modules in the run-time image (I suspect "single hop" won't be understood).

I believe keeping them both makes sense. Or at least make it so that it takes an argument to be able to distinguish between the two. The reason why I think this is useful is in the container case, where say - the JDK got installed by an installer - which didn't include packaged modules, but is otherwise a full JDK (with all modules). The installer already does integrity checking of the files and it might be desirable to do multi-hop evolutions, while still wanting to get warnings/errors on modified configuration files, for example. Happy to change the name of that flag/flags to --clone-run-image=ignore-multi,warn-only or something similar.

Adding a new jdk.tools.jlink.internal.Archive implementation where the resources come from the run-time image seems a sensible approach. I don't particularly like the name "JmodLessArchive" because the original module may not have been packaged as a JMOD file, it may have been a modular JAR. Same comment on the BOM file "jmod_resources" added to the top-level directory of each module.

OK. How about RunimageArchive and runimage_resources or clone_resources?

I think it's clever to add this to each module in the container image but part of me wonders if it should be hidden in some way to avoid tools depending on it. I don't have a concrete suggestion except to wonder if jrtfs should filter it out, same thing in the SystemModuleReader code as ModuleReader.find("jmod_resources") will find the resource, could be an attractive nuisance.

That seems fine. I can add code to filter those resources out. On the other hand, no special handling is being made for jdk/internal/vm/options. Perhaps that should be handled uniformly?

jerboaa avatar Sep 29 '23 16:09 jerboaa

The command line options to override and change the error to a warning or silently ignore seems to be "-run-time-ignore-single-hop" and "--run-image-only-warnings". Maybe it should be reduced to just one option and maybe it should contain the word "clone" to something that makes it more obvious that it's just copying or cloning the contents of the modules in the run-time image

After some more thought I've changed my mind and I've come to the conclusion that it makes sense to combine them. The latest patch uses --unlock-run-image as the "force" option which demotes the error to a warning.

Perhaps it makes sense to get some consensus on the naming parts at this point. The CSR seems a good vehicle for that and I've fleshed it out a bit now.

jerboaa avatar Oct 16 '23 13:10 jerboaa

Current GHA failure of gc/TestJNICriticalStressTest#id0 on Windows seems unrelated. FWIW, this check which also includes jlink tests passed fine.

jerboaa avatar Oct 19 '23 13:10 jerboaa

I looked at the latest proposal and CSR. Overall I think the proposal is good and you've got the right default to fail if the run-time image has been modified. So I think we are down to a few lesser topics now.

I'm wondering if the CLI option to override, meaning a first run-time image containing the jdk.jlink module generates a second run-time image, and the first run-time image has been modified, whether this is really needed. I'm wondering about this because this CLI option is hard to explain, will developers really understand it? If there is an CLI option then we'll need to find a better name, I don't think "--unlock-run-time" works as a name (the usage of options talk about "runtime image" for example, maybe "-ignore-signing-information" can provide inspiration as an override too).

Can --add-run-image-resources be dropped? Exposing this in the interface feels like it's an attractive nuisance and not clear (to me anyway) what developers would do with this.

A few very minor things that I jotted down while looking at the current proposal:

  • Adding a resource to serve as a marker that indicates it was created without the packaged modules is fine. I think the name should be looked as "runimage" is a bit consistent for this area. I'm also wondering if it would be better to hide in jdk/internal somewhere to avoid any tooling assuming it's a supported interface.

  • The error message exclaims "Please double check!", I think that error message will need to be tweaked once we get down to details like this.

AlanBateman avatar Nov 12 '23 11:11 AlanBateman

@AlanBateman Thanks for having taken another look!

I looked at the latest proposal and CSR. Overall I think the proposal is good and you've got the right default to fail if the run-time image has been modified. So I think we are down to a few lesser topics now.

Glad to hear it. Hopefully we can still get this into JDK 22.

I'm wondering if the CLI option to override, meaning a first run-time image containing the jdk.jlink module generates a second run-time image, and the first run-time image has been modified, whether this is really needed. I'm wondering about this because this CLI option is hard to explain, will developers really understand it? If there is an CLI option then we'll need to find a better name, I don't think "--unlock-run-time" works as a name (the usage of options talk about "runtime image" for example, maybe "-ignore-signing-information" can provide inspiration as an override too).

I think we need the option. Be it only for users wanting to validate links with and without packaged modules present (as one of the tests does). How about we call the option --force-run-image-link? Or maybe --ignore-base-run-image-changes. I'm not very good with coming up with names.

Can --add-run-image-resources be dropped? Exposing this in the interface feels like it's an attractive nuisance and not clear (to me anyway) what developers would do with this.

It's not clear what you mean by that. Dropped from what? The CSR? Something else? The run-image based link needs the --add-run-image-resources plugin for it to work.

A few very minor things that I jotted down while looking at the current proposal:

* Adding a resource to serve as a marker that indicates it was created without the packaged modules is fine. I think the name should be looked as "runimage" is a bit consistent for this area. I'm also wondering if it would be better to hide in jdk/internal somewhere to avoid any tooling assuming it's a supported interface.

How does jdk/internal/runimage as a name sound?

* The error message exclaims "Please double check!", I think that error message will need to be tweaked once we get down to details like this.

Sure. I can just drop that phrase.

jerboaa avatar Nov 13 '23 15:11 jerboaa

I did one pass through the changes. Looks like the plugin author has to consider how it should work to support linking without packaged modules.

The current implementation --system-modules re-applies for every jlink invocation since the transformation depends on the set of modules to be linked in the resulting image.

OTOH --vendor-bug-url, --vendor-version and --vendor-vm-bug-url plugins are auto-applied to the new image created via this run-time image based linking when these options are not specified.

I was wondering what plugins that were applied in the first image are carried automatically during the run-time image based linking? I would assume this will generate an image equivalent to running jlink with the packaged modules present. Therefore nothing should be carried automatically from the current run-time image, shouldn't it?

I agree that --add-run-image-resources should be hidden and it's not target for developers to use. I consider it's jlink internal implementation. It's auto-enabled and always generates the per-module runimage_resources. I think we might need to add Plugin::showPlugin or hidePlugin to specify if this plugin should be hidden from --list-plugins.

It's good to move runimage_resources to some package under jdk/internal but each module will need to be a different package name. BTW I found runimage a confusing term.

I am also not certain if we should support --unlock-run-time option. Are you trying to make the users do less work to configure some properties files once in the first image and all the custom runtime images created from that will not need to do the configuration?

mlchung avatar Nov 14 '23 02:11 mlchung

It's not clear what you mean by that. Dropped from what? The CSR? Something else? The run-image based link needs the --add-run-image-resources plugin for it to work.

I mean the list of plugins that are listed by --list-plugins. I see Mandy has the same comment and has a suggestion on how to hide this.

BTW: We need to replace all uses of "run-image" with "run-time image" to keep it consistent with the existing JEPs, docs, and other places.

AlanBateman avatar Nov 14 '23 07:11 AlanBateman

I did one pass through the changes.

Thanks for the review!

Looks like the plugin author has to consider how it should work to support linking without packaged modules.

Yes, to some extent.

The current implementation --system-modules re-applies for every jlink invocation since the transformation depends on the set of modules to be linked in the resulting image.

Yes. The same is true for a run-time image based link for the system modules plugin.

OTOH --vendor-bug-url, --vendor-version and --vendor-vm-bug-url plugins are auto-applied to the new image created via this run-time image based linking when these options are not specified.

Since some of those things are also possible to specify at build-time (with --with-vendor-name and friends), this applies to the packaged-modules link as well.

I was wondering what plugins that were applied in the first image are carried automatically during the run-time image based linking? I would assume this will generate an image equivalent to running jlink with the packaged modules present.

I'm not sure I fully understand the question.

Since the run-time image link is fundamentally based on using the modules image (lib/modules) plus files on the filesystem of the JDK install (minus jmods folder), everything that modifies class files, adds resources, modifies files like stripping debug info from binaries, carries over.

Say, you'd have a link using packaged modules:

jlink --add-modules jdk.jlink --strip-debug --output jdk.jlink-stripped

A link using the run-time image, then would produce a stripped java.base module with this step:

./jdk.jlink-stripped/bin/jlink --add-modules java.base --output java.base-stripped

IMO that's a nice use-case to have. If you want a re-setted link, use the packaged modules instead and start afresh.

Therefore nothing should be carried automatically from the current run-time image, shouldn't it?

Could you clarify what "carried automatically" means?

I agree that --add-run-image-resources should be hidden and it's not target for developers to use. I consider it's jlink internal implementation. It's auto-enabled and always generates the per-module runimage_resources. I think we might need to add Plugin::showPlugin or hidePlugin to specify if this plugin should be hidden from --list-plugins.

OK. Done in the latest version. I've added Plugin::isHidden, defaulting to false.

It's good to move runimage_resources to some package under jdk/internal but each module will need to be a different package name. BTW I found runimage a confusing term.

Unfortunately, adding packages like that isn't allowed, since jlink performs validation of the known packages using the module descriptor. By adding the resource to a new package, we'd somehow have to modify the module descriptor as well for every module. For now, I've resorted to renaming the resource file to - a still package-less - jdk_internal_runimage.

I am also not certain if we should support --unlock-run-time option. Are you trying to make the users do less work to configure some properties files once in the first image and all the custom runtime images created from that will not need to do the configuration?

Yes, that could be a use-case. Personally, I liked the possibility of doing recursive links. There was some beauty to it, since it allows multiple teams to do links suitable to their use-case. But this is now gone with the latest version which uses a marker file to prevent multiple recursive links based on the run-time image.

On the other hand, there are tests part of this patch which verify that a default link for java.se with default options using packaged modules and using the run-time image based link are binary identical. Since any extra resource (like the marker file), destroy this property, I'd like to keep some way to still verify this.

Perhaps doing this less visibly than an actual new CLI option is more amenable? A property akin to jlink.debug perhaps? Something like -Djlink.no-marker? It could be an undocumented thing.

jerboaa avatar Nov 14 '23 15:11 jerboaa

It's not clear what you mean by that. Dropped from what? The CSR? Something else? The run-image based link needs the --add-run-image-resources plugin for it to work.

I mean the list of plugins that are listed by --list-plugins. I see Mandy has the same comment and has a suggestion on how to hide this.

OK, thanks. Done. I guess since it's now a hidden plugin does it still need mentioning in the CSR?

BTW: We need to replace all uses of "run-image" with "run-time image" to keep it consistent with the existing JEPs, docs, and other places.

Makes sense. Did a first pass fixing those.

jerboaa avatar Nov 14 '23 16:11 jerboaa

A few very minor things that I jotted down while looking at the current proposal:

* Adding a resource to serve as a marker that indicates it was created without the packaged modules is fine. I think the name should be looked as "runimage" is a bit consistent for this area. I'm also wondering if it would be better to hide in jdk/internal somewhere to avoid any tooling assuming it's a supported interface.

How does jdk/internal/runimage as a name sound?

Coming back to this. Since jlink verifies the packages in the module descriptor are equal to the observed packages, we cannot add packages that way without also changing the module descriptor. I've renamed the resource file to jdk_internal_runimage for now. Hope that's sufficient.

jerboaa avatar Nov 14 '23 16:11 jerboaa

The current implementation --system-modules re-applies for every jlink invocation since the transformation depends on the set of modules to be linked in the resulting image.

Yes. The same is true for a run-time image based link for the system modules plugin.

OTOH --vendor-bug-url, --vendor-version and --vendor-vm-bug-url plugins are auto-applied to the new image created via this run-time image based linking when these options are not specified.

Since some of those things are also possible to specify at build-time (with --with-vendor-name and friends), this applies to the packaged-modules link as well.

Better to explain with an example:

$ jdk22/bin/jlink --add-modules jdk.compiler,jdk.jlink --output image1 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true"

$ image1/bin/jlink --add-modules jdk.jlink --output image2 --add-options "-Dcom.acme.name=BAR"

How can the user know what plugins are applied to image2? i.e. what is the jlink command to produce image2 if running from jdk22 with the packaged modules present?

Reading the changes, I'm not sure but I think it's not equivalent to:

jdk22/bin/jlink --add-modules jdk.jlink --output image2 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true" --add-options "-Dcom.acme.name=BAR"

I think this behavior should be documented.

mlchung avatar Nov 14 '23 17:11 mlchung

Thanks.

How can the user know what plugins are applied to image2? i.e. what is the jlink command to produce image2 if running from jdk22 with the packaged modules present?

The only way to know is by knowing the chain of jlink commands yielding up to the final image. Let jlink' be the jlink using packaged modules. Currently this can be at most two. In addition, the contents of argfile needs to be known. That doesn't seem to be very different to the status quo, though. See below.

Reading the changes, I'm not sure but I think it's not equivalent to:

jdk22/bin/jlink --add-modules jdk.jlink --output image2 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true" --add-options "-Dcom.acme.name=BAR"

Note that plugins like --add-options have been modified so that only the options passed at the current CLI will propagate to the final image. So in this case, image1 would have property com.foo.XYZ set, but not image2. Incidentally, what you probably intended to use was `--add-options "-Dcom.foo.XYZ=true -Dcom.acme.name=BAR".

Having said that, depending on the contents of argfile, those could be equivalent. In fact, they are with --unlock-run-image, and an empty argfile. --unlock-run-image avoids adding the marker file, which is the only difference when we extract the image.

--save-jlink-argfiles brings a strange angle to this discussion, but it's conceivable to get a similarly different image, even with --keep-packaged-modules. Consider:

echo '--add-options=-XX:+UseParallelGC' > argfile
./jdk22/bin/jlink --save-jlink-argfiles argfile --strip-debug --add-modules jdk.jlink --keep-packaged-modules ./image_a/jmods --output image_a
./image_a/bin/jlink --add-modules java.base --output image_b

It's not very apparent that image_b will have -XX:+UseParallelGC. So you need some sort of track record what you've used previously already in order to know how image_b got produced (short of --save-opts)?

I think this behavior should be documented.

Makes a lot of sense. Where? In the CSR?

jerboaa avatar Nov 15 '23 21:11 jerboaa

Note that plugins like --add-options have been modified so that only the options passed at the current CLI will propagate to the final image. So in this case, image1 would have property com.foo.XYZ set, but not image2. Incidentally, what you probably intended to use was `--add-options "-Dcom.foo.XYZ=true -Dcom.acme.name=BAR".

Having said that, depending on the contents of argfile, those could be equivalent. In fact, they are with --unlock-run-image, and an empty argfile. --unlock-run-image avoids adding the marker file, which is the only difference when we extract the image.

--save-jlink-argfiles brings a strange angle to this discussion, but it's conceivable to get a similarly different image, even with --keep-packaged-modules.

Right. This example intends to show that the behavior is not straight-forward for users to follow and also subject to the implementation of each of the plugins. I think we need an easy-to-understand model for developers to understand. Some possible options:

Option 1: all plugins applied in image1 are auto-applied to image2 by default Option 2: all plugins applied in image1 are not applied to image2 by default

When there is an exception, it should be documented clearly by the plugin (possibly in the output from --list-plugins). I also think option 1 may be more useful to the developers. I'm not sure how many plugins can undo the transformation done in image1 when creating image2.

For example, with option 1,

$ jdk22/bin/jlink --add-modules jdk.compiler,jdk.jlink --output image1 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true"

$ image1/bin/jlink --add-modules jdk.jlink --output image2 --add-options "-Dcom.acme.name=BAR"
# equivalent to:
$ jdk22/bin/jlink --add-modules jdk.jlink --output image2 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true  -Dcom.acme.name=BAR"

$ image1/bin/jlink --add-modules java.base --output image3 --vendor-bug.url https://com.acme/bugs
# equivalent to:
$ jdk22/bin/jlink --add-modules java.base --output image3  --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true" --vendor-bug.url https://com.acme/bugs

Discussion points are:

  • --save-jlink-argfiles is only applicable when jdk.jlink is added to the custom module. I think this one is not an issue.
  • --add-options concatenates the options?
  • -vendor-bug.url https://xyz.com/bugs --vendor-bug.url https://com.acme/bugs last one wins?

We need to go through each plugin and decide on its behavior. I'm also pondering how the Plugin API should support this run-time image based linking.

mlchung avatar Nov 15 '23 22:11 mlchung

Thanks.

How can the user know what plugins are applied to image2? i.e. what is the jlink command to produce image2 if running from jdk22 with the packaged modules present?

The only way to know is by knowing the chain of jlink commands yielding up to the final image. Let jlink' be the jlink using packaged modules. Currently this can be at most two. In addition, the contents of argfile needs to be known. That doesn't seem to be very different to the status quo, though. See below.

Reading the changes, I'm not sure but I think it's not equivalent to:

jdk22/bin/jlink --add-modules jdk.jlink --output image2 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true" --add-options "-Dcom.acme.name=BAR"

Note that plugins like --add-options have been modified so that only the options passed at the current CLI will propagate to the final image. So in this case, image1 would have property com.foo.XYZ set, but not image2. Incidentally, what you probably intended to use was `--add-options "-Dcom.foo.XYZ=true -Dcom.acme.name=BAR".

Having said that, depending on the contents of argfile, those could be equivalent. In fact, they are with --unlock-run-image, and an empty argfile. --unlock-run-image avoids adding the marker file, which is the only difference when we extract the image.

--save-jlink-argfiles brings a strange angle to this discussion, but it's conceivable to get a similarly different image, even with --keep-packaged-modules. Consider:

echo '--add-options=-XX:+UseParallelGC' > argfile
./jdk22/bin/jlink --save-jlink-argfiles argfile --strip-debug --add-modules jdk.jlink --keep-packaged-modules ./image_a/jmods --output image_a
./image_a/bin/jlink --add-modules java.base --output image_b

It's not very apparent that image_b will have -XX:+UseParallelGC. So you need some sort of track record what you've used previously already in order to know how image_b got produced (short of --save-opts)?

I think this behavior should be documented.

Makes a lot of sense. Where? In the CSR?

Note that plugins like --add-options have been modified so that only the options passed at the current CLI will propagate to the final image. So in this case, image1 would have property com.foo.XYZ set, but not image2. Incidentally, what you probably intended to use was --add-options "-Dcom.foo.XYZ=true -Dcom.acme.name=BAR". Having said that, depending on the contents of argfile, those could be equivalent. In fact, they are with --unlock-run-image, and an empty argfile. --unlock-run-imageavoids adding the marker file, which is the only difference when we extract the image.--save-jlink-argfiles` brings a strange angle to this discussion, but it's conceivable to get a similarly different image, even with --keep-packaged-modules.

Right. This example intends to show that the behavior is not straight-forward for users to follow and also subject to the implementation of each of the plugins. I think we need an easy-to-understand model for developers to understand. Some possible options:

Option 1: all plugins applied in image1 are auto-applied to image2 by default

Option 1 seems most appealing. I can massage --add-options to concatenate. The exception of the rule seems --system-modules for obvious reasons.

Option 2: all plugins applied in image1 are not applied to image2 by default

When there is an exception, it should be documented clearly by the plugin (possibly in the output from --list-plugins). I also think option 1 may be more useful to the developers. I'm not sure how many plugins can undo the transformation done in image1 when creating image2.

For example, with option 1,

$ jdk22/bin/jlink --add-modules jdk.compiler,jdk.jlink --output image1 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true"

$ image1/bin/jlink --add-modules jdk.jlink --output image2 --add-options "-Dcom.acme.name=BAR"
# equivalent to:
$ jdk22/bin/jlink --add-modules jdk.jlink --output image2 --vendor-bug.url https://xyz.com/bugs --save-jlink-argfiles argfile --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true  -Dcom.acme.name=BAR"

$ image1/bin/jlink --add-modules java.base --output image3 --vendor-bug.url https://com.acme/bugs
# equivalent to:
$ jdk22/bin/jlink --add-modules java.base --output image3  --generate-jli-classes jli_trace.txt --strip-debug --add-options "-Dcom.foo.XYZ=true" --vendor-bug.url https://com.acme/bugs

Discussion points are:

* `--save-jlink-argfiles` is only applicable when `jdk.jlink` is added to the custom module.  I think this one is not an issue.

For the runtime image link that's a requirement: jdk.jlink part of the image that is being used to create the image to perform the runtime image link. But I agree that this use-case seems rather expert.

* `--add-options` concatenates the options?

Sure, that can be done.

* `-vendor-bug.url https://xyz.com/bugs --vendor-bug.url https://com.acme/bugs` last one wins?

Yes. That's also how it works if the build got configured with specific vendor and then a jlink is being performed using packaged modules.

We need to go through each plugin and decide on its behavior.

OK. I'll add documentation to the --list-plugins help should there be deviations.

I'm also pondering how the Plugin API should support this run-time image based linking.

It could, but doesn't need to IMO. OTOH, transform() could grow an argument to indicate packaged-modules vs runtime image link.

jerboaa avatar Nov 16 '23 18:11 jerboaa

We need to go through each plugin and decide on its behavior.

OK. I'll add documentation to the --list-plugins help should there be deviations.

It'd be helpful if you write down your proposed behavior for each plugin for discussion. Otherwise, we will have to find out from the code.

I'm also pondering how the Plugin API should support this run-time image based linking.

It could, but doesn't need to IMO. OTOH, transform() could grow an argument to indicate packaged-modules vs runtime image link.

I'm not sure if it needs the extra argument. As the plugin knows what files it adds, it can always check its existence as the current implementation is doing. What I'm thinking if the plugin will need to indicate if it'd concatenate, retain or drop the transformation from image1 when creating `image2. This will get the plugin author to consider that when the plugin is developed.

Regarding the name of the runimage_resources file, this file is only used by jlink and so it can be a resource file in jdk.jlink module like jdk.jlink/jdk/tools/jlink/internal/runtime/$MODULE_resources (e.g. jdk.jlink/jdk/tools/jlink/internal/runtime/java.base_resources)

mlchung avatar Nov 16 '23 19:11 mlchung

@mlchung Just as an FYI, I'm working on it. Thanks!

jerboaa avatar Nov 20 '23 15:11 jerboaa

It'd be helpful if you write down your proposed behavior for each plugin for discussion. Otherwise, we will have to find out from the code.

Here it goes. This was a very useful exercise and uncovered some bugs. Fundamentally, each plugin's Category is what I was looking at.

Unique categories (for pre-existing plug-ins):

  • FILTER
  • TRANSFORMER
  • ADDER
  • METADATA_ADDER
  • SORTER
  • PROCESSOR
  • COMPRESSOR

SORTER, PROCESSOR and COMPRESSOR. Those plugins affect the final image only so they work the same as when using packaged modules. There is nothing to leak from a previous link as the output directory will contain a new JDK image. Note that classes.jsa and classes_nocoops.jsa are not part of the jmod files, nor are they classes or resources in the jimage. Thus, they are not tracked with add-run-image-resources and don't end up in the final JDK image when performing a run-time based link.

ADDER, METADATA_ADDER plugins add files to the final jimage and/or JDK image ('release' file), which aren't there without those plugins. They get appropriately filtered at link time, so there isn't any oberservable difference. Exception: save-jlink-arg-file. The arg files are processed too early so they carry forward for the link, but not into the final image of that link. Therefore I've marked them as equivalent.

FILTER, TRANSFORMER. Those change class files or native resources or exclude specific resources. Since those changes are then in effect in the resulting runtime image, and the link is performed from such an image, they carry over to the derived image. Certain transformers can be overridden by the final run-time image based link (e.g. vendor-version plugin). Filters remove things from the image, so those changes carry forward. Exceptions: system-modules and generate-jli-classes. Both behave the same as in packaged-modules case.

For each individual plug-in the planned behaviour is in the "Current behaviour in run-time image link mode" column.

Plugin name                 | Description                                        | Current behaviour in run-time  | Notes
                            |                                                    | image link mode                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
add-options                 |Prepend the specified <options> string, which may   | Same as with packaged-modules. | Category: ADDER
                            |include whitespace, before any other options when   | /java.base/jdk/internal/vm/    |
                            |invoking the virtual machine in the resulting       | options file is being filtered.|
                            |image.                                              |                                | Adds a file in jimage:
                            |                                                    |                                | /java.base/jdk/internal/vm/options
-------------------------------------------------------------------------------------------------------------------------------------------------------------
compress                    |Compression to use in compressing resources:        | Same as with packaged-modules  | Category: COMPRESSOR
                            |Accepted values are:                                |                                | 
                            |zip-[0-9], where zip-0 provides no compression,     |                                | Combination of 'zip'
                            |and zip-9 provides the best compression.            |                                | and 'compact-cp'
                            |Default is zip-6.                                   |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
dedup-legal-notices         |De-duplicate all legal notices.                     | Accumulate with base run-time  |
                            |If error-if-not-same-content is specified then      | image (if any).                |Category: TRANSFORMER 
                            |it will be an error if two files of the same        |                                |
                            |filename are different.                             |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
exclude-files               |                                                    | Accumulate with base run-time  | Category: FILTER
                            | Specify files to exclude.                          | image (if any).                |
                            | e.g.: **.java,glob:/java.base/lib/client/**        |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
exclude-jmod-section        |                                                    | Accumulate with base run-time  | Category: FILTER
                            |Specify a JMOD section to exclude.                  | image (if any).                |
                            |Where <section-name> is "man" or "headers".         |                                | Excludes resources of type man/header
-------------------------------------------------------------------------------------------------------------------------------------------------------------
exclude-resources           |Specify resources to exclude.                       | Accumulate with base run-time  | Category: FILTER
                            |e.g.: **.jcov,glob:**/META-INF/**                   | image (if any).                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
generate-cds-archive        |Generate CDS archive if the runtime image supports  | Same as with packaged-modules  | Category: PROCESSOR
                            |the CDS feature.                                    |                                | Generates classes.jsa classes_nocoops.jsa
                            |                                                    |                                | in $JAVA_HOME
-------------------------------------------------------------------------------------------------------------------------------------------------------------
generate-jli-classes        |Specify a file listing the java.lang.invoke         | Same as with packaged-modules  | Category: TRANSFORMER
                            |classes to pre-generate. By default, this plugin    |                                |  
                            |may use a builtin list of classes to pre-generate.  | Potential existing BMH.Species |
                            |If this plugin runs on a different runtime version  | classes are filtered to match  | Generates BoundMethodHandle$Species*
                            |than the image being created then code generation   | java.base jmod                 | classes.
                            |will be disabled by default to guarantee            |                                |
                            |correctness add ignore-version=true                 |                                |
                            |to override this.                                   |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
include-locales             |BCP 47 language tags separated by a comma,          | Accumulate with base run-time  | Category: FILTER
                            |allowing                                            | image (if any).                |
                            |locale matching defined in RFC 4647.                |                                | Filters specific locales in the target
                            |e.g.: en,ja,*-IN                                    |                                | image.
-------------------------------------------------------------------------------------------------------------------------------------------------------------
order-resources             |Order resources.                                    | Same as with packaged-modules  | Category: SORTER
                            |e.g.: **/module-info.class,@classlist,              |                                |
                            |/java.base/java/lang/**                             |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
release-info                |<file> option is to load release properties from    | Same as with packaged-modules  | Category: METAINFO_ADDER
                            |the supplied file.                                  |                                |
                            |add: is to add properties to the release file.      |                                | Adds a file 'release' to the final image
                            |Any number of <key>=<value> pairs can be passed.    |                                | in the top folder. Since that file is not 
                            |del: is to delete the list of keys in release file. |                                | in packaged modules nor in the jimage, 
                            |                                                    |                                | it doesn't get carried forward
-------------------------------------------------------------------------------------------------------------------------------------------------------------
save-jlink-argfiles         |Save the specified argument files that contain      | If specified, options in an    | Category: ADDER
                            |the arguments to be prepended to the execution of   | existing file are replaced by  |
                            |jlink in the output image. <filenames> is a         | the new options. Otherwise,    | Adds a file to the jdk.jlink module,
                            |: (; on Windows) separated list of command-line     | options from the base image    | /jdk.jlink/jdk/tools/jlink/internal/options
                            |argument files.                                     | affect the run, but don't      | 
                            |                                                    | carry forward.                 | 
-------------------------------------------------------------------------------------------------------------------------------------------------------------
strip-debug                 |Strip debug information from the output image       | Accumulate with base run-time  | Category: TRANSFORMER
                            |                                                    | image (if any).                | 'strip-java-debug-attributes' and
                            |                                                    |                                | 'strip-native-debug-symbols' combined
-------------------------------------------------------------------------------------------------------------------------------------------------------------
strip-java-debug-attributes |Strip Java debug attributes from                    | Accumulate with base run-time  | Category: TRANSFORMER
                            |classes in the output image                         | image (if any).                |                                      
-------------------------------------------------------------------------------------------------------------------------------------------------------------
strip-native-commands       |Exclude native commands (such as java/java.exe)     | Accumulate with base run-time  | Category: FILTER
                            |from the image.                                     | image (if any).                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
strip-native-debug-symbols  |Strip debug symbols from native libraries (if any). | Accumulate with base run-time  | Category: TRANSFORMER
                            |This plugin requires at least one option:           | image (if any).                |
                            |   objcopy: The path to the objcopy binary.         |                                |
                            |            Defaults to objcopy in PATH.            |                                |
                            |   exclude-debuginfo-files: Exclude debug info      |                                |
                            |            files. Defaults to true.                |                                |
                            |   keep-debuginfo-files[=<ext>]: Keep debug info    |                                |
                            |            files in <file>.<ext>.                  |                                |
                            |   Defaults to <file>.debuginfo                     |                                |
                            |Examples: --strip-native-debug-symbols              |                                |
                            |            keep-debuginfo-files:objcopy=OBJPATH    |                                |
                            |   --strip-native-debug-symbols                     |                                |
                            |            exclude-debuginfo-files                 |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
system-modules              |The batch size specifies the maximum number of      | Same as with packaged modules. | Category: TRANSFORMER
                            |modules be handled in one method to workaround if   |                                |
                            |the generated bytecode exceeds the method size      | Generated classes get filtered | Changes SystemModulesMap.class and adds
                            |limit. The default batch size is 75.                | so they don't populate.        | SystemModules${<N>,all,default}.class
-------------------------------------------------------------------------------------------------------------------------------------------------------------
vendor-bug-url              |Override the vendor bug URL baked into the build.   | Accumulate with base run-time  | Category: TRANSFORMER
                            |The value of the system property                    | image (if any).                |
                            |"java.vendor.url.bug" will be <vendor-url-bug>.     |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
vendor-version              |Override the vendor version string baked into the   | Accumulate with base run-time  | Category: TRANSFORMER
                            |build,if any. The value of the system property      | image (if any).                |
                            |"java.vendor.version" will be <vendor-version>.     |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
vendor-vm-bug-url           |Override the vendor VM bug URL baked                | Accumulate with base run-time  | Category: TRANSFORMER
                            |into the build.  The URL displayed in VM error      | image (if any).                |
                            |logs will be <vendor-vm-bug-url>.                   |                                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
vm                          |Select the HotSpot VM in the output image.          | Accumulate with base run-time  | Category: FILTER
                            |Default is all                                      | image (if any).                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Regarding the name of the runimage_resources file, this file is only used by jlink and so it can be a resource file in jdk.jlink module like jdk.jlink/jdk/tools/jlink/internal/runtime/$MODULE_resources (e.g. jdk.jlink/jdk/tools/jlink/internal/runtime/java.base_resources)

That's a good observation. Thanks. I've modified the patch and CSR to mention that. Those resource files now live in /jdk.jlink/jdk/tools/jlink/internal/runlink_$MODULE_resources.

The option --unlock-run-image to get equivalence between a link using packaged modules and run-time based link is now hidden (similar to --keep-packaged-modules). This is really advanced usage and doesn't need a prominent place in jlink --help.

Other things of note:

jlink orders plugin's by their Category. So in general, the processing pipeline is: FILTER->ADDER->TRANSFORMER->MODULEINFO_TRANSFORMER->SORTER->METAINFO_ADDER->COMPRESSOR->VERIFIER->PROCESSOR->PACKAGER. In this updated patch I've used this info in order to re-establish the invariant of certain classes and resources not being in packaged modules. Things like SystemModules$*.class and BMH$Species_*.class. Those are now being filtered (using exclude-resource) prior it being processed by the TRANSFORMER or ADDER phases. Furthermore, it prevents those classes to populate if plug-ins that generated them aren't used. This also removes the need to actually modify any of the existing plugins.

More thoughts?

jerboaa avatar Nov 23 '23 18:11 jerboaa