Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8333799

Linking Run-Time Images without JMODs

XMLWordPrintable

    • Icon: JEP JEP
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • tools
    • None
    • Severin Gehwolf
    • Feature
    • Open
    • JDK
    • core dash libs dash dev at openjdk dot org
    • M
    • M

      Summary

      Reduce the size of the JDK by approximately 25% by enabling the jlink tool to create custom run-time images without having to include copies of the packaged JDK modules in the jmods directory.

      Non-Goals

      • It is not a goal at this time to make the JDK build time option the default.

      Motivation

      The installed size of the JDK on the file system is important in cloud environments, where container images that include an installed JDK are automatically and frequently copied over the network from container registries. Reducing the size of the JDK would improve the efficiency of these operations.

      When looking at the on-disk-size of a JDK installation we can see that the jmods directory takes up approximately 25% of the total installed size on the file system.

      The following output with the Linux du ("disk usage") command line tool gives a sense of the size of the top two directories. Actual sizes will vary by platform and JDK vendor; in the sample output, the total size on the file system is 352MB.

      $ du -sh jdk
      352M jdk
      
      $ du -s jdk/* | sort -n | tail -n2
      87828    jdk/jmods
      269784   jdk/lib

      While the lib directory is the largest contributor (~264MB), almost all files in the lib folder are needed at run-time. The second largest contributor to the on-disk-size of the JDK is the jmods folder: ~85MB of ~352MB in total. This amounts to about 25% of the total size.

      The jmods directory are files needed for running jlink in order to create custom run-time images. The directory contains a "packaged module", in JMOD format, for each standard module and each JDK-specific module in the run-time image. JMOD is a packaging format, like the JAR format, except that it additionally supports native code, configuration files and other resources. Unlike the JAR format, the JMOD format is not an executable format, the JDK does not load classes from jmod files, and you can not put jmod files on the java launcher's class path or module path.

      What's more, the content of files in the jmods directory duplicate what is already present in the JDK image. The following example shows this for the java.lang.String class by extracting content from the jdk/lib/modules file and comparing it to the version in the java.base.jmod file. They are identical:

      $ ./jdk/bin/jimage extract --dir ./extracted ./jdk/lib/modules
      $ ./jdk/bin/jmod extract --dir java.base-extracted ./jdk/jmods/java.base.jmod
      $ diff java.base-extracted/classes/java/lang/String.class ./extracted/java.base/java/lang/String.class

      The jdk/lib/modules file contains the class files and resources for all modules in the run-time image. When an application runs, this is where the JDK loads the class files for java.lang.Object, java.lang.String and other classes in the java.* and jdk.* modules.

      Similarly, native libraries of the JVM are present in the JMOD files and the installed JDK image:

      $ ls jdk/lib/server/libjvm.so 
      jdk/lib/server/libjvm.so
      $ ./jdk/bin/jmod list ./jdk/jmods/java.base.jmod | grep libjvm.so
      lib/server/libjvm.so

      In summary we have:

      • The jmods directory contributes a significant amount of on-disk-size as compared to the total JDK installation size: approximately 25%.
      • Files in the jmods directory are used only by jlink when creating custom run-time images, but aren't used at application run-time.
      • Yet, files in the jmods directory duplicate content available elsewhere in the installed JDK image.

      It would greatly benefit the size of the JDK if the jlink tool did not require jmod files in the JDK run-time image and instead copied or reconstituted the class files, native code, and other resources from the run-time image itself.

      Description

      The new JDK build-time configuration option --enable-linkable-runtime builds a JDK whose jlink tool can create run-time images without using the jmods directory. When using this configuration option, no jmods directory will be created in the resulting JDK image.

      $ configure [..other options..] --enable-linkable-runtime
      $ make images

      The resulting JDK is approximately 25% smaller on the file system when compared to the JDK that is built with the default configuration. The JDK contains exactly the same set of modules as the JDK created with the default configuration.

      The jlink tool works exactly the same way as the jlink tool in a JDK created with the default configuration. For example, to create a run-time image containing only the java.xml and java.base module the jlink invocation works the same:

      $ jlink --add-modules java.xml --output myimage
      Linking based on the current run-time image.
      
      $ myimage/bin/java --list-modules
      java.base@24
      java.xml@24

      A further example creates a run-time image containing an application module named "app" that requires a library named "lib". These modules are packaged as modular JAR files in the mlib directory. The location of application modules linked into a custom run-time image need to be specified with the --module-path option as those modules wouldn't be present in the installed JDK image. JDK-specific modules will be linked from the installed run-time image.

      $ ls mlib
      app.jar lib.jar
      
      $ jlink --module-path mlib --add-modules app --output app
      Linking based on the current run-time image.
      $ app/bin/java --list-modules
      app
      lib
      java.base@24

      In this example, the class files and resources for modules "app" and "lib" are copied from the modular JAR files. The class files, native code, java launcher, and configuration files are copied from the JDK run-time image.

      Restrictions

      The jlink tool in a JDK build that was configured with --enable-linkable-runtime has a few limitations when compared to the jlink tool in a JDK build created with the default configuration:

      • jlink cannot be used to create a run-time image that itself contains the jlink tool. The jlink tool is in the jdk.jlink module and the following fails:

        $ jlink --add-modules jdk.jlink --output image
        Error: This JDK does not contain packaged modules and cannot be used to create another run-time image that includes the jdk.jlink module.

        This restriction may be re-visited in the future if it proves problematic.

      • jlink fails if user-editable configuration is modified. The JDK conf directory contains .properties and other files that a developer may edit to configure the JDK. One example is conf/security/java.security which contains the configuration for security providers, algorithms and more. With the default build, the user-editable configuration files for the java.* and jdk.* modules are copied from the packaged modules (the jmod files). Without the packaged modules, the configuration files are copied from the run-time image and jlink fails if any of the files are different from the original files.

        $ jlink --add-modules java.xml --output image
        Linking based on the current run-time image.
        Error: [...]/bin/conf/security/java.security has been modified.

        This restriction is necessary to prevent jlink creating a run-time image with ad hoc or insecure configuration. If the security configuration is changed, e.g. changed to enable an obsolete message digest algorithm that is disabled by default, then it would be inappropriate to copy this configuration to the new run-time image.

      • Cross-linking, e.g., running jlink on Linux x64 to create a run-time image for Windows x64, is no longer possible.

      Future Work

      Future work may remove some or all of the restrictions listed above.

      A future JEP may propose --enable-linkable-runtime be the default when building the JDK, thereby providing the benefit of smaller size on the file system to all distributions.

      Alternatives

      Provide the jmod files as a separate download. A number of Linux distributions already provide an OS installation package for the JDK that does not include the jmods directory. A separate OS installation package adds the .jmod files. This approach means that jlink tool fails if the separate OS installation package has not been downloaded and installed. It gets more difficult with container images that have the JDK installed but require a later step to install the separate OS installation package in order to use jlink.

            mr Mark Reinhold
            sgehwolf Severin Gehwolf
            Severin Gehwolf Severin Gehwolf
            Alan Bateman, Mandy Chung
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: