Learn how to push your Java app to VMware Tanzu Application Service for VMs (TAS for VMs) and how to configure your app to use the Java Native Image Buildpack. VMware discourages using the Java Native Image Buildpack with production workloads while it is in beta.

Building using Cloud Native Buildpacks

Cloud Native Buildpacks include support for building native image apps. You can pass in your source code or a compiled JAR and Cloud Native Buildpacks installs the required tools and builds a compatible image.

Using Cloud Native Buildpacks example

  1. Clone the example repository from GitHub:

    git clone https://github.com/paketo-buildpacks/samples
    cd samples/java/native-image/java-native-image-sample
    
  2. Build the example image:

    ./mvnw package
    pack build apps/native-image -p target/demo-0.0.1-SNAPSHOT.jar -e BP_NATIVE_IMAGE=true -B paketobuildpacks/builder:tiny
    

For more information about building with Cloud Native Buildpacks, see Getting Started in the Spring Native documentation.

Deploying using Cloud Native Buildpacks

This section describes how to deploy a Java app with native image support using Cloud Native Buildpacks.

To deploy an app compiled using the steps from the previous section to TAS for VMs, you can deploy the image directly using TAS for VMs’s Docker support. If Docker support is deactivated, you can extract the native image binary from the container image and deploy the app using the binary buildpack.

Deploying from an image

To deploy the app from an image:

  1. Publish your image. You can do this in a number of ways. For example, you can use the --publish flag to pack build with docker tag and docker push, or through any other means of publishing a container image to a registry.

  2. Validate that your foundation supports deploying Docker images by running the following command and confirming that diego_docker is set to enabled. If it is set to disabled, you cannot use this deployment option.

    cf feature-flags
    

    For example:

    $ cf feature-flags
    Retrieving status of all flagged features as [email protected]...
    
    features                                      state
    user_org_creation                             disabled
    private_domain_creation                       enabled
    app_bits_upload                               enabled
    app_scaling                                   enabled
    route_creation                                enabled
    service_instance_creation                     enabled
    diego_docker                                  enabled
    set_roles_by_username                         enabled
    unset_roles_by_username                       enabled
    task_creation                                 enabled
    env_var_visibility                            enabled
    space_scoped_private_broker_creation          enabled
    space_developer_env_var_visibility            enabled
    service_instance_sharing                      enabled
    hide_marketplace_from_unauthenticated_users   disabled
    resource_matching                             enabled
    
  3. Push your app by running:

    cf push -o registry.example.com/apps/native-image native-image-app
    

Extracting the image and deploy the Binary buildpack

To extract and deploy your app using the binary buildpack:

  1. Create a script to extract the files:

    #!/bin/bash
    
    if [ -z "$1" ] || [ -z "$2" ]; then
        echo "USAGE: extract.sh image-name full-main-class"
        echo
        exit 1
    fi
    
    CONTAINER_ID=$(docker create "$1")
    mkdir -p ./out
    docker cp "$CONTAINER_ID:/workspace/$2" "./out/$2"
    docker rm "$CONTAINER_ID" > /dev/null
    

    This script is optional, but illustrates the process of extracting the binary file. It runs docker create and docker cp to extract the file from the image, followed by docker rm to remove the containerd. You can do this manually, or you can use any other tools for interacting with a container image.

  2. Run the extract script:

    $ ./extract.sh apps/native-image io.paketo.demo.Demoapp
    $ file ./out/io.paketo.demo.Demoapp
    io.paketo.demo.Demoapp: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=05cb81992f3859c9653a9ef6a691e798a9c48b9b, with debug_info, not stripped
    

    The extract script places the binary in a directory called out under the current working directory. You can run file to examine it and confirm that it is a 64-bit Linux executable.

  3. Push and run the compiled binary by running the following command. You can adjust other properties or use a manifest.yml file to deploy as well.

    cf push -b binary_buildpack -m 256M -p ./out -c ./io.paketo.demo.Demoapp native-image
    

Push an app using the Java Native Image Buildpack

Follow these procedures to use the Java Native Image Buildpack.

Deploy Java apps

The Java Native Image Buildpack is based on the Paketo Java Native Image Buildpack. The Paketo Documentation for the Buildpack describes how to push your Java app.

For more in-depth documentation, see the Tanzu documentation for the Java Native Image Buildpack.

To push an app with the Java Native Image Buildpack, you must follow these steps:

  1. Push the app code without starting the app, and configure a high-memory value.

    cf push myApp \
      -b java_native_image_cnb_beta -s tanzu-jammy-full-stack \
      --no-start -m 8G
    

    Before you can stage the app, you must set the environment variables. Additionally, the buildpack uses a lot of memory.

  2. Set the memory value to at least 4 GB but ideally 8 GB of memory.

  3. Set this required environment variable for Java Native Image applications.

    cf set-env myApp BP_NATIVE_IMAGE true
    

    Depending on the specifics for the app, other environment variables might be required.

  4. Start the app:

    cf start myApp
    

The following examples are based on common use cases.

Deploy Spring Boot 3.0.x apps

During step 2, you set the BP_NATIVE_IMAGE environment variable. You might also set the following variables:

cf set-env myApp BP_MAVEN_BUILD_ARGUMENTS \
"-Dmaven.test.skip=true --no-transfer-progress package -Pnative"
cf set-env myApp BP_JVM_VERSION 17

Deploy Spring Boot 3.1.x apps

During step 2, you set the BP_NATIVE_IMAGE environment variable. You might also set the following variable:

cf set-env myApp BP_MAVEN_ACTIVE_PROFILES native

Deploy Spring Boot apps with Gradle

No additional environment variables are necessary to deploy Spring Boot apps with Gradle.

Deploy Quarkus apps

During step 2, you set the BP_NATIVE_IMAGE environment variable. You might also set the following variables:

cf set-env myApp BP_MAVEN_BUILD_ARGUMENTS "-Dquarkus.package.type=native-sources \
-Dmaven.test.skip=true package"
cf set-env myApp BP_MAVEN_BUILT_ARTIFACT "target/native-sources"
cf set-env myApp BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE= native-sources/native-image.args"
cf set-env myApp BP_NATIVE_IMAGE_BUILT_ARTIFACT "<PATH-TO-JAR-FILE>"
cf set-env myApp BP_JVM_VERSION=17

Supported versions

This version of TAS for VMs supports Java Native Image CNB 7.6.1.

Help and support

Join the #buildpacks channel in our Slack community if you need help.

check-circle-line exclamation-circle-line close-line
Scroll to top icon