There are some problems when deploying apps using older versions of Spring Boot on TAP, so I will make a note of the workaround.
This time, I will deploy https://github.com/making/demo-download-view.
This app was created 7 years ago using Spring Boot 1.3.
Let's deploy this app as-is to TAP.
tanzu apps workload apply demo-download-view \
--app demo-download-view \
--git-repo https://github.com/making/demo-download-view \
--git-branch master \
--type web \
--annotation autoscaling.knative.dev/minScale=1 \
--build-env BP_JVM_VERSION=8 \
-n demo \
-y
We will deal with the errors that occur one by one.
table of contents
- Build error due to old Maven
- Build error due to Spring-Boot-Lib not present in MANIFEST.MF
- Build error due to Spring-Boot-Classes not present in MANIFEST.MF
- Runtime error regarding Spring Cloud Bindings
- For the standalone Tanzu Build Service
Build error due to old Maven
When creating an image with the Build Service, I first got the following error:
Compiled Application: Contributing to layer
Executing mvnw --settings=/platform/bindings/settings-xml/settings.xml --batch-mode -Dmaven.test.skip=true --no-transfer-progress package
Downloading https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.3/apache-maven-3.3.3-bin.zip
........................................................................................................................................................................................................................................................................................................................................................................................................................
Unzipping /home/cnb/.m2/wrapper/dists/apache-maven-3.3.3-bin/3opbjp6rgl6qp7k2a6tljcpvgp/apache-maven-3.3.3-bin.zip to /home/cnb/.m2/wrapper/dists/apache-maven-3.3.3-bin/3opbjp6rgl6qp7k2a6tljcpvgp
Set executable permissions for: /home/cnb/.m2/wrapper/dists/apache-maven-3.3.3-bin/3opbjp6rgl6qp7k2a6tljcpvgp/apache-maven-3.3.3/bin/mvn
Unable to parse command line options: Unrecognized option: --no-transfer-progress
Maven Buildpack suppresses log output with the --no-transfer-progress
option when running maven build.
This option was introduced in Maven 3.6.1. The Maven Wrapper included in this app uses Maven 3.3.3 and the error occurred because this option does not exist.
You can update the Maven version used by the Maven Wrapper by running the following command in your source code directory:
mvn wrapper:wrapper
You can also specify a specific version like:
mvn wrapper:wrapper -Dmaven=3.8.6
This time I updated the Maven Wrapper with the following commits:
https://github.com/making/demo-download-view/commit/25eac90254d3c728ec1c4b90740aff51495e434c
Alternatively, you can set the following build environment variables without the --no-transfer-progress
option.
--build-env BP_MAVEN_BUILD_ARGUMENTS='-Dmaven.test.skip=true package' \
Build error due to Spring-Boot-Lib not present in MANIFEST.MF
If you update the source code on Git, the image will be built again. Now I got the following error:
Paketo Buildpack for Spring Boot 5.19.0
https://github.com/paketo-buildpacks/spring-boot
Build Configuration:
$BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support
Launch Configuration:
$BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings
$BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings
Paketo Buildpack for Spring Boot 5.19.0
manifest does not container Spring-Boot-Lib
ERROR: failed to build: exit status 1
The error is that there is no Spring-Boot-Lib
in the MANIFEST.MF in the jar file.
Reading the following buildpack source code, it seems that the buildpack looks at the directory set in this entry to add dependencies to the BOM.
This Spring-Boot-Lib
seems to have been included since Spring Boot 1.4.0 for Maven and 2.0.9 for Gradle.
- https://github.com/spring-projects/spring-boot/issues/5183
- https://github.com/spring-projects/spring-boot/issues/16068
The following values are set in MANIFEST.MF for supported versions:
- https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-jarmode-layertools/src/test/resources/org/springframework/boot/jarmode/layertools/test-manifest.MF#L10 (jarの場合)
- https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-jarmode-layertools/src/test/resources/org/springframework/boot/jarmode/layertools/test-war-manifest.MF#L10 (warの場合)
Unsupported versions must somehow set this value in the MANIFEST.MF. Any entry can be added to MANIFST.MF using maven-jar-plugin as follows.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Spring-Boot-Lib>lib/</Spring-Boot-Lib>
</manifestEntries>
</archive>
</configuration>
</plugin>
If you are creating a war file, change maven-jar-plugin to maven-war-plugin. The content to be set depends on the version of Spring Boot. Because it changes the layout of the jar.
If you want to check the layout of a jar or war, use zipinfo
command.
$ zipinfo target/demo-0.0.1-SNAPSHOT.jar
Archive: target/demo-0.0.1-SNAPSHOT.jar
Zip file size: 20306425 bytes, number of entries: 122
-rw---- 2.0 fat 0 bX defN 22-Dec-22 11:25 META-INF/
-rw---- 2.0 fat 477 bl defN 22-Dec-22 11:25 META-INF/MANIFEST.MF
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 templates/
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 com/
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 com/example/
-rw-r--r-- 2.0 unx 419 bl defN 22-Dec-22 11:25 templates/index.html
-rw-r--r-- 2.0 unx 15 bl defN 22-Dec-22 11:25 hello.txt
-rw-r--r-- 2.0 unx 730 bl defN 22-Dec-22 11:25 com/example/DemoDownloadViewApplication.class
-rw-r--r-- 2.0 unx 701 bl defN 22-Dec-22 11:25 com/example/HelloForm.class
-rw-r--r-- 2.0 unx 1586 bl defN 22-Dec-22 11:25 com/example/HelloController.class
-rw-r--r-- 2.0 unx 2112 bl defN 22-Dec-22 11:25 com/example/DownloadView.class
-rw-r--r-- 2.0 unx 0 bl defN 22-Dec-22 11:25 application.properties
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 META-INF/maven/
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 META-INF/maven/com.example/
drwxr-xr-x 1.0 unx 0 b- stor 22-Dec-22 11:25 META-INF/maven/com.example/demo/
-rw-r--r-- 2.0 unx 1913 bl defN 22-Dec-22 11:24 META-INF/maven/com.example/demo/pom.xml
-rw-r--r-- 2.0 unx 109 bl defN 22-Dec-22 11:25 META-INF/maven/com.example/demo/pom.properties
-rw---- 2.0 fat 0 bl defN 22-Dec-22 11:25 lib/
-rw---- 1.0 fat 193581 b- stor 15-Nov-16 02:45 lib/spring-boot-devtools-1.3.0.RELEASE.jar
-rw---- 1.0 fat 533592 b- stor 15-Nov-16 02:34 lib/spring-boot-1.3.0.RELEASE.jar
...
-rw---- 1.0 fat 1077165 b- stor 15-Nov-15 08:03 lib/spring-core-4.2.3.RELEASE.jar
-rw---- 2.0 fat 0 bl defN 22-Dec-22 11:25 org/
-rw---- 2.0 fat 0 bl defN 22-Dec-22 11:25 org/springframework/
-rw---- 2.0 fat 0 bl defN 22-Dec-22 11:25 org/springframework/boot/
-rw---- 2.0 fat 0 bl defN 22-Dec-22 11:25 org/springframework/boot/loader/
-rw---- 2.0 fat 1257 bl defN 15-Nov-16 02:31 org/springframework/boot/loader/LaunchedURLClassLoader$Java7LockProvider.class
...
-rw---- 2.0 fat 884 bl defN 15-Nov-16 02:31 org/springframework/boot/loader/archive/ExplodedArchive$FileNotFoundURLConnection.class
-rw---- 2.0 fat 192 bl defN 15-Nov-16 02:31 org/springframework/boot/loader/JavaAgentDetector.class
122 files, 20382587 bytes uncompressed, 20285023 bytes compressed: 0.5%
This time I updated the pom.xml with the following commits:
https://github.com/making/demo-download-view/commit/e13e75a10560721e9f2c86563494bafb94dae8d1
Build error due to Spring-Boot-Classes not present in MANIFEST.MF
If you update the source code on Git, the image will be built again. Now I got the following error:
Paketo Buildpack for Spring Boot 5.19.0
https://github.com/paketo-buildpacks/spring-boot
Build Configuration:
$BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support
Launch Configuration:
$BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings
$BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings
Paketo Buildpack for Spring Boot 5.19.0
manifest does not contain Spring-Boot-Classes
ERROR: failed to build: exit status 1
As before, the error is that there is no Spring-Boot-Classes
in the MANIFEST.MF in the jar file.
Reading the buildpack source code below, it seems to look at the directory set in this entry to detect the application type.
The following values are set in MANIFEST.MF for supported versions:
- https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-jarmode-layertools/src/test/resources/org/springframework/boot/jarmode/layertools/test-manifest.MF#L9 (jarの場合)
- https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-jarmode-layertools/src/test/resources/org/springframework/boot/jarmode/layertools/test-war-manifest.MF#L9 (warの場合)
This time also set this item with maven-jar-plugin or maven-war-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Spring-Boot-Lib>lib/</Spring-Boot-Lib>
<Spring-Boot-Classes>.</Spring-Boot-Classes>
</manifestEntries>
</archive>
</configuration>
</plugin>
This time I updated the pom.xml with the following commits:
https://github.com/making/demo-download-view/commit/ae127b2bbad58f663573489cbe95f24ff165129e
Runtime error regarding Spring Cloud Bindings
If you update the source code on Git, the image will be built again. This time the image build succeeded and the app started to run. But on startup I get the following error and the app did't start.
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.cloud.bindings.boot.BindingSpecificEnvironmentPostProcessor
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:396)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:373)
at org.springframework.boot.SpringApplication.initialize(SpringApplication.java:253)
at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:227)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1112)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1101)
at com.example.DemoDownloadViewApplication.main(DemoDownloadViewApplication.java:10)
... 6 more
Caused by: java.lang.ClassNotFoundException: org.springframework.cloud.bindings.boot.BindingSpecificEnvironmentPostProcessor
at java.net.URLClassLoader.findClass(URLClassLoader.java:387)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at org.springframework.boot.loader.LaunchedURLClassLoader.doLoadClass(LaunchedURLClassLoader.java:166)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:130)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:250)
at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:389)
... 12 more
It's an error related to Spring Cloud Bindings. This library is automatically added when building the image, but due to the version of Spring Boot, a ClassNotFoundException occurs.
If you don't use Service Binding, you don't need Spring Cloud Bindings, so add --build-env BP_SPRING_CLOUD_BINDINGS_DISABLED=true
option to disable Spring Cloud Bindings when building.
The final command I ran was:
tanzu apps workload apply demo-download-view \
--app demo-download-view \
--git-repo https://github.com/making/demo-download-view \
--git-branch tap \
--type web \
--annotation autoscaling.knative.dev/minScale=1 \
--build-env BP_JVM_VERSION=8 \
--build-env BP_SPRING_CLOUD_BINDINGS_DISABLED=true \
-n demo \
-y
$ tanzu apps workload get -n demo demo-download-view
📡 Overview
name: demo-download-view
type: web
💾 Source
type: git
url: https://github.com/making/demo-download-view
branch: tap
📦 Supply Chain
name: source-to-url
RESOURCE READY HEALTHY TIME OUTPUT
source-provider True True 42m GitRepository/demo-download-view
image-provider True True 101s Image/demo-download-view
config-provider True True 12m PodIntent/demo-download-view
app-config True True 12m ConfigMap/demo-download-view
service-bindings True True 12m ConfigMap/demo-download-view-with-claims
api-descriptors True True 12m ConfigMap/demo-download-view-with-api-descriptors
config-writer True True 81s Runnable/demo-download-view-config-writer
🚚 Delivery
name: delivery-basic
RESOURCE READY HEALTHY TIME OUTPUT
source-provider True True 11m ImageRepository/demo-download-view-delivery
deployer True True 69s App/demo-download-view
💬 Messages
No messages found.
🛶 Pods
NAME READY STATUS RESTARTS AGE
demo-download-view-00001-deployment-76b5cc876c-t9clq 0/2 Terminating 7 (5m19s ago) 11m
demo-download-view-00002-deployment-76dbf5f776-z7qvj 2/2 Running 0 71s
demo-download-view-build-1-build-pod 0/1 Init:Error 0 47m
demo-download-view-build-2-build-pod 0/1 Init:Error 0 42m
demo-download-view-build-3-build-pod 0/1 Init:Error 0 26m
demo-download-view-build-4-build-pod 0/1 Init:Error 0 16m
demo-download-view-build-5-build-pod 0/1 Completed 0 14m
demo-download-view-build-6-build-pod 0/1 Completed 0 2m29s
demo-download-view-config-writer-d9l79-pod 0/1 Completed 0 92s
demo-download-view-config-writer-f9kvp-pod 0/1 Completed 0 12m
🚢 Knative Services
NAME READY URL
demo-download-view Ready https://demo-download-view-demo.127-0-0-1.sslip.io
To see logs: "tanzu apps workload tail demo-download-view --namespace demo"
Now the app has started and I have access to the app.
$ curl -k "https://demo-download-view-demo.127-0-0-1.sslip.io/download?fileName=tap"
Hello Download!
For the standalone Tanzu Build Service
If you are using only the Tanzu Build Service, the following commands are equivalent.
kp image save demo-download-view \
--git https://github.com/making/demo-download-view \
--git-revision tap \
--tag ghcr.io/making/demo-download-view \
--env BP_JVM_VERSION=8 \
--env BP_SPRING_CLOUD_BINDINGS_DISABLED=true \
-n demo
Worked around buildpack issues caused by older Spring Boot versions.
Please upgrade Spring Boot if possible instead of using this workaround.