5

Having a Spring Boot app I tried to build it using the spring-boot-maven-plugin goal mvn spring-boot:build-image. But the build fails downloading the bellsoft-jre11.0.9.1+1-linux-amd64.tar.gz from github.com, since I don't have access to it from my build pipeline:

...
Paketo BellSoft Liberica Buildpack 5.2.1
  https://github.com/paketo-buildpacks/bellsoft-liberica
  Build Configuration:
    $BP_JVM_VERSION              11.0.9          the Java version
  Launch Configuration:
    $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
    $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
    $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
    $JAVA_TOOL_OPTIONS                           the JVM launch flags
  BellSoft Liberica JDK 11.0.9: Contributing to layer
    Downloading from https://github.com/bell-sw/Liberica/releases/download/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz
unable to invoke layer creator
unable to get dependency jdk
unable to download https://github.com/bell-sw/Liberica/releases/download/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz
unable to request https://github.com/bell-sw/Liberica/releases/download/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz
ERROR: failed to build: exit status 1

Is there a way I can download the bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz to a location accessible to my build pipeline and configure the bellsoft-liberica buildpack to use this instead?

jonashackt
  • 12,022
  • 5
  • 67
  • 124

5 Answers5

16

According to the docs:

Paketo Buildpacks may download dependencies from the internet. For example, the Java Buildpack will download the BellSoft Liberica JRE from the Liberica github releases by default. If a dependency URI is inaccessible from the build environment, a binding can be used to map a new URI to a given dependency.

Configuring bindings using the spring-boot-maven-plugin (or the Gradle plugin) requires Spring Boot 2.5+. If you are on an older version, you need to upgrade or switch over to pack CLI.

=== Use pack CLI with bindings to configure a different JDK download uri ===

The pack docs tell us about the general layout of a binding directory (/platform/bindings is later created inside the pack build container):

/chooseYourBindingsName
├── key-name-of-our-buildpacks-binding-configuration
└── type-name-of-our-buildpacks-binding-configuration

1. Create bindings directory

So let's try to create a fully running example! In order to hand over the binding configuration to pack CLI we need to create a directory first:

mkdir bellsoft-jdk-config && cd bellsoft-jdk-config

2. Create file type, containing the binding key

Now we need to create a file called type inside this directory containing the binding key for the bellsoft-liberica binding type dependency-mapping:

echo "dependency-mapping" >> type

A new file type should be present in the directory containing the string dependency-mapping.

3. Choose JDK version from buildpack.toml

As we want to change the bellsoft-liberica's download uri of the JDK, we need to decide which JDK version we exaclty want to use. The bellsoft-liberica buildpack's buildpack.toml gives an overview on which JRE/JDK versions are available inside the buildpack. For this example here I used the latest JDK version 11 which is configured inside the buildpack.toml like this:

...

[[metadata.dependencies]]
id      = "jdk"
name    = "BellSoft Liberica JDK"
version = "11.0.9"
uri     = "https://github.com/bell-sw/Liberica/releases/download/11.0.9.1+1/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz"
sha256  = "786c48fa6429d6a3f0afb189a65f0a43772e42afbab836852b9a1fdfdb8fc502"
stacks  = [ "io.buildpacks.stacks.bionic", "org.cloudfoundry.stacks.cflinuxfs3" ]
...

4. Download JDK

Having decided on the version, we need to download the JDK from the location provided inside the uri field to a location we have access to later inside our build environment (since we don't have access to github.com). Let's assume, we have the JDK downloaded and available at http://your-accessible-uri-to/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz.

5. Create file named as the sha256, containing the JDK uri

Now we should create another file named exactly according to the sha256 digest value of the [[metadata.dependencies]] section of the JDK version we chose inside the buildpack.toml. This file must contain the uri of our downloaded JDK:

echo "http://your-accessible-uri-to/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz" >> 786c48fa6429d6a3f0afb189a65f0a43772e42afbab836852b9a1fdfdb8fc502

In the end our directory bellsoft-jdk-config should comply to the pack CLI bindings directory docs and looks somehow like this:

/bellsoft-jdk-config
├── 786c48fa6429d6a3f0afb189a65f0a43772e42afbab836852b9a1fdfdb8fc502
└── type

6. Execute pack CLI with --volume for binding & BP_JVM_VERSION

Finally we can issue our pack CLI command. Ensure that pack CLI is installed on your system. Be also sure to also provide the exact JDK version number using the --env BP_JVM_VERSION=exactJDKversionNumberHere environment variable configuration, which matches your downloaded JDK version and the section in the buildpack.toml:

pack build your-application-name-here \
    --path . \
    --volume $(pwd)/bellsoft-jdk-config:/platform/bindings/bellsoft-jdk-config \
    --env BP_JVM_VERSION=11.0.9 \
    --builder paketobuildpacks/builder:base

Now the bellsoft-liberica buildpack will download the JDK tar.gz from http://your-accessible-uri-to/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz:

...
Paketo BellSoft Liberica Buildpack 5.2.1
  https://github.com/paketo-buildpacks/bellsoft-liberica
  Build Configuration:
    $BP_JVM_VERSION              11.0.9          the Java version
  Launch Configuration:
    $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
    $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
    $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
    $JAVA_TOOL_OPTIONS                           the JVM launch flags
  BellSoft Liberica JDK 11.0.9: Contributing to layer
    Downloading from http://your-accessible-uri-to/bellsoft-jdk11.0.9.1+1-linux-amd64.tar.gz 
...
Daniel Mikusa
  • 13,716
  • 1
  • 22
  • 28
jonashackt
  • 12,022
  • 5
  • 67
  • 124
  • What should the permissions be for type file and actual files? I am using it through spring-boot bootBuildImage (gradle plugin) and I am getting `failed to load bindings from '/platform/bindings': failed to read binding 'ca-certificates': missing 'type'` – theo Sep 08 '22 at 06:34
  • Did you create the `type` file mentioned in step 2. via `echo "dependency-mapping" >> type` inside the directory you created in step 1.? – jonashackt Sep 08 '22 at 13:46
  • for my case it is `ca-certificates` I am trying to load so yeah I did `echo "ca-certificates" >> type` – theo Sep 08 '22 at 13:52
2

I create bindings:

/bindings/bellsoft-jdk-config
├── 786c48fa6429d6a3f0afb189a65f0a43772e42afbab836852b9a1fdfdb8fc502
├── a3092627b082cb3cdbbe4b255d35687126aa604e6b613dcda33be9f7e1277162
├── be27df8838a6d069a2212de5f46da4e39f33f087f2e77c8a725d0f7ec8b5273e
├── d9ff2d84528a2154ff669b85e6dbdee7f244194dcc64e0a8a1bedc470b3bcf56
└── type

Then created a Dockerfile that copies these bindings and builds a new platform based on the previous one:

FROM paketobuildpacks/builder:0.0.464-base-platform-api-0.3
 
COPY bindings /platform/bindings
 
CMD ["/bin/bash"]
docker build -t your-repo-url/java-builder-test:1 .
docker push your-repo-url/java-builder-test:1

then I configured the spring plugin to use this platform:

<configuration>
    <imageBuilder>your-repo-url/java-builder-test:1</imageBuilder>
    <layers>
        <enabled>true</enabled>
    </layers>
    <image>
        <name>your-repo-url/${project.artifactId}:${project.version}</name>
    </image>
</configuration>

This workaround worked, but you have to use correct directory permission.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • I didn't try this approach, since Paketo/Cloud Native Buildpacks aim to free you from the need to write your own `Dockerfile` - so I would advice you to go with `pack CLI`. I have a working example on TravisCI - see https://github.com/jonashackt/spring-boot-buildpack/blob/main/.travis.yml You should be able to adapt this to your CI system. It doesn't use bindings, but I described this [in my answer](https://stackoverflow.com/a/65212256/4964553). – jonashackt Dec 21 '20 at 08:06
0

I changed my Java version in pom.xml to 17:

<properties>
    <java.version>17</java.version>
    <spring-cloud.version>2020.0.2</spring-cloud.version>
</properties>
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
0

I changed the java version in pom.xml file to 17 and it worked!

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 04 '22 at 07:23
0

Change the Java version in pom.xml and it will work. i have changed it to java 17. and it worked for me.