当前位置: 首页 > 知识库问答 >
问题:

Java-从终端运行jar工作,但双击中断功能

吴唯
2023-03-14

我正试图通过JavaFX制作的GUI启动一个命令行应用程序。当我在IDE中运行该程序时,一切正常,但当我试图双击编译后的.jar文件来运行它时,它就不行了。

我发现这可能是因为路径、类路径、工作目录等与从终端运行时不同。

public Button startButton;
public Button clearButton;
public Button minButton;
public Button plusButton;
public Button clearFieldButton;
public Button clearLogButton;
public TextField linkField;
public TextField qualField;
public TextArea errorField;
public ListView<String> historyField;

private String os;

public void initialize(){
    os = System.getProperty("os.name");
    linkField.setText(null);
    qualField.setText(null);
    getHistory();
    setButtonActions();
    Runnable run = new Runnable() {
        @Override
        public void run() {
            linkField.requestFocus();
        }
    };
    Platform.runLater(run);
}

private void setButtonActions(){
    historyField.setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent mouseEvent) {
            if(mouseEvent.getClickCount() == 2){
                String qual;
                if(qualField.getText() == null){
                    qual = "best";
                }
                else{
                    qual = qualField.getText();
                }
                startStream(historyField.getSelectionModel().getSelectedItem(), qual);
            }
        }
    });
    clearButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            clearHistory();
        }
    });
    minButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            delLast();
        }
    });
    plusButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            writeHistory(linkField.getText());
        }
    });
    startButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            startStream(linkField.getText(),qualField.getText());
        }
    });
    clearFieldButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            linkField.clear();
            qualField.clear();
        }
    });
    clearLogButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent actionEvent) {
            errorField.clear();
        }
    });
}

private void delLast(){
    LinkedList<String> temp = new LinkedList<>();
    try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){
        String line;
        while((line = br.readLine()) != null){
            temp.add(line);
        }
        temp.removeLast();
        clearHistory();
        for (String s : temp) {
            writeHistory(s);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void clearHistory(){
    try(BufferedWriter br = new BufferedWriter(new FileWriter("history.txt"))){
        br.write("");
        getHistory();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void getHistory(){
    if(!new File("history.txt").exists()){
        try(BufferedWriter wr = new BufferedWriter(new FileWriter("history.txt"))) {
            wr.write("");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    else{
        historyField.getItems().clear();
        ArrayList<String> history = new ArrayList<>();
        try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){
            String line;
            while((line = br.readLine()) != null){
                history.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        historyField.getItems().addAll(history);
    }
}

private boolean checkIfInFile(String link){
    try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){
        String line;
        while ((line = br.readLine()) != null){
            if(line.equals(link)){
                return true;
            }
        }
        return false;
    } catch (IOException e) {
        e.printStackTrace();
    }
    return false;
}

private void writeHistory(String link){
    if(link != null){
        try(PrintWriter print = new PrintWriter(new FileWriter("history.txt", true))) {
            print.append(link).append("\n");
        } catch (IOException e) {
            e.printStackTrace();
        }
        getHistory();
    }
}

private void startStream(String link, String quality){
    errorField.setText("");
    String command = "";
    if(!checkIfInFile(link)){
        writeHistory(link);
    }
    if(!os.contains("win")){
        ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "/usr/bin/which streamlink");
        Map<String, String> env = pb.environment();
        env.put("PATH",System.getenv("PATH"));
        errorField.appendText(env.get("PATH") + "\n");
        try(BufferedReader br = new BufferedReader(new InputStreamReader(pb.start().getInputStream()))) {
            command = br.readLine();
            errorField.appendText(command);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if(quality == null){
            command = command + " " + link;
        }
        else if(link != null){
            command = command + " " + link + " " + quality;
        }
    }
    else{
        if(link == null){
            command = "streamlink";
        }
        else if(quality == null){
            command = "streamlink " + link;
        }
        else{
            command = "streamlink " + link + " " + quality;
        }
    }
    try {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
        Process proc = pb.start();
        final InputStream in = proc.getInputStream();
        Thread outputThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try(BufferedReader br = new BufferedReader(new InputStreamReader(in))){
                    String read;
                    while((read = br.readLine()) != null){
                        errorField.appendText(read + "\n");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        outputThread.start();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

任何帮助将不胜感激。

编辑:忘了提到双击Windows可以完美工作。

编辑2:**我刚刚发现“真正”的问题是什么。如果您通过终端或bash脚本运行,这是echo$PATH的结果:'/用户/Vermeulen/. jenv/shims:/opt/本地/bin:/opt/本地/sbin:/库/框架 /Python.framework/Version/3.5/bin:/usr/本地/bin:/usr/bin:/bin:/usr/sbin:/sbin: /usr/local/bin:/opt/X11/bin:/usr/X11/bi',当您双击jar时,回声$PATH的结果是:'/usr/bin:/bin:/usr/sbin:/sbin'**

共有2个答案

赫连明诚
2023-03-14

你能在jar中共享Manifest.mf文件吗?应该有正确设置的主类。请检查这个

其次,也检查一下这个。我希望jdk已经在属性选项卡中正确设置。

柯栋
2023-03-14

在我的linux机器上双击使用我的主目录作为工作目录。因此,如果您试图找到一些与jar文件相关的文件,它将失败。

要解决这个问题,您不能用包含

java -jar myjarfile.jar

您应该能够双击shell脚本(取决于您的linux发行版)

如果要通过代码解决问题,请尝试以下代码段:

CodeSource src = Main.class.getProtectionDomain().getCodeSource();
File pathToJar = new File(src.getLocation().toURI());
System.out.println(pathToJar.getAbsolutePath());

它返回主类文件的目录或jar文件的完整路径。取决于你是如何开始你的计划的。使用此信息查找您的文件。

----------------更新1

你还没有准确描述你想做什么。如果要设置外部命令的路径等环境变量,请使用ProcessBuilder。

ProcessBuilder builder = new ProcessBuilder("myprogramm", "firstArg", "secondArg");
Map<String, String> environment = builder.environment();
environment.put("PATH", environment.get("PATH") + ":/my/path");
Process process = builder.start();
OutputStream outputStream = process.getOutputStream();
process.waitFor();

有关更多信息,请阅读ProcessBuilder。

 类似资料:
  • 问题内容: 我刚刚使用jdk7创建了一个jar文件。我尝试运行它,但一直出现错误。原来,它指向的是jre6,而不是jdk7中的jre。因此,我使用以下命令对其进行了更改 ftype jarfile =“ C:\ jre \ bin \ javaw.exe的路径” -jar“%1”%* 之后,我试图再次双击我的jar文件,但是它弹出了一个窗口,要求我选择一个打开它的程序。当我选择与上述相同的java

  • 我有一个JAR文件,它在运行时输出一些东西到终端上。但是,当我双击JAR文件时,什么也没有发生,我的Mac告诉我检查控制台可能的错误,我什么也没有发现。 另一方面,从终端运行JAR工作正常,并且JAR按预期运行。 我正在使用IntelliJ构建我的JAR,我确信我的配置对于构建一个JAR文件是正确的。

  • 我有一些Java(swing)代码调用。如果我从命令行运行它,程序运行得非常好。

  • 我正在尝试将我的程序导出为一个可运行的JAR。该程序在eclipse中工作得非常好,但它不能作为一个可运行的JAR运行。我正在使用另外3个jar文件作为引用jar,这样我就可以使用音频,我认为这可能是问题所在。可运行的jar启动,但它只是一个全白的窗口,程序没有启动。 我点击我的项目,然后右键点击并选择“导出”,然后我选择“可运行的JAR”选项。我尝试使用所有三个处理引用库的选项来创建jar。 将

  • 我使用的是一个安装了Ubuntu的云虚拟机。安装的Java版本为: 在编译java程序时,我必须使用两个jar:和。我使用的终端命令是: 使用将disco和sqlite jar添加到类路径中。 这将在目录中创建我的文件,而不会出现错误。这些JAR包含在目录中。 包含这部分代码,从头开始: 当我在终端中运行以下内容时,问题就开始了: 终端机显示我: 错误:出现JNI错误,请检查您的安装并在线程“ma

  • 我做了一个搜索,我可以看到很多人都有和我一样的问题,但是没有一个解决方案对我有用。 基本上,我在Eclipse中有一个Java项目,它来自我以前的Windows安装。我清理并重建了它,因为一开始它无法编译,但现在我将其导出为可运行的Jar。然而,让应用程序出现的唯一方法是执行在命令提示符下运行,或者在Eclipse中运行它。如果我在Windows资源管理器中双击JAR,即使我知道Java是正确关联