未找到 Jdeps 模块 java.annotation
Jdeps Module java.annotation not found
我正在尝试使用 jdeps 和 jlink 为 Spring 引导微服务创建一个最小的 jre,但是当我使用 jdeps 部分时出现以下错误
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:893)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:192)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:421)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:255)
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)
我已经尝试了以下命令但没有效果
jdeps --ignore-missing-deps --multi-release 17 --module-path target/lib/* target/errorrr-*.jar
jdeps --multi-release 16 --module-path target/lib/* target/errorrr-*.jar
jdeps --ignore-missing-deps --multi-release 17 --class-path target/lib/* target/errorrr-*.jar
我已经用 java 版本 11、16 和 17 以及 Spring Boot 的不同版本进行了尝试。
当我 运行 mvn install
时,maven-dependency-plugin 插件将构建所需的所有依赖项复制到 target/lib 文件夹
在确定负责任的依赖关系后,我从头开始创建了一个新项目,仅用它来隔离错误,但它仍然存在。
我一开始尝试使用 gradle 但由于错误仍然存在,我将其更改为 mavem 但也没有改变。
当我添加所请求的指定依赖项时,错误更改为
#13 1.753 Exception in thread "main" java.lang.Error: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:271)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.parse(DependencyFinder.java:133)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DepsAnalyzer.run(DepsAnalyzer.java:129)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.ModuleExportsAnalyzer.run(ModuleExportsAnalyzer.java:74)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask$ListModuleDeps.run(JdepsTask.java:1047)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:574)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
#13 1.753 Caused by: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
#13 1.753 at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
#13 1.753 at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:267)
#13 1.754 ... 7 more
#13 1.754 Caused by: com.sun.tools.jdeps.MultiReleaseException
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.VersionHelper.add(VersionHelper.java:62)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileReader.readClassFile(ClassFileReader.java:360)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileIterator.hasNext(ClassFileReader.java:402)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.lambda$parse(DependencyFinder.java:179)
#13 1.754 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
#13 1.754 at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
#13 1.754 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
#13 1.754 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
#13 1.754 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
#13 1.754 at java.base/java.lang.Thread.run(Thread.java:833)
我的pom.xml
<?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.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>errorrr</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>errorrr</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
如果我不需要使用这个依赖项,我可以完成所有的构建过程,最后我有一个 76mb 的 jre
我一直在为我的 gradle spring 引导项目中的类似问题而苦苦挣扎
我正在使用以下输出在我的 dockerfile 中的 jlink 中添加模块 (openjdk:17-alpine
):
RUN jdeps \
--ignore-missing-deps \
-q \
--multi-release 17 \
--print-module-deps \
--class-path build/lib/* \
app.jar > deps.info
RUN jlink --verbose \
--compress 2 \
--strip-java-debug-attributes \
--no-header-files \
--no-man-pages \
--output jre \
--add-modules $(cat deps.info)
我认为只要您拥有所有必需的依赖项,您的 mvn 构建就可以了。但以防万一我修改了我的 gradle jar 任务以包含如下依赖项:
jar {
manifest {
attributes "Main-Class": "com.demo.Application"
}
duplicatesStrategy = DuplicatesStrategy.INCLUDE
from {
configurations.default.collect { it.isDirectory() ? it : zipTree(it)
}
}
}
我找到了一个有效但不完美但可以正常工作的解决方案。
在我的例子中,lib“jackson”是问题的原因。它使用 java 多版本,并且在 jdeps 期间以某种方式导致了一些错误。
经过一些测试后,我明白我可以从评估中删除这个库,并且 deps.info 中不会缺少任何模块。
我需要添加此任务以进行删除:
task myDeleteTask(type: Delete) {
delete files("${buildDir}/temp-lib/jackson-databind-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-datatype-jdk8-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-datatype-jsr310-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-module-parameter-names-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-core-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-dataformat-cbor-{your_version}.jar")
}
task tempCopyDependencies(type: Copy) {
from configurations.runtimeClasspath
into "$buildDir/temp-lib"
}
tasks.named("build"){
finalizedBy("tempCopyDependencies")
finalizedBy("myDeleteTask")
}
OBS:题中我用maven是因为比较简单,知识面也比较广,但是我的实际项目用的是gradle,这样删除任务就更容易了
我遇到了类似的问题,对我的情况有所帮助 - 指定 --class-path
和 --module-path
都指向与库相同的目录。
根据你的例子,我觉得应该是jdeps --ignore-missing-deps --print-module-deps --multi-release 17 --module-path="target/lib/*" --class-path="target/lib/*" target/errorrr-*.jar
.
此外,jdeps
来自 JDK 17(可能还有更早的版本)。它似乎已在 JDK 18 中修复,至少它对我来说没有任何问题。
使用 Docker 您可以进行分阶段构建,首先使用 JDK 18 识别依赖项,然后使用 JDK 17 构建新的 JRE 映像。像这样:
FROM amazoncorretto:18-alpine as deps
COPY ./app.jar /app/app.jar
RUN mkdir /app/unpacked && \
cd /app/unpacked && \
unzip ../app.jar && \
cd .. && \
$JAVA_HOME/bin/jdeps \
--ignore-missing-deps \
--print-module-deps \
-q \
--recursive \
--multi-release 17 \
--class-path="./unpacked/BOOT-INF/lib/*" \
--module-path="./unpacked/BOOT-INF/lib/*" \
./app.jar > /deps.info
FROM amazoncorretto:17.0.3-alpine as corretto-jdk
RUN apk add --no-cache binutils
COPY --from=deps /deps.info /deps.info
RUN $JAVA_HOME/bin/jlink \
--verbose \
--add-modules $(cat /deps.info) \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output /customjre
您可以在此处查看完整示例:https://github.com/monosoul/jvm-in-docker/blob/main/jre-slim-auto.dockerfile
对于任何感兴趣的人,这里有一篇关于使用 jlink
和 jdeps
的博客文章:https://blog.monosoul.dev/2022/04/25/reduce-java-docker-image-size/
我正在尝试使用 jdeps 和 jlink 为 Spring 引导微服务创建一个最小的 jre,但是当我使用 jdeps 部分时出现以下错误
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:893)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:192)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:421)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:255)
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)
我已经尝试了以下命令但没有效果
jdeps --ignore-missing-deps --multi-release 17 --module-path target/lib/* target/errorrr-*.jar
jdeps --multi-release 16 --module-path target/lib/* target/errorrr-*.jar
jdeps --ignore-missing-deps --multi-release 17 --class-path target/lib/* target/errorrr-*.jar
我已经用 java 版本 11、16 和 17 以及 Spring Boot 的不同版本进行了尝试。
当我 运行 mvn install
时,maven-dependency-plugin 插件将构建所需的所有依赖项复制到 target/lib 文件夹在确定负责任的依赖关系后,我从头开始创建了一个新项目,仅用它来隔离错误,但它仍然存在。
我一开始尝试使用 gradle 但由于错误仍然存在,我将其更改为 mavem 但也没有改变。
当我添加所请求的指定依赖项时,错误更改为
#13 1.753 Exception in thread "main" java.lang.Error: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:271)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.parse(DependencyFinder.java:133)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DepsAnalyzer.run(DepsAnalyzer.java:129)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.ModuleExportsAnalyzer.run(ModuleExportsAnalyzer.java:74)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask$ListModuleDeps.run(JdepsTask.java:1047)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:574)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
#13 1.753 Caused by: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
#13 1.753 at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
#13 1.753 at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
#13 1.753 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:267)
#13 1.754 ... 7 more
#13 1.754 Caused by: com.sun.tools.jdeps.MultiReleaseException
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.VersionHelper.add(VersionHelper.java:62)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileReader.readClassFile(ClassFileReader.java:360)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileIterator.hasNext(ClassFileReader.java:402)
#13 1.754 at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.lambda$parse(DependencyFinder.java:179)
#13 1.754 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
#13 1.754 at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
#13 1.754 at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
#13 1.754 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
#13 1.754 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
#13 1.754 at java.base/java.lang.Thread.run(Thread.java:833)
我的pom.xml
<?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.6.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>errorrr</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>errorrr</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
如果我不需要使用这个依赖项,我可以完成所有的构建过程,最后我有一个 76mb 的 jre
我一直在为我的 gradle spring 引导项目中的类似问题而苦苦挣扎
我正在使用以下输出在我的 dockerfile 中的 jlink 中添加模块 (openjdk:17-alpine
):
RUN jdeps \
--ignore-missing-deps \
-q \
--multi-release 17 \
--print-module-deps \
--class-path build/lib/* \
app.jar > deps.info
RUN jlink --verbose \
--compress 2 \
--strip-java-debug-attributes \
--no-header-files \
--no-man-pages \
--output jre \
--add-modules $(cat deps.info)
我认为只要您拥有所有必需的依赖项,您的 mvn 构建就可以了。但以防万一我修改了我的 gradle jar 任务以包含如下依赖项:
jar {
manifest {
attributes "Main-Class": "com.demo.Application"
}
duplicatesStrategy = DuplicatesStrategy.INCLUDE
from {
configurations.default.collect { it.isDirectory() ? it : zipTree(it)
}
}
}
我找到了一个有效但不完美但可以正常工作的解决方案。 在我的例子中,lib“jackson”是问题的原因。它使用 java 多版本,并且在 jdeps 期间以某种方式导致了一些错误。 经过一些测试后,我明白我可以从评估中删除这个库,并且 deps.info 中不会缺少任何模块。 我需要添加此任务以进行删除:
task myDeleteTask(type: Delete) {
delete files("${buildDir}/temp-lib/jackson-databind-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-datatype-jdk8-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-datatype-jsr310-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-module-parameter-names-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-core-{your_version}.jar")
delete files("${buildDir}/temp-lib/jackson-dataformat-cbor-{your_version}.jar")
}
task tempCopyDependencies(type: Copy) {
from configurations.runtimeClasspath
into "$buildDir/temp-lib"
}
tasks.named("build"){
finalizedBy("tempCopyDependencies")
finalizedBy("myDeleteTask")
}
OBS:题中我用maven是因为比较简单,知识面也比较广,但是我的实际项目用的是gradle,这样删除任务就更容易了
我遇到了类似的问题,对我的情况有所帮助 - 指定 --class-path
和 --module-path
都指向与库相同的目录。
根据你的例子,我觉得应该是jdeps --ignore-missing-deps --print-module-deps --multi-release 17 --module-path="target/lib/*" --class-path="target/lib/*" target/errorrr-*.jar
.
此外,jdeps
来自 JDK 17(可能还有更早的版本)
使用 Docker 您可以进行分阶段构建,首先使用 JDK 18 识别依赖项,然后使用 JDK 17 构建新的 JRE 映像。像这样:
FROM amazoncorretto:18-alpine as deps
COPY ./app.jar /app/app.jar
RUN mkdir /app/unpacked && \
cd /app/unpacked && \
unzip ../app.jar && \
cd .. && \
$JAVA_HOME/bin/jdeps \
--ignore-missing-deps \
--print-module-deps \
-q \
--recursive \
--multi-release 17 \
--class-path="./unpacked/BOOT-INF/lib/*" \
--module-path="./unpacked/BOOT-INF/lib/*" \
./app.jar > /deps.info
FROM amazoncorretto:17.0.3-alpine as corretto-jdk
RUN apk add --no-cache binutils
COPY --from=deps /deps.info /deps.info
RUN $JAVA_HOME/bin/jlink \
--verbose \
--add-modules $(cat /deps.info) \
--strip-debug \
--no-man-pages \
--no-header-files \
--compress=2 \
--output /customjre
您可以在此处查看完整示例:https://github.com/monosoul/jvm-in-docker/blob/main/jre-slim-auto.dockerfile
对于任何感兴趣的人,这里有一篇关于使用 jlink
和 jdeps
的博客文章:https://blog.monosoul.dev/2022/04/25/reduce-java-docker-image-size/