---
title: Tanzu Application Platform 1.7でJava 21を使用するメモ
tags: ["Kubernetes", "Tanzu Build Service", "Tanzu", "TAP", "kpack"]
categories: ["Dev", "CaaS", "Kubernetes", "TAP"]
date: 2023-12-02T23:35:10Z
updated: 2023-12-02T23:36:58Z
---

[前記事](/entries/773)で、Tanzu Application Platformで特定のBuildpackだけ更新する方法を紹介しました。


TAP 1.7ではJava 21に対応したBuildpackがまだサポートされていません。一方、Java 21に対応した [tanzu java buildpack 9.13.0](https://network.tanzu.vmware.com/products/tanzu-java-buildpack#/releases/1423990) が2023-12-01にリリースされました。

<img width="1498" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/04dcd279-42a5-409e-aa65-cacfc242e033">

ということで、TAP 1.7でこのtanzu java buildpack 9.13.0を使って、Java 21対応をしたいと思います。

TAP 1.7.1では次のような `ClusterBuildpack` がインストールされます。tanzu java buildpackのバージョンは[9.11.0](https://docs.vmware.com/en/VMware-Tanzu-Buildpacks/services/tanzu-buildpacks/GUID-release-notes-tanzu-java-v9-11-0.html)です。

```
$ kubectl get clusterbuildpack
NAME                      READY
dotnet-core-2.8.2         True
go-2.2.2                  True
java-9.11.0               True <====
java-native-image-7.9.0   True
nodejs-2.3.2              True
php-2.6.1                 True
procfile-5.6.1            True
python-2.5.1              True
ruby-2.8.1                True
web-servers-0.15.4        True
```



tanzu java buildpack 9.11.0に含まれている個別のbuildpackは次のコマンドで確認できます。

> ℹ️ java buildpackは以下のbuildpack群をまとめたmeta buildpackです。

```
$ kubectl get clusterbuildpack java-9.11.0 -ojson | jq -r '.status.buildpacks[] | [.id, .version] | @tsv'
paketo-buildpacks/apache-skywalking	5.6.1
paketo-buildpacks/apache-tomcat	7.13.9
paketo-buildpacks/apache-tomee	1.7.4
paketo-buildpacks/appdynamics	5.14.0
paketo-buildpacks/aternity	5.4.2
paketo-buildpacks/azure-application-insights	5.15.4
paketo-buildpacks/ca-certificates	3.6.3
paketo-buildpacks/clojure-tools	2.8.8
paketo-buildpacks/datadog	4.0.0
paketo-buildpacks/dist-zip	5.6.4
paketo-buildpacks/dynatrace	5.5.0
paketo-buildpacks/elastic-apm	5.14.0
paketo-buildpacks/encrypt-at-rest	4.5.6
paketo-buildpacks/environment-variables	4.5.3
paketo-buildpacks/executable-jar	6.7.4
paketo-buildpacks/google-stackdriver	7.7.0
paketo-buildpacks/gradle	7.5.0
paketo-buildpacks/image-labels	4.5.2
paketo-buildpacks/jattach	1.4.4
paketo-buildpacks/java-memory-assistant	1.4.4
paketo-buildpacks/jprofiler	6.5.3
paketo-buildpacks/leiningen	4.6.4
paketo-buildpacks/liberty	3.8.4
paketo-buildpacks/maven	6.15.6
paketo-buildpacks/new-relic	7.8.0
paketo-buildpacks/procfile	5.6.4
paketo-buildpacks/sbt	6.12.4
paketo-buildpacks/spring-boot	5.27.1
paketo-buildpacks/syft	1.10.1
paketo-buildpacks/watchexec	2.8.3
paketo-buildpacks/yourkit	6.0.6
tanzu-buildpacks/aspectj	4.5.0
tanzu-buildpacks/checkmarx	4.6.0
tanzu-buildpacks/contrast-security	5.3.1
tanzu-buildpacks/deprecation-warnings	0.0.4
tanzu-buildpacks/jacoco	4.6.0
tanzu-buildpacks/java	9.11.0
tanzu-buildpacks/jrebel	4.12.0
tanzu-buildpacks/luna-security-provider	1.7.0
tanzu-buildpacks/node-engine	2.0.0
tanzu-buildpacks/overops	4.12.2
tanzu-buildpacks/snyk	4.6.0
tanzu-buildpacks/synopsys	4.6.1
tanzu-buildpacks/tanzu-bellsoft-liberica	9.12.1 <====
tanzu-buildpacks/yarn	1.1.11
```

`tanzu-buildpacks/tanzu-bellsoft-liberica` が実際のJDKを持つbuildpackであり、9.12.1では8, 11, 17, 20しかサポートされていません。



なお、`default`の`ClusterBuilder`が参照しているbuildpackは次のコマンドで確認できます。

```
$ kubectl get clusterbuilder default -ojsonpath='{.status.order}' | jq -r '.[].group[0] | [.id, .version] | @tsv'
tanzu-buildpacks/ruby	2.8.1
tanzu-buildpacks/dotnet-core	2.8.2
tanzu-buildpacks/go	2.2.2
tanzu-buildpacks/python	2.5.1
tanzu-buildpacks/web-servers	0.15.4
tanzu-buildpacks/java-native-image	7.9.0
tanzu-buildpacks/java	9.11.0 <====
tanzu-buildpacks/nodejs	2.3.2
paketo-buildpacks/procfile	5.6.7
```

使用されているtanzu java buildpack(`tanzu-buildpacks/java`) のバージョンが9.11.0であることがわかります。

今回はこの`ClusterBuilder`が参照するtanzu java buildpackのバージョンを9.13.0にしたいです。

更新方法は
https://docs.vmware.com/en/VMware-Tanzu-Application-Platform/1.7/tap/tanzu-build-service-dependencies.html#update-dependencies-7
に記載されています。


まずはbuildpackのDockerイメージを `imgpkg` コマンドでrelocateします。元となるイメージ名はTanzu Netから確認可能です。
lite dependenciesを使用している場合は末尾に`-lite`がつくものを、full dependenciesを使用している場合は`-lite`がつかないものを使用します。


<img width="1608" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/cbe50b97-a950-4dd9-85b6-60b15316a253">

ここでは `ghcr.io/making` 配下にrelocateします。

```
imgpkg copy -i registry.tanzu.vmware.com/tanzu-java-buildpack/java:9.13.0 --to-repo ghcr.io/making/tanzu-java-buildpack/java
```

relocateしたイメージを `ClusterBuildpack` の `.spec.image` に指定します。
`.spec.serviceAccountRef`に指定するService Accountは、relocateしたイメージをpullできる`imagePullSecrets`が設定されている必要があります。
わからない場合は`kubectl get clusterbuildpack -ojsonpath='{.items[0].spec.serviceAccountRef}'`で既存の`ClusterBuildpack`が使用しているService Accountを確認できます。

名前の形式は、TAPに同梱されるものと被らないようにする方が良いでしょう。ここではドキュメント同様に `out-of-band-` をprefixとして使用しています。

```yaml
kubectl apply -f - << 'EOF'
---
apiVersion: kpack.io/v1alpha2
kind: ClusterBuildpack
metadata:
  name: out-of-band-java-9.13.0
spec:
  image: ghcr.io/making/tanzu-java-buildpack/java:9.13.0
  serviceAccountRef:
    name: dependencies-pull-serviceaccount
    namespace: tbs-full-deps
---
EOF
```

`ClusterBuildpack`一覧を確認します。`out-of-band-java-9.13.0` が追加されています。

```
$ kubectl get clusterbuildpack
NAME                      READY
dotnet-core-2.8.2         True
go-2.2.2                  True
java-9.11.0               True
java-native-image-7.9.0   True
nodejs-2.3.2              True
out-of-band-java-9.13.0   True <====
php-2.6.1                 True
procfile-5.6.1            True
python-2.5.1              True
ruby-2.8.1                True
web-servers-0.15.4        True
```

この `out-of-band-java-9.13.0` に含まれる個別のbuildpackは次のコマンドで確認できます。

```
$ kubectl get clusterbuildpack out-of-band-java-9.13.0 -ojson | jq -r '.status.buildpacks[] | [.id, .version] | @tsv'
paketo-buildpacks/syft	1.10.1
tanzu-buildpacks/apache-skywalking	6.0.4
tanzu-buildpacks/apache-tomcat	7.14.1
tanzu-buildpacks/apache-tomee	1.7.9
tanzu-buildpacks/appdynamics	5.17.1
tanzu-buildpacks/aspectj	4.5.2
tanzu-buildpacks/aternity	5.4.6
tanzu-buildpacks/azure-application-insights	5.17.2
tanzu-buildpacks/bellsoft-liberica	9.13.0 <====
tanzu-buildpacks/ca-certificates	3.6.7
tanzu-buildpacks/checkmarx	4.6.2
tanzu-buildpacks/clojure-tools	2.8.13
tanzu-buildpacks/contrast-security	5.5.0
tanzu-buildpacks/datadog	4.5.1
tanzu-buildpacks/deprecation-warnings	0.0.4
tanzu-buildpacks/dist-zip	5.6.8
tanzu-buildpacks/dynatrace	5.6.1
tanzu-buildpacks/elastic-apm	6.2.1
tanzu-buildpacks/encrypt-at-rest	4.5.11
tanzu-buildpacks/environment-variables	4.5.7
tanzu-buildpacks/executable-jar	6.8.3
tanzu-buildpacks/google-stackdriver	8.0.4
tanzu-buildpacks/gradle	7.6.2
tanzu-buildpacks/image-labels	4.5.6
tanzu-buildpacks/jacoco	4.6.1
tanzu-buildpacks/jattach	1.4.9
tanzu-buildpacks/java-memory-assistant	1.4.9
tanzu-buildpacks/java	9.13.0
tanzu-buildpacks/jprofiler	6.5.7
tanzu-buildpacks/jrebel	4.14.0
tanzu-buildpacks/leiningen	4.6.9
tanzu-buildpacks/liberty	3.8.11
tanzu-buildpacks/luna-security-provider	1.7.2
tanzu-buildpacks/maven	6.15.12
tanzu-buildpacks/new-relic	8.4.1
tanzu-buildpacks/node-engine	2.0.0
tanzu-buildpacks/overops	4.12.4
tanzu-buildpacks/procfile	5.6.9
tanzu-buildpacks/sbt	6.12.10
tanzu-buildpacks/snyk	4.6.2
tanzu-buildpacks/spring-boot	5.27.6
tanzu-buildpacks/synopsys	4.6.3
tanzu-buildpacks/watchexec	2.8.7
tanzu-buildpacks/yarn	1.1.11
tanzu-buildpacks/yourkit	6.1.6
```

`tanzu-buildpacks/tanzu-bellsoft-liberica` のバージョンが9.13.0であることがわかります。

`ClusterBuildpack`を追加したことで、`ClusterBuilder`が変わったかどうかを次のコマンドで確認します。

```
$ kubectl get clusterbuilder default -ojsonpath='{.status.order}' | jq -r '.[].group[0] | [.id, .version] | @tsv'
tanzu-buildpacks/ruby	2.8.1
tanzu-buildpacks/dotnet-core	2.8.2
tanzu-buildpacks/go	2.2.2
tanzu-buildpacks/python	2.5.1
tanzu-buildpacks/web-servers	0.15.4
tanzu-buildpacks/java-native-image	7.9.0
tanzu-buildpacks/java	9.13.0 <====
tanzu-buildpacks/nodejs	2.3.2
paketo-buildpacks/procfile	5.6.7
```

使用されているtanzu java buildpack(`tanzu-buildpacks/java`) のバージョンが9.13.0になったことがわかります。

これでJava 21が利用できるbuildpackがTAP 1.7環境にインストールされました。

あとはWorkload側でbuild時の環境変数`BP_JVM_VERSION`に21を明示すればJava 21を使用したコンテナイメージができます。

`tanzu apps workload apply`コマンドの場合は、`--build-env BP_JVM_VERSION=21`を、YAMLの場合は次の設定をすれば良いです。

```yaml
spec:
  build:
    env:
    - name: BP_JVM_VERSION
      value: "21"
```

Developer Portalでビルドのログを見るとJDK 21が利用されていることが確認できます。

<img width="1132" alt="image" src="https://github.com/making/blog.ik.am/assets/106908/287abfd1-d636-49bc-a97b-eebf382cfedf">

アプリがSpring Boot 3.2を使用している場合はプロパティ `spring.threads.virtual.enabled=true` (環境変数 `SPRING_THREADS_VIRTUAL_ENABLED`を`true`にしてもOK) を設定するだけでVirtual Threadsが利用できます。

なお、このブログのBackendのAPIをこの記事の方法でビルドしました。以下のコマンドでこのブログのBackendのAPIが使用しているJavaのバージョンを確認できます。Java 21が使われています。

```
$ curl -s https://api.ik.am/info | jq .java
{
  "version": "21.0.1",
  "vendor": {
    "name": "BellSoft"
  },
  "runtime": {
    "name": "OpenJDK Runtime Environment",
    "version": "21.0.1+12-LTS"
  },
  "jvm": {
    "name": "OpenJDK 64-Bit Server VM",
    "vendor": "BellSoft",
    "version": "21.0.1+12-LTS"
  }
}
```
