程序在变成 .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 中进行的。
在过去的几天里我尝试了很多方法都没有成功...我已经搜索了各种 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 中进行的。