Maven构建后某些场景未加载

Posted

技术标签:

【中文标题】Maven构建后某些场景未加载【英文标题】:Some scene not loading after maven build 【发布时间】:2015-07-20 14:01:03 【问题描述】:

我正在 netbeans 中开发 JavaFx 应用程序,在 netbeans 中,该项目正在构建和运行良好。

我从我的项目中创建了一个构建(mvn 包),它没有错误地完成,但是当我启动程序时,它没有加载所有场景,并且 FXMLLoader 在这种情况下返回空值。

同一文件夹中的所有 .fxml 文件。

public class JavaFXApplication extends Application 

    public static final String TOOLBAR_MAIN = "toolbarMain";
    public static final String TOOLBAR_MAIN_FXML = "/fxml/ToolbarMain.fxml";
    public static final String TOOLBAR_SUB = "toolbarSub";
    public static final String TOOLBAR_SUB_FXML = "/fxml/ToolbarSub.fxml";

    public static final String NEW_SESSION_PANEL = "newSession";
    public static final String NEW_SESSION_PANEL_FXML = "/fxml/NewSessionPanel.fxml";
    public static final String OPEN_SESSION_PANEL = "openSession";
    public static final String OPEN_SESSION_PANEL_FXML = "/fxml/OpenSessionPanel.fxml";
    public static final String CONNECTIONS_PANEL = "connections";
    public static final String CONNECTIONS_PANEL_FXML = "/fxml/ConnectionsPanel.fxml";
    public static final String LOGS_PANEL = "logs";
    public static final String LOGS_PANEL_FXML = "/fxml/LogsPanel.fxml";
    public static final String EXCEPTIONS_PANEL = "exceptions";
    public static final String EXCEPTIONS_PANEL_FXML = "/fxml/ExceptionsPanel.fxml";
    public static final String MESSAGES_PANEL = "messages";
    public static final String MESSAGES_PANEL_FXML = "/fxml/MessagesPanel.fxml";

    public static ScreensController menuContainer = new ScreensController();
    public static ScreensController contentContainer = new ScreensController();

    public static ServerService server = new ServerService();

    public static Stage STAGE;

    @Override
    public void start(Stage primaryStage) throws Exception 

        STAGE = primaryStage;

        primaryStage.setOnCloseRequest((WindowEvent t) -> 
            if (server.isRunning()) 
                server.cancel();
            
        );

        menuContainer.loadScreen(JavaFXApplication.TOOLBAR_MAIN,
                JavaFXApplication.TOOLBAR_MAIN_FXML);
        menuContainer.loadScreen(JavaFXApplication.TOOLBAR_SUB,
                JavaFXApplication.TOOLBAR_SUB_FXML);

        contentContainer.loadScreen(JavaFXApplication.NEW_SESSION_PANEL,
                JavaFXApplication.NEW_SESSION_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.OPEN_SESSION_PANEL,
                JavaFXApplication.OPEN_SESSION_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.NEW_SESSION_PANEL,
                JavaFXApplication.NEW_SESSION_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.CONNECTIONS_PANEL,
                JavaFXApplication.CONNECTIONS_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.LOGS_PANEL,
                JavaFXApplication.LOGS_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.EXCEPTIONS_PANEL,
                JavaFXApplication.EXCEPTIONS_PANEL_FXML);
        contentContainer.loadScreen(JavaFXApplication.MESSAGES_PANEL,
                JavaFXApplication.MESSAGES_PANEL_FXML);
        menuContainer.setScreen(JavaFXApplication.TOOLBAR_MAIN);
        contentContainer.setScreen(JavaFXApplication.NEW_SESSION_PANEL);

        SplitPane root = new SplitPane();

        root.getItems().addAll(menuContainer, contentContainer);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
        primaryStage.setResizable(false);
        primaryStage.setTitle("Exam Supervisor");

    

加载屏幕的屏幕控制器:

public class ScreensController extends StackPane 

    private HashMap<String, Node> screens = new HashMap<>();

    public void addScreen(String name, Node screen) 
        screens.put(name, screen);
    

    public boolean loadScreen(String name, String resource) 
        try 
            FXMLLoader myLoader = new FXMLLoader(getClass().getResource(resource));
            System.out.println("name:" + name + " ,resource" + resource + " ,loader:" + myLoader.getLocation());
            Parent loadScreen = myLoader.load();
            ControlledScreen myScreenControler
                    = myLoader.getController();
            myScreenControler.setScreenParent(this);
            addScreen(name, loadScreen);
            return true;
         catch (Exception e) 
            System.out.println("name: " + name + ", resource" + resource + " ,exception: " + e.getMessage());
            return false;
        
    

    public boolean setScreen(final String name) 

        if (screens.get(name) != null) 
            final DoubleProperty opacity = opacityProperty();

            if (!getChildren().isEmpty()) 
                getChildren().remove(0);
                getChildren().add(0, screens.get(name));
             else 
                getChildren().add(screens.get(name));
            
            return true;
         else 
            System.out.println(screens.get(name) + " ,screen hasn't been loaded!\n");
            return false;
        

    

    public boolean unloadScreen(String name) 
        if (screens.remove(name) == null) 
            System.out.println("Screen didn't exist");
            return false;
         else 
            return true;
        
    

我的 github 仓库:https://github.com/eszikk/ExamSuperVisorServer

【问题讨论】:

您将 fxml 作为资源的子文件夹:您在创建的 jar 文件中具有相同的结构吗? 是的。构建创建了 /target/classes/fxml 结构,它包含所有 .fxml 文件。 这不是我问的。在生成的jar文件中,fxml文件夹是在顶层,还是放在resources文件夹下? 是的,它在顶层。这是结构:/com, /fxml, /imageRes, /META-INF, /shared, /styles, 您能否添加您的项目结构like this 或验证它是否以类似的方式? 【参考方案1】:

我查看了您的 netbeans 项目文件和 maven pom,没有发现任何奇怪的地方。两种配置的类路径中都不包含 javafx 库的事实告诉我,您是从 Java 安装中使用它的。

也许您在启动 maven 目标时使用了与 netbeans 不同的 Java 安装。然后,可能缺少 fxml 模块,或者第二次安装时没有安装 java fx,或者其他不兼容的东西。

您是否从控制台启动了 maven 目标?例如

java -jar xyz.jar

试试

java-版本

并将版本与netbeans使用的java版本进行比较(帮助>关于)。

Netbeans 构建由内部 maven 版本完成。但也有可能外部 maven 构建使用的 java 编译器版本与内部 netbeans 构建不同。

希望对你有帮助!

【讨论】:

【参考方案2】:

尝试使用javafx-maven-plugin 希望对您有所帮助。

【讨论】:

通常当有人悬赏他们的问题时,他们通常会寻找比简单链接更多的细节。请向 OP 解释为什么您的建议会有所帮助,以及以何种方式以及如何实施。就目前而言,这是一个糟糕的答案。 对不起,我是新人)。我有一个类似的问题,在我开始使用这个插件之前,也许它在这种情况下会有所帮助。这只是一个建议。【参考方案3】:

在进行以下更改后,我已从 Netbeans 外部成功运行您的应用程序。

首先,我想知道为什么你有编译器插件。因此,我删除了它并在构建过程中收到“未找到 sun.util.logging.PlatformLogger 的类文件”错误。

您遇到了JavaFX8 - sun.util.logging.PlatformLogger not found Exception in NetBeans 8中所述的问题

你需要修复它。

其次,您所拥有的只是编译阶段,而不是可运行的 jar。

可能有办法使用编译器插件(或通过在类路径中包含其他依赖的 jar)来实现,但我发现使用程序集插件创建一个包含所有依赖项的 jar 更容易..

将以下内容添加到您的 pom.xml

         <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>com.eszik.supervisorserver.main.Main</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </plugin>

接下来,分别运行两个 mvn 命令。

mvn clean install
mvn assembly:single

然后, java -jar 目标/SuperVisorServer-1.0-SNAPSHOT-jar-with-dependencies.jar

【讨论】:

以上是关于Maven构建后某些场景未加载的主要内容,如果未能解决你的问题,请参考以下文章

SignalR 在某些限制后未处理请求。即使在相同或不同机器上的其他浏览器中,选项卡仍会加载

不允许在 chrome 上加载本地资源 - 错误,生产构建后 Angular 应用程序未运行

使用电子生成器构建后,电子应用程序未加载 index.html,甚至没有给出错误

Sencha touch 2 原生构建未加载

选择字段未在构建时加载

通过 gradle 构建后无法找到或加载主类