JavaFX本机打包-初始化静态变量时出现奇怪的错误

JavaFX本机打包-初始化静态变量时出现奇怪的错误,java,javafx,exe,native,packaging,Java,Javafx,Exe,Native,Packaging,我正在Netbeans中进行一个JavaFX项目,目前大约有3000行长,我已经定期打包为.exe进行测试,但从未遇到过像这样奇怪的问题 当以本机方式打包为Windows.exe文件时,我发现在安装.exe并启动我的程序后,我得到一个弹出窗口,上面写着“类{mypackage}/{mymainclass}未找到。”,然后是“未能启动JVM。” 在Netbeans中启动程序,打包为.exe,在Powershell中启动带有“java-jar{app}.jar”的.jar,所有这些都绝对没有错误。即

我正在Netbeans中进行一个JavaFX项目,目前大约有3000行长,我已经定期打包为.exe进行测试,但从未遇到过像这样奇怪的问题

当以本机方式打包为Windows.exe文件时,我发现在安装.exe并启动我的程序后,我得到一个弹出窗口,上面写着“类{mypackage}/{mymainclass}未找到。”,然后是“未能启动JVM。

在Netbeans中启动程序,打包为.exe,在Powershell中启动带有“java-jar{app}.jar”的.jar,所有这些都绝对没有错误。即使是安装的应用程序文件夹中的.jar也没有问题,命令行中没有错误

经过几个小时的git提交和本机打包,我成功地将问题归结为一行代码:
私有静态组合框选项=新建组合框()

当我在初始化器中初始化组合框时,程序在从.exe安装后神奇地工作:

private static ComboBox choices;
{
    choices = new ComboBox();
}
然而,当我使用静态初始化器时(通过将
static
放在第一个大括号前面),即使Netbeans声明“initialiser可以是静态的”,我也会得到与以前相同的错误

这是令人费解的,因为Java显然可以处理代码本身,但在通过本机打包程序之后,它将不会启动。我在其他类中使用了大量类似的代码来初始化静态变量,没有任何不良影响

我尝试在主类中添加类似的行:
private static CheckBox chkbox=new CheckBox()

在安装.exe之后,它导致了完全相同的错误(与以前一样,.jar很好),但是当我将该行剪切并粘贴到另一个类时,它没有任何效果

有趣的是,我的主类已经有了一个静态布尔值,其初始化方式与组合框和复选框相同:
private static boolean someBool=true但布尔值不会导致任何问题

有人能解释这背后的原因吗?多谢各位

编辑:我还尝试在另一台机器上打包,但在同一个git提交后它停止了工作。 我正在使用JDK和JRE的1.8.0144版本

编辑2:这里是一个产生错误的简单示例的主类

package testproject;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class MainApplication extends Application {

    private static CheckBox testCheckBox = new CheckBox(); // Causes error after launching from installed .exe

    /* UNCOMMENT THIS SECTION AND REMOVE THE " = new CheckBox()" ABOVE TO FIX THE ERROR
    {
        testCheckBox = new CheckBox();
    }
     */

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Empty window");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

我将避免在静态初始值设定项中创建JavaFX小部件(例如静态字段或静态块),因为这将在加载类时创建它们,这可能发生在任何线程中。您希望这种情况在JavaFX应用程序线程中发生。
在您的情况下,它发生在主线程中,这肯定是不正确的

查看有关JavaFX应用程序启动以及线程如何参与该过程的更多详细信息

尝试在“JavaFX应用程序线程”之外初始化JavaFX小部件(据我所知)是未定义的行为,可能会以许多不同的方式失败(或者侥幸成功)。如果创建失败,则类加载失败(因为静态init失败),因此“找不到类”。不幸的是,由于这是在加载主类时发生的,所以您不会看到初始错误,只会看到“未找到类XXX”


可能在您的情况下,
java
启动器可以很好地处理此初始化,但是.exe使用的启动器是不同的。我并不觉得奇怪,它失败了。我同样感到惊讶的是,它可以与常规java一起工作:)

您能提供一些MCVE吗?将有助于这个复制,也许有一些不同的错误也(如JDK版本您使用)。谢谢您的答复。我已经成功地生成了一个显示相同错误的简单项目,下面是到BitBucket repo的链接:唯一的类在src/testproject中。请在您的问题中发布代码。。。链接引用往往会随着时间的推移而过时,这可能会导致序列化。反序列化避免了使用构造函数和进行初始化。这似乎是类似的。我已经发布了代码。序列化能解释一下.jar是如何工作的吗?但是.exe不能。谢谢,这是有道理的。