1

我正在尝试jdeprscan我的 CentOS 系统。以下是我正在执行的命令:

export classpath=<PATH/*>:<ANOTHER/PATH/*>:<SOME/OTHER/PATH/*>
jdeprscan --for-removal --verbose --class-path $classpath --release 9 <ANOTHER/PATH>/MyProject.jar

尽管提供了类路径,但我遇到了多个此类错误

Processing class <some/class/in/MyProject.jar>...
error: cannot find class <some/class/in/a/different/jar>
error: cannot resolve Methodref <some/class/in/a/different/jar>.<method>:()Ljava/lang/String;

我已经验证错误消息中提到的类几乎是类路径中提供的 jar 之一。奇怪的是,对于我正在扫描的 jar 中引用的所有其他类,我并没有收到此错误。

几点供大家参考:

  • 类路径中提供的路径中有 50 多个 jar
  • 我试图扫描的 jar 位于类路径中提到的路径之一中
  • 我已经尝试过 JDK 9 和 JDK 10 中可用的 jdeprscan 并得到相同的错误
  • 我试过用*.jar替换类路径中的 * ,没有帮助!

我遵循的语法有什么问题,还是 jdeprscan 中的一个已知错误?

4

2 回答 2

3

Windows 下 Oracle JDK 11 的一些初步说明jdeprscsan(我知道与 CentOS 上的 JDK 9 相关的问题,但也许以下也适用......):

  • 使用通配符“path/to/lib/*.jar”(如果没有“.jar”扩展名,它将无法工作)
  • 不支持具有多个路径的通配符(即--class-path dir1/;dir2/*.jar在通配符上引发解析异常)
  • 指定目录中的 JAR--class-path被添加到类路径并按字母顺序分析,这可能会导致一些error : cannot find class X消息,因为 JARa.jar可能依赖于b.jar尚未加载的 JAR。

基于以上,我找到了以下3个解决方案。请注意,我jdeprscan从 Oracle JDK 12.0.2 进行了相同的实验,没有任何改进。

解决方案1:类路径上的所有类

  1. 解压缩特定目录中的所有 JAR(忽略 META-INF/maven/pom.xml 等被覆盖的文件),例如mylib(请注意,在此阶段,mylibs 目录仅包含由目录包组织的类,没有 JAR)。
  2. 运行以下命令:

jdeprscan --for-removal --class-path /path/to/mylib /path/to/my-application.jar

优点:速度快(非常手动操作)

缺点:只分析已经在命令行(my-application.jar)指定的JAR文件

解决方案 2:所有 JAR + 类路径上的胖 JAR

  1. 将所有 JAR 库复制到一个mylib目录中
  2. 从(忽略重复文件)的 JAR 中提取所有文件mylib并将它们重新打包到一个大 JARmylib/00lib.jar中(一个简单的 ZIP 文件重命名为.jar诀窍)
  3. 复制mylib/00lib.jarmylib/01lib.jar确保对其进行分析
  4. 运行以下命令:

    jdeprscan --for-removal --verbose --class-path path/to/mylib/*.jar path/to/my-application.jar

优点:快速(只需少量手动操作)+ 分析来自mylib

缺点:一些jdeprscan消息将与胖 JAR 相关,00lib.jar因此您将无法立即确定哪个库使用了已弃用或从 Java 9 或 11 中删除的类,但您可以通过查看类名间接地做到这一点,例如(com.atomikos库中的一个类需要缺少的类javax.jms.JMSException):

Processing class com/atomikos/datasource/xa/jms/JmsTransactionalResource...
error: cannot find class javax/jms/JMSException

解决方案 3:对类路径中的 JAR 文件重新排序

  1. 将所有 JAR 库复制到一个mylib目录中
  2. 运行以下命令:

    jdeprscan --for-removal --class-path path/to/mylib/*.jar path/to/my-application.jar

  3. 检查日志以查看error: cannot find class不应引发的消息,因为 JAR 存在于 lib 目录中。对于每个这样的库,复制一个名称在按字母顺序引用它的库名称之前的库。例如,我在 lib 目录中有一个 JAR,alpha.jar它依赖于commons-lang-3.0.jar(尚未加载到类路径中),所以我复制commons-lang-3.0.jara0commons-lang-3.0.jar它以便在alpha.jar. 复制 JAR 并且不要重命名它很重要,否则它可能不会被分析jdeprscan(不会出现在每个 JAR 上)。完成后,返回第 2 步,直到没有出现库依赖项产生的错误消息。

优点:清楚地显示哪些 JAR 使用了已弃用/已删除的类。

缺点:需要很多时间(每个 JAR 的手动副本会导致类加载问题)。

结论

jdeprscan解决方案 2一起使用。这应该被视为一种解决方法(它是不完整的工具文档还是错误,我不知道......)。

于 2019-07-26T09:47:25.243 回答
0

如果您碰巧在 PATH 中有一个包含类JAR 的文件夹,它将无法工作。您必须单独指定 JAR(或摆脱类)。

于 2018-09-25T10:02:48.837 回答