From 9ec4dc8a5fcc8a3c70662e8e92abcd32222fe9fd Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Wed, 10 Nov 2021 12:17:04 -0500 Subject: [PATCH 1/6] Add FAQ about unsupported Java version --- docs/faq.md | 73 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index c77c510958..ca1f254a02 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -42,11 +42,11 @@ If a question you have is not answered below, please [submit an issue](/../../is [What should I do when the registry responds with UNAUTHORIZED?](#what-should-i-do-when-the-registry-responds-with-unauthorized)\ [How do I configure a proxy?](#how-do-i-configure-a-proxy)\ [How can I examine network traffic?](#how-can-i-examine-network-traffic)\ -[How do I view debug logs for Jib?](#how-do-i-view-debug-logs-for-jib) +[How do I view debug logs for Jib?](#how-do-i-view-debug-logs-for-jib)\ +[I am seeing `Method Not Found` or `Class Not Found` errors when building.](#i-am-seeing-method-not-found-or-class-not-found-errors-when-building) **Launch Problems**\ [I am seeing `ImagePullBackoff` on my pods.](#i-am-seeing-imagepullbackoff-on-my-pods-in-minikube)\ -[I am seeing `Method Not Found` or `Class Not Found` errors when building.](#i-am-seeing-method-not-found-or-class-not-found-errors-when-building)\ [Why won't my container start?](#why-wont-my-container-start) **Jib CLI**\ @@ -699,13 +699,47 @@ Accept-Encoding: gzip Authorization: User-Agent: jib 2.1.1-SNAPSHOT jib-maven-plugin Google-HTTP-Java-Client/1.34.0 (gzip) ``` - + ### How do I view debug logs for Jib? Maven: use `mvn -X -Djib.serialize=true` to enable more detailed logging and serialize Jib's actions. Gradle: use `gradle --debug -Djib.serialize=true` to enable more detailed logging and serialize Jib's actions. +### I am seeing `Method Not Found` or `Class Not Found` errors when building. + +Sometimes when upgrading your gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). + +This commonly appears in multi module gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library. + +`build.gradle` (root) +```groovy +plugins { + id 'com.google.cloud.tools.jib' version 'x.y.z' apply false +} +``` + +`build.gradle` (sub-project) +```groovy +plugins { + id 'com.google.cloud.tools.jib' +} +``` + +### I am seeting `Unsupported class file major version` when building. + +When you're using latest Java versions to write an app (or using an old version of Jib), you may see the error _coming from Jib when building an image_ (not when compiling your code): + +``` +Failed to execute goal com.google.cloud.tools:jib-maven-plugin:3.1.4:dockerBuild (default-cli) on project demo: Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:3.1.4:dockerBuild failed: Unsupported class file major version 61 +``` + +Jib uses the [ASM library](https://asm.ow2.io/) to examine compiled Java bytecode to automatically infer a main class (in other words, the class that defines `public static void main()` to start your app). In this way, if you have only one such class, Jib can automatically infer and use that class to set an image entrypoint (basically, a command to start your app). When new Java versions come out, often the ASM library version used in Jib doesn't support the new bytecode format. If this is the case, check if you are using the latest Jib. If you still get the error with the latest Jib, file a [bug](https://github.com/GoogleContainerTools/jib/issues/new/choose) to have the Jib team upgarde the ASM library. + +**Workaround**: to prevent Jib from doing auto-inference, you can manually set your desired main class via [``](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#container-object) (for example, `com.example.your.Main`). Note, as with other Jib parameters, the parameter can be set through system and Maven properties or on the command-line (for example, `-Dcontainer.mainClass=...`). + +Note that although the ASM library is the common cause of this error coming from Jib, it may be due to other reasons. Always check the full stack (`-e` or `-X` for Maven and `--stacktrace` for Gradle) to see where the error is coming from. + ## Launch problems @@ -739,35 +773,15 @@ kubectl patch serviceaccount default \ See more at [Using Google Container Registry (GCR) with Minikube](https://ryaneschinger.com/blog/using-google-container-registry-gcr-with-minikube/). -### I am seeing `Method Not Found` or `Class Not Found` errors when building. - -Sometimes when upgrading your gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). - -This commonly appears in multi module gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library. - -`build.gradle` (root) -```groovy -plugins { - id 'com.google.cloud.tools.jib' version 'x.y.z' apply false -} -``` - -`build.gradle` (sub-project) -```groovy -plugins { - id 'com.google.cloud.tools.jib' -} -``` - ### Why won't my container start? There are some common reasons why containers fail on launch. -#### My shell script won't run - +#### My shell script won't run. + Jib Maven and Gradle plugins prior to 3.0 used Distroless Java as the default base image, which does not have a shell. See [Where is bash?](#where-is-bash) for more details. -#### The container fails with `exec` errors +#### The container fails with `exec` errors. A Jib user reported an error launching their container: ``` @@ -783,6 +797,7 @@ Solution: The user installed the file in a different location. ## Jib CLI ### How does the `jar` command support Standard JARs? + The Jib CLI supports both [thin JARs](https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html) (where dependencies are specified in the JAR's manifest) and fat JARs. The current limitation of using a fat JAR is that the embedded dependencies will not be placed into the designated dependencies layers. They will instead be placed into the classes or resources layer. Therefore, for efficiency, we recommend against containerizing fat JARs (Spring Boot fat JARs are an [exception](#how-does-the-jar-command-support-spring-boot-jars)) if you can prepare thin JARs. We hope to have better support for fat JARs in the future. @@ -790,6 +805,7 @@ The current limitation of using a fat JAR is that the embedded dependencies will A standard JAR can be containerized by the `jar` command in two modes, exploded or packaged. #### Exploded Mode (Recommended) + Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar` The default mode for containerizing a JAR. It will open up the JAR and optimally place files into the following layers: @@ -802,6 +818,7 @@ The default mode for containerizing a JAR. It will open up the JAR and optimally **Entrypoint** : `java -cp /app/dependencies/:/app/explodedJar/ ${MAIN_CLASS}` #### Packaged Mode + Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar --mode packaged`. It will result in the following layers on the container: @@ -812,10 +829,12 @@ It will result in the following layers on the container: **Entrypoint** : `java -jar ${JAR_NAME}.jar` ### How does the `jar` command support Spring Boot JARs? + The `jar` command currently supports containerization of Spring Boot fat JARs. A Spring-Boot fat JAR can be containerized in two modes, exploded or packaged. #### Exploded Mode (Recommended) + Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar` The default mode for containerizing a JAR. It will respect [`layers.idx`](https://spring.io/blog/2020/08/14/creating-efficient-docker-images-with-spring-boot-2-3) in the JAR (if present) or create optimized layers in the following format: @@ -829,6 +848,7 @@ The default mode for containerizing a JAR. It will respect [`layers.idx`](https: **Entrypoint** : `java -cp /app org.springframework.boot.loader.JarLauncher` #### Packaged Mode + Achieved by calling `jib jar --target ${TARGET_REGISTRY} ${JAR_NAME}.jar --mode packaged` It will containerize the JAR as is. However, **note** that we highly recommend against using packaged mode for containerizing Spring Boot fat JARs. @@ -836,6 +856,7 @@ It will containerize the JAR as is. However, **note** that we highly recommend a **Entrypoint**: `java -jar ${JAR_NAME}.jar` ### How does the `war` command work? + The `war` command currently supports containerization of standard WARs. It uses the official [`jetty`](https://hub.docker.com/_/jetty) on Docker Hub as the default base image and explodes out the WAR into `/var/lib/jetty/webapps/ROOT` on the container. It creates the following layers: * Other Dependencies Layer From 87412e53c214403ed217028c675adb029db098b6 Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Wed, 10 Nov 2021 12:21:31 -0500 Subject: [PATCH 2/6] Update faq.md --- docs/faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index ca1f254a02..8bd55178cc 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -726,7 +726,7 @@ plugins { } ``` -### I am seeting `Unsupported class file major version` when building. +### I am seeing `Unsupported class file major version` when building. When you're using latest Java versions to write an app (or using an old version of Jib), you may see the error _coming from Jib when building an image_ (not when compiling your code): @@ -736,7 +736,7 @@ Failed to execute goal com.google.cloud.tools:jib-maven-plugin:3.1.4:dockerBuild Jib uses the [ASM library](https://asm.ow2.io/) to examine compiled Java bytecode to automatically infer a main class (in other words, the class that defines `public static void main()` to start your app). In this way, if you have only one such class, Jib can automatically infer and use that class to set an image entrypoint (basically, a command to start your app). When new Java versions come out, often the ASM library version used in Jib doesn't support the new bytecode format. If this is the case, check if you are using the latest Jib. If you still get the error with the latest Jib, file a [bug](https://github.com/GoogleContainerTools/jib/issues/new/choose) to have the Jib team upgarde the ASM library. -**Workaround**: to prevent Jib from doing auto-inference, you can manually set your desired main class via [``](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#container-object) (for example, `com.example.your.Main`). Note, as with other Jib parameters, the parameter can be set through system and Maven properties or on the command-line (for example, `-Dcontainer.mainClass=...`). +**Workaround**: to prevent Jib from doing auto-inference, you can manually set your desired main class via [``](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin#container-object) (for example, `com.example.your.Main`). As with other Jib parameters, it can be set through system/Maven properties or on the command-line (for example, `-Dcontainer.mainClass=...`). Note that although the ASM library is the common cause of this error coming from Jib, it may be due to other reasons. Always check the full stack (`-e` or `-X` for Maven and `--stacktrace` for Gradle) to see where the error is coming from. From 98d9f71fc489a669b331e954bbad5414018133eb Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Wed, 10 Nov 2021 12:23:18 -0500 Subject: [PATCH 3/6] Update faq.md --- docs/faq.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 8bd55178cc..52cbbb4dce 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -43,7 +43,8 @@ If a question you have is not answered below, please [submit an issue](/../../is [How do I configure a proxy?](#how-do-i-configure-a-proxy)\ [How can I examine network traffic?](#how-can-i-examine-network-traffic)\ [How do I view debug logs for Jib?](#how-do-i-view-debug-logs-for-jib)\ -[I am seeing `Method Not Found` or `Class Not Found` errors when building.](#i-am-seeing-method-not-found-or-class-not-found-errors-when-building) +[I am seeing `Method Not Found` or `Class Not Found` errors when building.](#i-am-seeing-method-not-found-or-class-not-found-errors-when-building)\ +[I am seeing `Unsupported class file major version` when building.](#i-am-seeing-unsupported-class-file-major-version-when-building) **Launch Problems**\ [I am seeing `ImagePullBackoff` on my pods.](#i-am-seeing-imagepullbackoff-on-my-pods-in-minikube)\ From d1e1a2502372af4489d3a367883d4f8f4935c331 Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Wed, 10 Nov 2021 14:29:34 -0500 Subject: [PATCH 4/6] Throw exception with helpful message --- .../com/google/cloud/tools/jib/api/MainClassFinder.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/api/MainClassFinder.java b/jib-core/src/main/java/com/google/cloud/tools/jib/api/MainClassFinder.java index 5967f8a6bc..edd452ef54 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/api/MainClassFinder.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/api/MainClassFinder.java @@ -168,6 +168,14 @@ public static Result find(List files, Consumer logger) { mainClasses.add(reader.getClassName().replace('/', '.')); } + } catch (IllegalArgumentException ex) { + throw new UnsupportedOperationException( + "Check the full stace trace, and if the root cause is from ASM ClassReader about " + + "unsupported class file version, see " + + "https://github.com/GoogleContainerTools/jib/blob/master/docs/faq.md" + + "#i-am-seeing-unsupported-class-file-major-version-when-building", + ex); + } catch (ArrayIndexOutOfBoundsException ignored) { // Not a valid class file (thrown by ClassReader if it reads an invalid format) logger.accept(LogEvent.warn("Invalid class file found: " + file)); From e6c2a661732642ea60d798401074ee54f1023b17 Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Thu, 11 Nov 2021 09:09:43 -0500 Subject: [PATCH 5/6] Update docs/faq.md Co-authored-by: Tomo Suzuki --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 52cbbb4dce..baa2f6c194 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -709,7 +709,7 @@ Gradle: use `gradle --debug -Djib.serialize=true` to enable more detailed loggin ### I am seeing `Method Not Found` or `Class Not Found` errors when building. -Sometimes when upgrading your gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). +Sometimes when upgrading your Gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). This commonly appears in multi module gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library. From fcacb1283a605ec7a6b917ea61bc9f761603b834 Mon Sep 17 00:00:00 2001 From: Chanseok Oh Date: Thu, 11 Nov 2021 09:09:54 -0500 Subject: [PATCH 6/6] Update docs/faq.md Co-authored-by: Tomo Suzuki --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index baa2f6c194..506c92e3b4 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -711,7 +711,7 @@ Gradle: use `gradle --debug -Djib.serialize=true` to enable more detailed loggin Sometimes when upgrading your Gradle build plugin versions, you may experience errors due to mismatching versions of dependencies pulled in (for example: [issues/2183](https://github.com/GoogleContainerTools/jib/issues/2183)). This can be due to the buildscript classpath loading behavior described [on gradle forums](https://discuss.gradle.org/t/version-is-root-build-gradle-buildscript-is-overriding-subproject-buildscript-dependency-versions/20746/3). -This commonly appears in multi module gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library. +This commonly appears in multi module Gradle projects. A solution to this problem is to define all of your plugins in the base project and apply them selectively in your subprojects as needed. This should help alleviate the problem of the buildscript classpath using older versions of a library. `build.gradle` (root) ```groovy