程序在变成 .jar 时不会 运行

Program will not run when turned into .jar

在过去的几天里我尝试了很多方法都没有成功...我已经搜索了各种 Whosebug 条目但无济于事...我一定是遗漏了什么。

我尝试过三种不同的 IDEs...IntelliJ、Eclispe 和 Netbeans。

问题是当试图将我的程序变成可执行 jar 时它无法 运行(通过双击或通过命令 运行ning)。

执行以下命令时:

java -jar D:\Computing\Programming\Java\Projects\JavaFXGameMenu\out\artifacts\JavaFXGameMenu_jar\JavaFXGameMenu.jar

我得到:错误:无法找到或加载主classroot.Main

当我 运行 相同但使用 javaw 时..我没有收到错误消息,但也没有任何反应。

我主要使用 IntelliJ 作为我正在构建的 JavaFX 应用程序。

这是项目层次结构:

创建工件时,我根据其他线程选择了以下内容:

然后我重新 运行 使用:Java -jar D:\Computing\Executables\JavaFXGameMenu.jar

我遇到以下问题:

我已经将相关的环境变量放入我的系统和Path中,我使用的是jre1.8。0_144。

非常感谢任何有助于追踪问题的帮助

下面的代码...但这完全编译并且 运行s 在 IDE 内没有错误...问题是当它从命令变成 .jar 和 运行 时.

package root;

import javafx.application.Application;

import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;


public class Main extends Application {

    private double width = 1920;
    private double height = 1080;

    private Parent createContent(){
        Pane root = new Pane();
        root.setPrefSize(width, height); //W:860 H:600
        ImageView imgLogo = null;
        ImageView bottomlogo = null;
        MenuItem newGame = new MenuItem("NEW GAME");
        MenuItem continueGame = new MenuItem("CONTINUE");
        MenuItem friends = new MenuItem("FRIENDS");
        MenuItem settings = new MenuItem("SETTINGS");
        MenuItem store = new MenuItem("STORE");
        MenuItem exit = new MenuItem("EXIT");

        try(InputStream is = Files.newInputStream(Paths.get("src/resources/Images/dark.jpg"))) {
            ImageView img = new ImageView(new Image(is));
            img.setFitWidth(width);
            img.setFitHeight(height);
            root.getChildren().add(img);
        } catch (IOException e){
            System.out.println("Couldn't Load Image");
        }

        try(InputStream is = Files.newInputStream(Paths.get("src/resources/Images/logo.png"))) {
            imgLogo = new ImageView(new Image(is));
            imgLogo.setX(1000);
            imgLogo.setY(100);
            imgLogo.setFitWidth(600);
            imgLogo.setFitHeight(300);
        } catch (IOException e){
            System.out.println("Couldn't Load Image");
        }

        try(InputStream is = Files.newInputStream(Paths.get("src/resources/Images/SteamAgony.png"))) {
            bottomlogo = new ImageView(new Image(is));
            bottomlogo.setX(100);
            bottomlogo.setY(800);
            bottomlogo.setFitHeight(200);
            bottomlogo.setFitWidth(200);
            bottomlogo.setOpacity(0.7);
        } catch (IOException e){
            System.out.println("Couldn't Load Image");
        }

        MenuBox menu = new MenuBox(
                newGame,
                continueGame,
                friends,
                settings,
                store,
                exit);

        menu.setTranslateX(width / 3.4);
        menu.setTranslateY(height / 2.5);

        settings.setOnMouseClicked(event -> new SceneCreator().createScene(200,300));

        exit.setOnMouseClicked( event -> Platform.exit());

        root.getChildren().addAll(menu, imgLogo, bottomlogo);

        return root;
    }

    @Override
    public void start(Stage primaryStage) throws Exception{
        Scene scene = new Scene(createContent());
        primaryStage.setScene(scene);
        primaryStage.initStyle(StageStyle.UNDECORATED);
        primaryStage.show();
    }

    @Override
    public void stop(){
        //TODO
    }

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

错误在Main.createContent第102行。可能是你忘记初始化子节点了(我对JavaFX不是很熟悉)。

您正在添加一个 null 元素作为 Pane 的子元素,这导致了您面临的空指针问题,如果您使用调试器,您将能够找到不应为 null 的变量所在的位置设置为空。

编辑 - 添加代码后

您在 try catches(imageLogo、bottomLogo)中看到 2 个字段,即使它们失败了也添加它们,这会添加空值,从而导致错误。

您为图像使用了相对路径,这可能是问题所在,您是从项目根目录 运行 安装 jar 吗?如果不是你可以放绝对路径,但使用资源会更可靠,并允许 jar 运行 在不同的计算机上。

如@cedrikk 所述,问题与您在 Main.createContent 中的代码有关。

你说问题是在尝试 运行 将 jar 作为可执行文件时 - 您尝试在 IDE 内 运行 吗?如果不是 - 你应该尝试,并在它的同时 - 调试它以帮助你找到问题。只需右键单击您的 Main class 并选择调试。

关于 运行 与 javaw 结合使用,您没有收到错误消息的原因是因为 javaw 在没有控制台的情况下执行 java 程序 -通常会收到错误消息,除非使用某些日志记录解决方案。

问题在于声明 inputStreams。

这适用于来自 jar 的 IDE 和 运行:

    String bgImg = "root/resources/dark.jpg";
    URL bgImgPath = Main.class.getClassLoader().getResource(bgImg);
    ImageView img = new ImageView(new Image(bgImgPath.toExternalForm()));
    img.setFitWidth(width);
    img.setFitHeight(height);
    root.getChildren().add(img);

与之前相比:

try(InputStream is = Files.newInputStream(Paths.get("src/resources/Images/dark.jpg"))){
    ImageView img = new ImageView(new Image(is));
    img.setFitWidth(width);
    img.setFitHeight(height);
    root.getChildren().add(img);
}catch (IOException e) {
    System.out.println("Could not load");
}

路径的更改是从我尝试将资源文件夹添加到根文件夹而不是在 src 中进行的。