如何使用jdeps计算所需的java模块列表?

发布于 2025-01-10 06:03:22 字数 3087 浏览 2 评论 0原文

我基本上正在使用一个具有复杂结构的 tomcat web 应用程序,在多个位置有许多 jar 和类,我想使用 jlink 及其 --add-modules< 生成一个 JRE /code> 选项,以减少我使用的二进制文件的重量和攻击面。

澄清一下,如果我使用 jlink --add-modules ALL-MODULE-PATH 包含所有模块,则一切都会顺利运行。

我已经进行了几次尝试:

1) 在整个目录上运行 jdeps

我需要分析的目标是一个经典的 tomcat 结构,其中在多个位置包含 jar 和类。

> tree -L 1 /usr/local/tomcat/                                                                                                                  
├── LICENSE
├── NOTICE
├── RELEASE-NOTES
├── bin
├── conf
├── db.sh
├── favicon.ico
├── lib
├── logs
├── run
├── save.sh
├── start.sh
├── stop.sh
├── temp
├── webapps
└── work

> find . -name "*.jar" -o -name "*.class" | wc -l                                                                                             
     938

我一直在尝试以多种方式使用 jdeps,但是 文档 不是很有帮助。下面是返回类似于我所期望的内容的唯一命令:

> jdeps --recursive --print-module-deps --ignore-missing-deps /usr/local/tomcat/
java.base,java.compiler,java.desktop,java.management,java.naming,java.scripting,java.sql

这种工作按预期进行,但似乎只考虑了类。如果没有 --print-module-deps 我会得到一大堆像这样的未知依赖项

com.my.app -> org.eclipse.jgit.diff  not found

即使依赖项已正确安装在 /usr/local/tomcat/webapps/ROOT/WEB-INF /lib/org.eclipse.jgit-5.10.0.202012080955-r.jar

一个明显的结果是,有很多未列出的所需模块,并且当使用自定义 JRE 执行应用程序时,由于缺少 java 模块,我会收到错误。

2)在我测试过的目录的每个jar/类文件上运行jdeps,

在每个jar上运行jdeps以添加缺少的模块,尽管使用jdeps的更直接/有效的方法会更好。

查找 . -名称“*.jar”-o -名称“*.class”| xargs jdeps --print-module-deps --ignore-missing-deps 似乎可以解决这个基本用例,但是当应用于更大的 tomcat 项目时,仍然存在运行时异常,所以我认为 ignore-missing-deps 使其毫无意义。

终端截图

3) 在目录上运行 jdeps,将所有 jar 文件提供给 jdeps 的类路径选项

不确定 jdeps 是否在完整的 tomcat 目录上运行,我尝试提供将所有 jar 文件添加到 jdeps 的 -cp 类路径选项中,并且看起来它消除了一些“未找到”条目(262 => 43)。添加类没有什么区别。

我仍然需要将 --ignore-missing-deps--print-module-deps 和 a tail -1 结合使用来忽略“拆分包”的少量内容警告

# run jdeps on directory (might need `apk -U add findutils` on alpine)
jdeps --multi-release 17 --recursive -cp "$(find . -name "*.jar" -printf "%h/*\n" | sort -u | paste -sd ":")" --ignore-missing-deps --print-module-deps ./  | tail -1

使用此输出,我可以将原来包含 68 个 java 模块的完整列表减少到只有 17 个,从而获得大约 22MB 的空间。 不确定攻击面,但我已经看到了更好的减重效果!

这仍然不完美,例如我发现该应用使用 jar:// 文件系统提供程序。 java类中没有特定的import,因此jdeps无法知道应用程序需要jdk.zipfs模块来挂载jar...

结论

对我的没有信心二进制;

为什么 jdeps 仍然给我 not find 错误和 split package 警告,我该如何解决这个问题?

I'm basically working with a tomcat webapp that has a complex structure, with many jars and classes at several locations and I want to generate a JRE with jlink and its --add-modules option in order to reduce the weight and attack surface of the binaries I use.

To clarify, if I include all modules with jlink --add-modules ALL-MODULE-PATH everything runs smoothly.

I've given this a few attempts:

1) run jdeps on whole dir

The target I need to analyse is a classic tomcat structure, which contains jars and classes at several locations.

> tree -L 1 /usr/local/tomcat/                                                                                                                  
├── LICENSE
├── NOTICE
├── RELEASE-NOTES
├── bin
├── conf
├── db.sh
├── favicon.ico
├── lib
├── logs
├── run
├── save.sh
├── start.sh
├── stop.sh
├── temp
├── webapps
└── work

> find . -name "*.jar" -o -name "*.class" | wc -l                                                                                             
     938

I've been trying to use jdeps in several ways but the docs are not super helpfull. Below is the only command that returned something looking like what I'd expect:

> jdeps --recursive --print-module-deps --ignore-missing-deps /usr/local/tomcat/
java.base,java.compiler,java.desktop,java.management,java.naming,java.scripting,java.sql

That kind of works as expected, but it seems to only take the classes into account. Without --print-module-deps I get a whole bunch of unknown dependencies like this

com.my.app -> org.eclipse.jgit.diff  not found

Even though the dependecy is properly installed at /usr/local/tomcat/webapps/ROOT/WEB-INF/lib/org.eclipse.jgit-5.10.0.202012080955-r.jar.

As an obvious consequence, there are a lot of unlisted needed modules, and when executing the app with the custom JRE, I get errors because of the missing java modules.

2) Run jdeps on each jar/class file of the directory

I've tested runnning jdeps on every single jar to add the missing modules, even though a more direct / efficient approach with jdeps would be better.

The find . -name "*.jar" -o -name "*.class" | xargs jdeps --print-module-deps --ignore-missing-deps seems to do the trick on this basic usecase, but when applied to the bigger tomcat project, there still are runtime exceptions so I think the ignore-missing-deps makes it pointless.

terminal screenshot

3) Run jdeps on directory, providing all jar files to the classpath option of jdeps

Not being sure if jdeps is made to run on a full tomcat directory like that, I tried providing all jars to the -cp classpath option of jdeps, and it looks like it gets rid of some of the "not found" entries (262 => 43). Adding the classes makes no difference.

I still need to use --ignore-missing-deps in conjuction with --print-module-deps an a tail -1 to ignore the handfull of "split package" warnings

# run jdeps on directory (might need `apk -U add findutils` on alpine)
jdeps --multi-release 17 --recursive -cp "$(find . -name "*.jar" -printf "%h/*\n" | sort -u | paste -sd ":")" --ignore-missing-deps --print-module-deps ./  | tail -1

Using this output, I can go from the original full list of 68 java modules to only 17, gaining approximately 22MB. Not sure about the attack surface, but I've seen better results on weigh reduction!

This is still unperfect, for example I figured out that the app uses the jar:// FileSystemProvider. There is no specific import in the java class, so jdeps can't know that the app need the jdk.zipfs module to mount jars...

Conclusion

Not confident about my binary;

Why does jdeps still gives me not found errors and split package warnings, how can I fix that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文