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

Sim*_*ano 5 java tomcat jlink jdeps java-module

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

\n

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

\n

我已经对此进行了几次尝试:

\n

1)jdeps在整个目录上运行

\n

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

\n
> tree -L 1 /usr/local/tomcat/                                                                                                                  \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 LICENSE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 NOTICE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 RELEASE-NOTES\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 db.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 favicon.ico\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 run\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 save.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 start.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 stop.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 temp\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webapps\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 work\n\n> find . -name "*.jar" -o -name "*.class" | wc -l                                                                                             \n     938\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
> jdeps --recursive --print-module-deps --ignore-missing-deps /usr/local/tomcat/\njava.base,java.compiler,java.desktop,java.management,java.naming,java.scripting,java.sql\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
com.my.app -> org.eclipse.jgit.diff  not found\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

2)在目录的每个jar/class文件上运行jdeps

\n

我已经测试过在每个 jar 上运行 jdeps 以添加缺少的模块,尽管更直接/有效的方法jdeps会更好。

\n

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

\n

终端截图

\n

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

\n

不确定是否jdeps可以在这样的完整 tomcat 目录上运行,我尝试将所有 jar 提供给-cpjdeps 的类路径选项,看起来它摆脱了一些“未找到”条目(262 => 43) 。添加类没有什么区别。

\n

我仍然需要--ignore-missing-deps结合使用--print-module-deps与tail -1

\n
> tree -L 1 /usr/local/tomcat/                                                                                                                  \n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 LICENSE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 NOTICE\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 RELEASE-NOTES\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 conf\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 db.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 favicon.ico\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 logs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 run\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 save.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 start.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 stop.sh\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 temp\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webapps\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 work\n\n> find . -name "*.jar" -o -name "*.class" | wc -l                                                                                             \n     938\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

这仍然不完美,例如我发现该应用程序使用jar:// FileSystemProvider。java类中没有具体的信息import,因此jdeps无法知道应用程序需要jdk.zipfs模块来安装jar...

\n

结论

\n

对我的二进制文件没有信心;

\n

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

\n