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

时间:2016-09-27 16:37:22

标签: java macos javafx jar path

我正在尝试通过JavaFX中的GUI启动命令行应用程序。 当我在我的IDE中运行该程序时,一切正常,但是当我尝试通过双击已编译的.jar文件来运行它时,它没有。

我已经发现它可能是因为PATH或Classpath或工作目录或类似的东西与从终端运行它时不同。

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的结果:'/ User / Vermeulen / .jenv / shims:/opt/local/bin:/opt/local/sbin:/ Library / Frameworks / Python.framework / VE rsions / 3.5 /斌:在/ usr / local / bin目录:在/ usr / bin中:/ bin中:/ usr / sbin目录:/ sbin目录:在/ usr / local / bin目录中:/ opt / X11 / bin:/ usr / X11 / bi'当你双击jar时,echo $ PATH的结果是:'/ usr / bin:/ bin:/ usr / sbin:/ sbin'**

2 个答案:

答案 0 :(得分:3)

在我的linux机器上双击使用我的主目录作为工作目录。因此,如果您尝试查找相对于jar文件的某些文件,它将失败。

要解决此问题,您无法使用包含

的shell脚本启动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());

它返回Main-class文件的目录或jar文件的完整路径。取决于您启动程序的方式。 使用此信息查找文件。

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

您还没有准确描述您的目标。 如果要为外部命令设置PATH等环境变量,请使用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

答案 1 :(得分:0)

你能否在jar中分享Manifest.mf文件?应该有正确设置的主类。 please check this

其次check this as well。我希望在属性选项卡中已经正确设置了jdk。