JavaFX本机打包-初始化静态变量时出现奇怪的错误
我正在Netbeans中进行一个JavaFX项目,目前大约有3000行长,我已经定期打包为.exe进行测试,但从未遇到过像这样奇怪的问题 当以本机方式打包为Windows.exe文件时,我发现在安装.exe并启动我的程序后,我得到一个弹出窗口,上面写着“类{mypackage}/{mymainclass}未找到。”,然后是“未能启动JVM。” 在Netbeans中启动程序,打包为.exe,在Powershell中启动带有“java-jar{app}.jar”的.jar,所有这些都绝对没有错误。即使是安装的应用程序文件夹中的.jar也没有问题,命令行中没有错误 经过几个小时的git提交和本机打包,我成功地将问题归结为一行代码: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,所有这些都绝对没有错误。即
私有静态组合框选项=新建组合框()代码>
当我在初始化器中初始化组合框时,程序在从.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不能。谢谢,这是有道理的。