Skip to content

Experimental support for layered images #719

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

melix
Copy link
Collaborator

@melix melix commented Apr 23, 2025

This commit introduces a Gradle DSL to support layered images creation. As of now, this is mainly aimed towards a single use case which is incremental builds. The test project demonstrates how to use the DSL to create a base layer which includes the JDK "java.base" module as well as all external dependencies used by the project.

The DSL builds on top of the binaries concept, by allowing them to declare either that they produce a layer, or that they use one or more layers. The DSL contains methods to make it easier to declare use or creation, as well as supports an easy way to declare that a layer should use only external dependencies. For example, this is how you would create a base layer and consume it from the main binary:

graalvmNative {
    binaries {
        libdependencies {
            createLayer {
                modules = ["java.base"]
                jars.from(externalDependenciesOf(configurations.runtimeClasspath))
            }
        }
        main {
            useLayer("libdependencies")
        }
    }
}

Note that there is a binary named libdependencies, and as soon as the createLayer is called, it will offer additional options which are specific to layers (for example declaring the list of packages or modules).

The DSL to create a layer contains the packages option, which could be used with automatic extraction of package names, which is why there is code to extract packages from jars, however, this code is currently unused for a reason: these packages can contain dependencies to "optional" modules, which cannot be figured out at build time. Typically, logback will support additional modules and load them dynamically, and if the package is included in the list and that the supporting dependencies are not on classpath, then the layer creation would fail. Therefore, the only reliable option right now is to use the jars property to set the list of jars which should belong to the layer.

@melix melix added the gradle-plugin Related to Gradle plugin label Apr 23, 2025
@melix melix requested a review from cstancu April 23, 2025 14:08
@melix melix self-assigned this Apr 23, 2025
@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Apr 23, 2025
melix added 2 commits May 5, 2025 10:54
This commit introduces a Gradle DSL to support layered images creation.
As of now, this is mainly aimed towards a single use case which is incremental builds.
The test project demonstrates how to use the DSL to create a base layer which includes
the JDK "java.base" module as well as all external dependencies used by the project.

The DSL builds on top of the binaries concept, by allowing them to declare either
that they produce a layer, or that they use one or more layers. The DSL contains
methods to make it easier to declare use or creation, as well as supports an easy
way to declare that a layer should use only external dependencies. For example,
this is how you would create a base layer and consume it from the main binary:

```
graalvmNative {
    binaries {
        libdependencies {
            createLayer {
                modules = ["java.base"]
                jars.from(externalDependenciesOf(configurations.runtimeClasspath))
            }
        }
        main {
            useLayer("libdependencies")
        }
    }
}
```

Note that there is a _binary_ named `libdependencies`, and as soon
as the `createLayer` is called, it will offer additional options which are
specific to layers (for example declaring the list of packages or modules).

The DSL to create a layer contains the `packages` option, which could be
used with automatic extraction of package names, which is why there is
code to extract packages from jars, however, this code is currently
unused for a reason: these packages can contain dependencies to "optional"
modules, which cannot be figured out at build time. Typically, logback
will support additional modules and load them dynamically, and if the
package is included in the list and that the supporting dependencies
are not on classpath, then the layer creation would fail. Therefore,
the only reliable option right now is to use the `jars` property to
set the list of jars which should belong to the layer.
@melix melix force-pushed the cc/layered-images branch from b1463f1 to 1ecb3a8 Compare May 5, 2025 09:08
Windows uses the argFile by default, which highlighted a bug: the
arg file was written in the output directory, which was cleaned
before running the task (cleaning is necessary or we'd have stale
files and up-to-date checking would be broken).

The arg file is now written in the temp directory instead.
@melix melix changed the title [WIP] Experimental support for layered images Experimental support for layered images May 7, 2025
@wirthi wirthi requested review from vjovanov and dnestoro May 7, 2025 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
gradle-plugin Related to Gradle plugin OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant