奇怪的 ClassNotFoundException

Weird ClassNotFoundException

当我在eclipse中调试时,这行代码工作正常。

this.primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
                    @Override
                    public void handle(KeyEvent keyEvent) { 
                            InputManager.Instance().addEvent(keyEvent); 
                        }
                });

当我使用我自己的代码(不是脚本)将它导出到 .jar 时,它会抛出一个相当长的异常。

Exception in Application start method
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(Unk
nown Source)
        at com.sun.javafx.application.LauncherImpl.launchApplication(Unknown Sou
rce)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
        at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown So
urce)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication6(
Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: test/Game
        at test.Game.start(Game.java:62)
        at com.sun.javafx.application.LauncherImpl.lambda$launchApplication13
(Unknown Source)
        at com.sun.javafx.application.PlatformImpl.lambda$runAndWait6(Unknown
 Source)
        at com.sun.javafx.application.PlatformImpl.lambda$null4(Unknown Sourc
e)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.application.PlatformImpl.lambda$runLater5(Unknown S
ource)
        at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null9(Unknown Source)
        ... 1 more
Caused by: java.lang.ClassNotFoundException: test.Game
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 10 more
Exception running application test.Game

然而,当我以相同的方式导出它,但处理程序被注释掉时,它工作正常。 我试过 root.addEventHandler、root/primaryStage.setOnKeyPressed,单独声明处理程序,..

你能找出前任的原因吗?

ClassNotFound 异常通常是由于您的 CLASSPATH 环境变量设置不正确造成的。

JVM 一定是从 CLASSPATH 目录遍历了所有地方,但找不到您编译的 *.class 和 java jar 文件。解决此问题的一种方法是使用 java 二进制文件中的 -cp 选项。或者您可以将 CLASSPATH 环境设置为 java 文件所在的目录。

在 Eclipse 中 运行 很好,因为 class 路径设置为工作区并且 IDE 已经为您处理了这个问题。

Read here for more information about CLASSPATH. https://docs.oracle.com/javase/tutorial/essential/environment/paths.html

export it into .jar using my own code

您的 "own code" 不正确,因为它没有将 test/Game.class 文件包含在 .jar 文件中。

您的 class 在 test 包中称为 Game。当 class 使用匿名 classes 时,必须为这些 classes 指定一个名称,以便创建 .class 文件(内部也需要该名称)。此类文件的名称可以是任何名称,但是 current 方案是在定义 class 之后命名,在 $ 符号后添加序号,因此第一个匿名 class 称为 Game.class,第二个将称为 Game.class,依此类推。

这就是为什么当您编译 Game.java 时,您最终会得到 2 个文件:Game.classGame.class必须将这些文件 添加到 .jar 文件中。

你不应该依赖这个命名约定,如果可能的话,因为它可能会在未来发生变化,而其他编译器可能会以不同的方式进行。