6

我一直在使用 JLink 为各种 Spring Boot 应用程序创建最小的 JRE。通过反复试验找出所需的模块,我已经成功地手动完成了这项工作。成功完成此操作后,我一直在尝试使用 JDeps 自动化此过程。

第一次尝试是为我的应用程序扫描构建的 Jar。我正在使用 Java 14 jdeps 分析 Java 11 代码库。

jdeps --class-path BOOT-INF/classes --module-path BOOT-INF/lib/,${JAVA_HOME}/jmods --add-modules=ALL-MODULE-PATH --list-deps target/camel-account-sapi-0.0.2-SNAPSHOT.jar

这会导致几个未找到的依赖项。

Error: Missing dependencies: classes not found from the module path and classpath.
To suppress this error, use --ignore-missing-deps to continue.

camel-account-sapi-0.0.2-SNAPSHOT.jar
   com.ms3.camelaccountsapi.CamelAccountSapiApplication -> org.springframework.boot.SpringApplication         not found
   com.ms3.camelaccountsapi.CamelAccountSapiApplication -> org.springframework.boot.autoconfigure.SpringBootApplication not found
   com.ms3.camelaccountsapi.CamelAccountSapiApplication -> org.springframework.context.ConfigurableApplicationContext not found
   com.ms3.camelaccountsapi.routes.GeneratedRoutesInterface -> org.apache.camel.builder.RouteBuilder              not found
   com.ms3.camelaccountsapi.routes.GeneratedRoutesInterface -> org.apache.camel.model.rest.RestDefinition         not found
   com.ms3.camelaccountsapi.routes.GeneratedRoutesInterface -> org.apache.camel.model.rest.RestOperationParamDefinition not found
   com.ms3.camelaccountsapi.routes.GeneratedRoutesInterface -> org.apache.camel.model.rest.RestParamType          not found
   com.ms3.camelaccountsapi.routes.GeneratedRoutesInterface -> org.springframework.stereotype.Component           not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> com.datasonnet.document.MediaTypes                 not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.Exchange                          not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.Expression                        not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.LoggingLevel                      not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.Predicate                         not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.builder.DatasonnetBuilder         not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.builder.RouteBuilder              not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.builder.SimpleBuilder             not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.builder.ValueBuilder              not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.model.ChoiceDefinition            not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.model.OnExceptionDefinition       not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.model.ProcessorDefinition         not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.apache.camel.model.RouteDefinition             not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.slf4j.Logger                                   not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.slf4j.LoggerFactory                            not found
   com.ms3.camelaccountsapi.routes.RoutesImplementation -> org.springframework.stereotype.Component           not found
   org.springframework.boot.loader.PropertiesLauncher -> org.springframework.util.Assert                    not found
   org.springframework.boot.loader.jarmode.JarModeLauncher -> org.springframework.core.io.support.SpringFactoriesLoader not found
   org.springframework.boot.loader.jarmode.JarModeLauncher -> org.springframework.util.ClassUtils                not found

添加--ignore-missing-deps更完整但不完整的结果:

java.base
java.logging

接下来我使用java -Djarmode=layertools -jar ./target/camel-account-sapi-0.0.2-SNAPSHOT.jar extract

这给了我包含所有 150 个 JAR 依赖项的 BOOT-INF/lib 文件夹。因此,我尝试使用一些额外的选项来运行与以前类似的 JDeps 命令: jdeps --module-path temp/BOOT-INF/lib/,${JAVA_HOME}/jmods --add-modules=ALL-MODULE-PATH --multi-release 11 --list-deps --ignore-missing-deps --recursive --compile-time temp/BOOT-INF/lib/*

然而,这会导致异常

Exception in thread "main" java.lang.module.FindException: Module java.annotation not found, required by org.apache.tomcat.embed.core
    at java.base/java.lang.module.Resolver.findFail(Resolver.java:894)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:191)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:140)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:422)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:256)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
    at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)

我注意到 /lib 文件夹中的一些 JAR 可以成功分析,因此我编写了一个 Bash 脚本来在每个 /lib jar 上运行相同的命令,同时忽略异常。150 个模块中的 15 个无法分析,因为Module not found来自其他 135 个模块的所需模块的结果列表非常接近。它只缺少一个必需的模块jdk.crypto.ec并找到所有其他模块:

java.sql,java.security.jgss,java.logging,java.xml,java.compiler,jdk.unsupported,java.transaction.xa,java.rmi,java.management,java.instrument,java.naming,java.base,java.datatransfer,jdk.httpserver,java.scripting,java.desktop,java.prefs

我走错方向了吗?或者可以/应该做些什么来解决这些缺失的模块问题?我相信,例如,上面的“缺失”模块java.annotation可能存在于其他 JAR 之一中?由于其他 15 个失败的 jdeps 命令中的一些,我认为情况更是如此。

temp/BOOT-INF/lib/tomcat-embed-core-9.0.38.jar
Exception in thread "main" java.lang.module.FindException: Module java.annotation not found, required by org.apache.tomcat.embed.core
    at java.base/java.lang.module.Resolver.findFail(Resolver.java:894)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:191)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:140)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:422)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:256)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
    at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
error
temp/BOOT-INF/lib/tomcat-embed-websocket-9.0.38.jar
Exception in thread "main" java.lang.module.FindException: Module org.apache.tomcat.embed.core not found, required by org.apache.tomcat.embed.websocket
    at java.base/java.lang.module.Resolver.findFail(Resolver.java:894)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:191)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:140)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:422)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:256)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
    at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
error
4

1 回答 1

0

我现在正在解决一个非常相似的问题。看起来在 tomcat embed 9.0.37 和 9.0.38 之间定义了显式模块信息。与自动模块相比,模块的名称发生了变化。

  • java.annotationmodule 是从 annotations-api.jar 导出的名称。我不知道为什么它使用这个名字。肯定是有原因的,就是不明白。
  • org.apache.tomcat.embed.jasper.el变成org.apache.tomcat.embed.el

我不确定这会让你走多远,但这可能是一个开始。

于 2020-10-08T21:48:31.940 回答