Java jdeps command on a springboot jar throws error for Tomcat dependency

1.1k views Asked by At

Im trying to create a custom slimmed down JRE for my springboot application

My pom.xml:

<modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/>
    </parent>
    <groupId>com.owl</groupId>
    <artifactId>POSapi</artifactId>
    <version>1</version>
    <description>owl pos API backend server</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.vavr</groupId>
            <artifactId>vavr</artifactId>
            <version>0.10.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gcp-starter-sql-mysql</artifactId>
            <version>1.2.8.RELEASE</version>
        </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>
        </plugins>
    </build>

</project>

Running just

jdeps -recursive POSapi-1.jar

gives a bunch of not found java dependencies

 com.owl.PosApi                                     -> com.owl.PosApi.Security                            POSapi-1.jar
   com.owl.PosApi                                     -> java.lang                                          java.base
   com.owl.PosApi                                     -> java.util                                          java.base
   com.owl.PosApi                                     -> javax.annotation                                   not found
   com.owl.PosApi                                     -> org.springframework.beans.factory.annotation       not found
   com.owl.PosApi                                     -> org.springframework.boot                           not found
   com.owl.PosApi                                     -> org.springframework.boot.autoconfigure             not found
   com.owl.PosApi                                     -> org.springframework.cache.annotation               not found
   com.owl.PosApi                                     -> org.springframework.context                        not found
   com.owl.PosApi                                     -> org.springframework.context.annotation             not found
   com.owl.PosApi                                     -> org.springframework.security.authentication.dao    not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation     not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation.method.configuration not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation.web not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation.web.builders not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation.web.configuration not found
   com.owl.PosApi                                     -> org.springframework.security.config.annotation.web.configurers not found
   com.owl.PosApi                                     -> org.springframework.security.config.http           not found
   com.owl.PosApi                                     -> org.springframework.security.core.userdetails      not found
   com.owl.PosApi                                     -> org.springframework.security.crypto.bcrypt         not found
   com.owl.PosApi                                     -> org.springframework.security.crypto.password       not found
   com.owl.PosApi.Controller                          -> com.fasterxml.jackson.core                         not found
   com.owl.PosApi.Controller                          -> com.fasterxml.jackson.databind                     not found
   com.owl.PosApi.Controller                          -> com.owl.PosApi.DTO                                 POSapi-1.jar
   com.owl.PosApi.Controller                          -> com.owl.PosApi.Service                             POSapi-1.jar
   com.owl.PosApi.Controller                          -> com.owl.PosApi.model                               POSapi-1.jar
   com.owl.PosApi.Controller                          -> com.owl.PosApi.repositories                        POSapi-1.jar
   com.owl.PosApi.Controller                          -> java.lang                                          java.base
   com.owl.PosApi.Controller                          -> java.lang.invoke                                   java.base
   com.owl.PosApi.Controller                          -> java.time                                          java.base
   com.owl.PosApi.Controller                          -> java.util                                          java.base
   com.owl.PosApi.Controller                          -> java.util.function                                 java.base
   com.owl.PosApi.Controller                          -> javax.transaction                                  not found
   com.owl.PosApi.Controller                          -> org.springframework.beans.factory.annotation       not found
   com.owl.PosApi.Controller                          -> org.springframework.cache.annotation               not found
   com.owl.PosApi.Controller                          -> org.springframework.http                           not found
   com.owl.PosApi.Controller                          -> org.springframework.web.bind.annotation            not found
   com.owl.PosApi.Controller                          -> org.springframework.web.server                     not found
   com.owl.PosApi.DTO                                 -> com.fasterxml.jackson.annotation                   not found
   com.owl.PosApi.DTO                                 -> com.owl.PosApi.DTO                                 POSapi-1.jar
   com.owl.PosApi.DTO                                 -> com.owl.PosApi.model                               POSapi-1.jar
   com.owl.PosApi.DTO                                 -> java.lang                                          java.base
   com.owl.PosApi.DTO                                 -> java.lang.invoke                                   java.base
   com.owl.PosApi.DTO                                 -> java.time                                          java.base
   com.owl.PosApi.DTO                                 -> java.util                                          java.base
   com.owl.PosApi.Security                            -> com.fasterxml.jackson.core                         not found
   com.owl.PosApi.Security                            -> com.fasterxml.jackson.databind                     not found
   com.owl.PosApi.Security                            -> com.owl.PosApi.Security                            POSapi-1.jar
   com.owl.PosApi.Security                            -> java.io                                            java.base
   com.owl.PosApi.Security                            -> java.lang                                          java.base
   com.owl.PosApi.Security                            -> java.lang.invoke                                   java.base
   com.owl.PosApi.Security                            -> java.util                                          java.base
   com.owl.PosApi.Security                            -> javax.persistence                                  not found
   com.owl.PosApi.Security                            -> org.springframework.beans.factory.annotation       not found
   com.owl.PosApi.Security                            -> org.springframework.cache.annotation               not found
   com.owl.PosApi.Security                            -> org.springframework.data.jpa.repository            not found
   com.owl.PosApi.Security                            -> org.springframework.http                           not found
   com.owl.PosApi.Security                            -> org.springframework.security.core.userdetails      not found
   com.owl.PosApi.Security                            -> org.springframework.security.crypto.password       not found
   com.owl.PosApi.Security                            -> org.springframework.stereotype                     not found
   com.owl.PosApi.Security                            -> org.springframework.web.bind.annotation            not found
   com.owl.PosApi.Service                             -> com.fasterxml.jackson.core                         not found
   com.owl.PosApi.Service                             -> com.fasterxml.jackson.databind                     not found
   com.owl.PosApi.Service                             -> com.fasterxml.jackson.databind.node                not found
   com.owl.PosApi.Service                             -> com.owl.PosApi.DTO                                 POSapi-1.jar
   com.owl.PosApi.Service                             -> com.owl.PosApi.Service                             POSapi-1.jar
   com.owl.PosApi.Service                             -> com.owl.PosApi.model                               POSapi-1.jar
   com.owl.PosApi.Service                             -> com.owl.PosApi.repositories                        POSapi-1.jar
   com.owl.PosApi.Service                             -> com.owl.PosApi.repositories.Products               POSapi-1.jar
   com.owl.PosApi.Service                             -> io.vavr                                            not found
   com.owl.PosApi.Service                             -> java.lang                                          java.base
   com.owl.PosApi.Service                             -> java.lang.invoke                                   java.base
   com.owl.PosApi.Service                             -> java.time                                          java.base
   com.owl.PosApi.Service                             -> java.util                                          java.base
   com.owl.PosApi.Service                             -> java.util.function                                 java.base
   com.owl.PosApi.Service                             -> java.util.stream                                   java.base
   com.owl.PosApi.Service                             -> javax.transaction                                  not found
   com.owl.PosApi.Service                             -> org.springframework.beans.factory.annotation       not found
   com.owl.PosApi.Service                             -> org.springframework.cache.annotation               not found
   com.owl.PosApi.Service                             -> org.springframework.http                           not found
   com.owl.PosApi.Service                             -> org.springframework.stereotype                     not found
   com.owl.PosApi.Service                             -> org.springframework.web.server                     not found
   com.owl.PosApi.model                               -> com.fasterxml.jackson.annotation                   not found
   com.owl.PosApi.model                               -> com.owl.PosApi.model                               POSapi-1.jar
   com.owl.PosApi.model                               -> java.io                                            java.base
   com.owl.PosApi.model                               -> java.lang                                          java.base
   com.owl.PosApi.model                               -> java.lang.invoke                                   java.base
   com.owl.PosApi.model                               -> java.time                                          java.base
   com.owl.PosApi.model                               -> java.util                                          java.base
   com.owl.PosApi.model                               -> javax.persistence                                  not found
   com.owl.PosApi.model.Products                      -> com.fasterxml.jackson.annotation                   not found
   com.owl.PosApi.model.Products                      -> com.owl.PosApi.model.Products                      POSapi-1.jar
   com.owl.PosApi.model.Products                      -> java.io                                            java.base
   com.owl.PosApi.model.Products                      -> java.lang                                          java.base
   com.owl.PosApi.model.Products                      -> java.lang.invoke                                   java.base
   com.owl.PosApi.model.Products                      -> java.util                                          java.base
   com.owl.PosApi.model.Products                      -> javax.persistence                                  not found
   com.owl.PosApi.repositories                        -> com.owl.PosApi.model                               POSapi-1.jar
   com.owl.PosApi.repositories                        -> java.lang                                          java.base
   com.owl.PosApi.repositories                        -> java.time                                          java.base
   com.owl.PosApi.repositories                        -> java.util                                          java.base
   com.owl.PosApi.repositories                        -> org.springframework.data.jpa.repository            not found
   com.owl.PosApi.repositories                        -> org.springframework.stereotype                     not found
   com.owl.PosApi.repositories.Products               -> com.owl.PosApi.model.Products                      POSapi-1.jar
   com.owl.PosApi.repositories.Products               -> java.lang                                          java.base
   com.owl.PosApi.repositories.Products               -> org.springframework.data.jpa.repository            not found
   org.springframework.boot.loader                    -> java.io                                            java.base
   org.springframework.boot.loader                    -> java.lang                                          java.base
   org.springframework.boot.loader                    -> java.lang.invoke                                   java.base
   org.springframework.boot.loader                    -> java.lang.reflect                                  java.base
   org.springframework.boot.loader                    -> java.net                                           java.base
   org.springframework.boot.loader                    -> java.nio.charset                                   java.base
   org.springframework.boot.loader                    -> java.security                                      java.base
   org.springframework.boot.loader                    -> java.util                                          java.base
   org.springframework.boot.loader                    -> java.util.function                                 java.base
   org.springframework.boot.loader                    -> java.util.jar                                      java.base
   org.springframework.boot.loader                    -> java.util.regex                                    java.base
   org.springframework.boot.loader                    -> java.util.stream                                   java.base
   org.springframework.boot.loader                    -> java.util.zip                                      java.base
   org.springframework.boot.loader                    -> org.springframework.boot.loader                    POSapi-1.jar
   org.springframework.boot.loader                    -> org.springframework.boot.loader.archive            POSapi-1.jar
   org.springframework.boot.loader                    -> org.springframework.boot.loader.jar                POSapi-1.jar
   org.springframework.boot.loader                    -> org.springframework.boot.loader.util               POSapi-1.jar
   org.springframework.boot.loader.archive            -> java.io                                            java.base
   org.springframework.boot.loader.archive            -> java.lang                                          java.base
   org.springframework.boot.loader.archive            -> java.lang.invoke                                   java.base
   org.springframework.boot.loader.archive            -> java.net                                           java.base
   org.springframework.boot.loader.archive            -> java.util                                          java.base
   org.springframework.boot.loader.archive            -> java.util.function                                 java.base
   org.springframework.boot.loader.archive            -> java.util.jar                                      java.base
   org.springframework.boot.loader.archive            -> java.util.zip                                      java.base
   org.springframework.boot.loader.archive            -> org.springframework.boot.loader.archive            POSapi-1.jar
   org.springframework.boot.loader.archive            -> org.springframework.boot.loader.jar                POSapi-1.jar
   org.springframework.boot.loader.data               -> java.io                                            java.base
   org.springframework.boot.loader.data               -> java.lang                                          java.base
   org.springframework.boot.loader.data               -> org.springframework.boot.loader.data               POSapi-1.jar
   org.springframework.boot.loader.jar                -> java.io                                            java.base
   org.springframework.boot.loader.jar                -> java.lang                                          java.base
   org.springframework.boot.loader.jar                -> java.lang.invoke                                   java.base
   org.springframework.boot.loader.jar                -> java.lang.ref                                      java.base
   org.springframework.boot.loader.jar                -> java.lang.reflect                                  java.base
   org.springframework.boot.loader.jar                -> java.net                                           java.base
   org.springframework.boot.loader.jar                -> java.nio.charset                                   java.base
   org.springframework.boot.loader.jar                -> java.security                                      java.base
   org.springframework.boot.loader.jar                -> java.security.cert                                 java.base
   org.springframework.boot.loader.jar                -> java.time                                          java.base
   org.springframework.boot.loader.jar                -> java.time.temporal                                 java.base
   org.springframework.boot.loader.jar                -> java.util                                          java.base
   org.springframework.boot.loader.jar                -> java.util.concurrent                               java.base
   org.springframework.boot.loader.jar                -> java.util.function                                 java.base
   org.springframework.boot.loader.jar                -> java.util.jar                                      java.base
   org.springframework.boot.loader.jar                -> java.util.logging                                  java.logging
   org.springframework.boot.loader.jar                -> java.util.regex                                    java.base
   org.springframework.boot.loader.jar                -> java.util.stream                                   java.base
   org.springframework.boot.loader.jar                -> java.util.zip                                      java.base
   org.springframework.boot.loader.jar                -> org.springframework.boot.loader.data               POSapi-1.jar
   org.springframework.boot.loader.jar                -> org.springframework.boot.loader.jar                POSapi-1.jar
   org.springframework.boot.loader.jarmode            -> java.io                                            java.base
   org.springframework.boot.loader.jarmode            -> java.lang                                          java.base
   org.springframework.boot.loader.jarmode            -> java.util                                          java.base
   org.springframework.boot.loader.jarmode            -> org.springframework.boot.loader.jarmode            POSapi-1.jar
   org.springframework.boot.loader.jarmode            -> org.springframework.core.io.support                not found
   org.springframework.boot.loader.jarmode            -> org.springframework.util                           not found
   org.springframework.boot.loader.util               -> java.io                                            java.base
   org.springframework.boot.loader.util               -> java.lang                                          java.base
   org.springframework.boot.loader.util               -> java.util                                          java.base

Since it seems jdep doesn't work with springboot JARS I am using this script from here: https://linuxtut.com/how-to-make-spring-boot-docker-image-smaller-51713/

#!/bin/sh
# jdeps-spring-boot

set -eu

readonly TARGET_JAR=$1
readonly TARGET_VER=$2

#Directory to extract the jar
readonly TMP_DIR="/tmp/app-jar"
mkdir -p ${TMP_DIR}
trap 'rm -rf ${TMP_DIR}' EXIT

#Extract the jar
unzip -q "${TARGET_JAR}" -d "${TMP_DIR}"

#output
jdeps \
    -classpath \'${TMP_DIR}/BOOT-INF/lib/*:${TMP_DIR}/BOOT-INF/classes:${TMP_DIR}\' \
    --print-module-deps \
    --ignore-missing-deps \
    --module-path ${TMP_DIR}/BOOT-INF/lib/jakarta.activation-api-1.2.2.jar \
    --recursive \
    --multi-release ${TARGET_VER} \
    -quiet \
    ${TMP_DIR}/org ${TMP_DIR}/BOOT-INF/classes ${TMP_DIR}/BOOT-INF/lib/*.jar

I have java 16 installed, however when I run ./get-springboot-module.sh target/POSapi-1.jar 11

I get the following exception:

Exception in thread "main" java.lang.module.FindException: Module java.annotation not found, 
required by org.apache.tomcat.embed.core

So now i'm stuck, does anyone have any previous experience with this error? It seems like jdep cannot find the tomcat dependency?

0

There are 0 answers