如何检查 *.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 文件,以及静态内容。
我有一个旧的 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 文件,以及静态内容。