如何检查 *.war 文件的导入?

How to check imports of a *.war file?

我有一个旧的 war 文件,其中的源代码在我的旧机器过世时丢失了。

运行 tomcat 8 没问题。

在我的新机器上,当 tomcat(8 和 9)尝试部署 war 文件时,它给我

... 10 more Caused by: java.lang.ClassNotFoundException: javafx.scene.image.Image at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1358) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1180) ... 23 more

我不记得在我的代码中直接使用过 javafx。

那么,如何检查 *.war 文件的导入以查看是哪个 class 或库导致了问题?

我已经在示例 classes 上尝试过 javap,但从未看到任何导入。

我是ware,javafx 不再是 运行time 环境的一部分,这显然是问题的直接原因,但是,对于这个应用程序,javafx 不应该是根本不需要。

运行 javap -v -constants 在您的 .class 文件上查看 class 参考资料。

您可能希望通过 grep "= Class" (Linux) 或 findstr "=\ Class" (Windows) 或 grep javafx / findstr javafx.

例如即使是超级简单的 "Hello World" 程序也会使用多个 classes.

public class Test {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

输出

C:\path\to\classes\classes>javap -v -constants Test.class | grep "= Class"
   #1 = Class              #2             // Test
   #3 = Class              #4             // java/lang/Object
  #17 = Class              #18            // java/lang/System
  #25 = Class              #26            // java/io/PrintStream

它没有显示 String 的用法。要了解原因,请查看完整的常量池,对于那个小程序来说是:

Constant pool:
   #1 = Class              #2             // Test
   #2 = Utf8               Test
   #3 = Class              #4             // java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               <init>
   #6 = Utf8               ()V
   #7 = Utf8               Code
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               LTest;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Fieldref           #17.#19        // java/lang/System.out:Ljava/io/PrintStream;
  #17 = Class              #18            // java/lang/System
  #18 = Utf8               java/lang/System
  #19 = NameAndType        #20:#21        // out:Ljava/io/PrintStream;
  #20 = Utf8               out
  #21 = Utf8               Ljava/io/PrintStream;
  #22 = String             #23            // Hello World
  #23 = Utf8               Hello World
  #24 = Methodref          #25.#27        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #25 = Class              #26            // java/io/PrintStream
  #26 = Utf8               java/io/PrintStream
  #27 = NameAndType        #28:#29        // println:(Ljava/lang/String;)V
  #28 = Utf8               println
  #29 = Utf8               (Ljava/lang/String;)V
  #30 = Utf8               args
  #31 = Utf8               [Ljava/lang/String;
  #32 = Utf8               SourceFile
  #33 = Utf8               Test.java

因为你不需要所有的字符串常量,你可以使用 grep -v Utf8:

   #1 = Class              #2             // Test
   #3 = Class              #4             // java/lang/Object
   #8 = Methodref          #3.#9          // java/lang/Object."<init>":()V
   #9 = NameAndType        #5:#6          // "<init>":()V
  #16 = Fieldref           #17.#19        // java/lang/System.out:Ljava/io/PrintStream;
  #17 = Class              #18            // java/lang/System
  #19 = NameAndType        #20:#21        // out:Ljava/io/PrintStream;
  #22 = String             #23            // Hello World
  #24 = Methodref          #25.#27        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #25 = Class              #26            // java/io/PrintStream
  #27 = NameAndType        #28:#29        // println:(Ljava/lang/String;)V

WAR 存档是压缩的 zip 文件。您可以使用 WinRar(在 Windows 中)或解压缩(在 Linux 中)等任何工具或您喜欢的任何工具来提取它们。解压缩后,您将获得存档的目录和文件。在其中,您将找到您使用的所有其他库和 class 文件,以及静态内容。