2

I'm trying to build a docker image but I get an error telling me that the jib-maven-plugin failed. Resulting in an unsupported class file major version 61 error.

At first I thought it had to do with the version of java I was using (Java 17). So I uninstalled it from my machine and installed Java 15 but without succes.

The command I'm trying to run:

./mvnw compile jib:dockerBuild -Djib.to.image=fullstack:v1

The error response I get:

Failed to execute goal com.google.cloud.tools:jib-maven-plugin:2.5.2:dockerBuild (default-cli) on project demo: Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:2.5.2:dockerBuild failed: Unsupported class file major version 61 -> [Help 1]

My pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>15</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <!-- The plugin below is to make a docker image using Jib -->
            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.5.2</version>
                <configuration>
                    <from>
                        <image>openjdk:15</image>
                    </from>
                    <container>
                        <ports>
                            <port>8080</port>
                        </ports>
                        <format>OCI</format>
                    </container>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <!-- The code below is for packaging the frontend with the backend using maven -->
    <profiles>
        <profile>
            <id>build-frontend</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>

                    <plugin>
                        <groupId>com.github.eirslett</groupId>
                        <artifactId>frontend-maven-plugin</artifactId>
                        <!-- Use the latest released version:
                                  https://repo1.maven.org/maven2/com/github/eirslett/frontend-maven-plugin/ -->
                        <version>1.11.2</version>
                        <configuration>
                            <nodeVersion>v4.6.0</nodeVersion>
                            <workingDirectory>src/frontend</workingDirectory>
                        </configuration>
                        <executions>
                            <execution>
                                <id>install node and npm</id>
                                <goals>
                                    <goal>install-node-and-npm</goal>
                                </goals>
                                <configuration>
                                    <nodeVersion>v15.4.0</nodeVersion>
                                    <npmVersion>7.3.0</npmVersion>
                                </configuration>
                            </execution>
                            <execution>
                                <id>npm install</id>
                                <goals>
                                    <goal>npm</goal>
                                </goals>
                                <configuration>
                                    <arguments>install</arguments>
                                </configuration>
                            </execution>
                            <execution>
                                <id>npm run build</id>
                                <goals>
                                    <goal>npm</goal>
                                </goals>
                                <configuration>
                                    <arguments>run build</arguments>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <!-- The plugin below is for copying the build folder into the target static folder (maven) -->
                    <plugin>
                        <artifactId>maven-resources-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>copy-build-folder</id>
                                <phase>process-classes</phase>
                                <goals>
                                    <goal>copy-resources</goal>
                                </goals>
                                <configuration>
                                    <resources>
                                        <resource>
                                            <directory>src/frontend/build</directory>
                                        </resource>

                                    </resources>
                                    <outputDirectory>${basedir}/target/classes/static</outputDirectory>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

A.Vandijck
  • 59
  • 1
  • 8
  • 1
    I wonder if this is because the ASM library that Jib uses to auto-infer a main class; ASM library may not yet support Java 17. What if you manually specify your main via ``? Also, I recommend upgrading Jib to 3.1.4. – Chanseok Oh Nov 01 '21 at 15:39
  • 1
    Also, run `mvn -X ...` to get the full stack trace and update the question with it. – Chanseok Oh Nov 01 '21 at 18:01
  • The error message unsupported 61 means JDK 16... – khmarbaise Nov 01 '21 at 18:12
  • @ChanseokOh Adding `` to my pom.xml did solve the issue, thanks! If you wish you can add it as an answer. – A.Vandijck Nov 01 '21 at 18:55
  • @khmarbaise Thats actually not true. Version 61 means JDK 17. [Source](https://stackoverflow.com/questions/9170832/list-of-java-class-file-format-major-version-numbers) – A.Vandijck Nov 01 '21 at 18:58
  • Ah sure mistaken that https://javaalmanac.io/bytecode/versions/ – khmarbaise Nov 01 '21 at 19:51

2 Answers2

7

UPDATE(01/20/2022): new Jib version with the bug fix is released. Upgrading Jib will fix it.

However, a few years later when you use Java 18+ or so, you may hit this issue again. Even so, there's a workaround.


Basically, this is a bug in Jib.

Jib uses the ASM library to examine compiled Java bytecode to automatically infer a main class (i.e., one that defines public static void main()). In this way, if you have only one such class, Jib can automatically infer and use that class for an image entrypoint.

The cause in this case is that, Jib is currently not using the latest ASM library that is capable of identifying and understanding bytecode of newer Java versions. The Jib team needs to upgrade the library and make a new Jib release.

Workaround: to prevent Jib from doing auto-inference, you can manually set your desired main class via <container><mainClass>, e.g., <container><mainClass>com.example.your.Main</mainClass>. As with other Jib parameters, this can be set through properties or on the command-line, e.g., -Dcontainer.mainClass=....


Note, although the error was due to ASM in this case, it is of course possible to hit this error for other reasons. You may want to run Maven with -e or -X to get the full stack trace to see where the error is coming from.

Chanseok Oh
  • 3,920
  • 4
  • 23
  • 63
0

I was able to fix it by upgrading my jib-maven-plugin to its latest version (currently, it is 3.2.1). So, update it in your pom.xml file and reload the project by right-clicking on the pom.xml file, selecting 'Maven' and 'Reload project'.

Your jib-maven-plugin shall look something like this:

            <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <container>
                        <ports>
                            <port>8080</port>
                        </ports>
                        <format>OCI</format>
                    </container>
                </configuration>
            </plugin>

Hope this will help.

Sarvar Khalimov
  • 455
  • 5
  • 11