【问题标题】:Unable to access jarfile? [Ubuntu, Linux]无法访问jarfile? [Ubuntu、Linux]
【发布时间】:2015-08-12 07:41:11
【问题描述】:

我这几天一直在尝试解决这个问题,但我似乎无法理解为什么它不能正常工作。我正在尝试从 ProcessBuilder 启动一个 jar 文件,但它只是说找不到该 jar 文件。如果我从终端运行完全相同的命令,那么它运行起来就像一个魅力。任何帮助将不胜感激。

注意:参数s是服务器文件,我已经确认传下来的是正确的参数。

这是该方法的简化版本(它在 pb.start 上出错):

public static void startServer(String s){
    File server = new File(DataManager.getWorkingDirectory() + "/Servers/" + s + "/");
    if(server.exists()){
        if(serverProcess == null){
            try{
                String OS = System.getProperty("os.name").toLowerCase();
                boolean isLinux = (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0) ? true : false;
                //java -jar -XX:MaxPermSize=126M -Xmx1G -jar ...(PathToJar)/server.jar
                ProcessBuilder pb = new ProcessBuilder("java", "-jar", "-XX:MaxPermSize=" + permSize + "M", "-Xmx" + ramAmount + "G", "\"" + (!isLinux ? DataManager.getWorkingDirectory().replace("\\", "/") : "") + "Servers/" + s + "/server.jar\"", "nogui");
                if(!isLinux){
                    pb.directory(server);
                }else{
                    pb.directory(new File(DataManager.getWorkingDirectory()));
                }
                logger.info("Starting Server...");
                final Process p = pb.start();
                GUIMain.serverProcess  = p;

这是整个方法:

public static void startServer(String s){
    File server = new File(DataManager.getWorkingDirectory() + "/Servers/" + s + "/");
    if(server.exists()){
        if(serverProcess == null){
            try{
                String OS = System.getProperty("os.name").toLowerCase();
                boolean isLinux = (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0) ? true : false;
                //java -jar -XX:MaxPermSize=126M -Xmx1G -jar ...(PathToJar)/server.jar
                ProcessBuilder pb = new ProcessBuilder("java", "-jar", "-XX:MaxPermSize=" + permSize + "M", "-Xmx" + ramAmount + "G", "\"" + (!isLinux ? DataManager.getWorkingDirectory().replace("\\", "/") : "") + "Servers/" + s + "/server.jar\"", "nogui");
                if(!isLinux){
                    pb.directory(server);
                }else{
                    pb.directory(new File(DataManager.getWorkingDirectory()));
                }
                logger.info("Starting Server...");
                final Process p = pb.start();
                GUIMain.serverProcess  = p;
                Thread thread = new Thread(){
                    public void run(){
                        try{
                            if(serverList != null){
                                serverList.setEnabled(false);
                            }
                            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
                            BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
                            String s = null;
                            while ((s = stdInput.readLine()) != null) {
                                if(s.toUpperCase().contains("EULA")){
                                    updateTextPane("<font color=\"red\">" + s.replace("Go to eula.txt for more info.", "Please press the <font color=\"green\">Agree to EULA</font> button to agree to the EULA.") + "</font>");
                                    runCommand("stop");
                                }else{
                                    updateTextPane(s);
                                }
                            }
                            while ((s = stdError.readLine()) != null) {
                                updateTextPane(s);
                            }
                            try{
                                Field field = p.getClass().getDeclaredField("hasExited");
                                field.setAccessible(true);
                                while (!(boolean) field.get(p)) {}
                            }catch(Exception e){
                                CrashReport.logStackTrace(e.getMessage(), e.getStackTrace());
                                updateTextPane("<font color=\"red\">Server is offline.</font>");
                                GUIMain.serverProcess = null;
                                if(serverList != null){
                                    serverList.setEnabled(true);
                                }
                            }
                        }catch(Exception e){
                            CrashReport.logStackTrace(e.getMessage(), e.getStackTrace());
                        }
                    }
                };
                thread.start();
            }catch(Exception e1){
                CrashReport.logStackTrace(e1.getMessage(), e1.getStackTrace());
            }
        }else{
            updateTextPane("<font color=\"red\">Server is already running!</font>");
        }
    }else{
        logger.error("The server " + server.toString() + " doesn't exist!");
    }
}

【问题讨论】:

  • 你确定是同一个命令吗?打印processBuilder.command 并查看。
  • 您确定您提供了完整且正确的jar 文件路径吗?
  • 您遇到了什么错误。你可以包括堆栈跟踪吗?
  • @KDM -- 我已经验证我使用的是完全相同的命令。
  • @SubodhJoshi 我尝试给出从 /home 开始的整个路径,但我收到了相同的结果。

标签: java linux ubuntu


【解决方案1】:

这很可能是因为您在将路径传递给ProcessBuilder 时引用了路径:

"\"" + (!isLinux ? DataManager.getWorkingDirectory().replace("\\", "/") : "") + "Servers/" + s + "/server.jar\""

ProcessBuilder 负责引用参数,因此最终会出现双引号。请尝试以下方法:

(!isLinux ? DataManager.getWorkingDirectory().replace("\\", "/") : "") + "Servers/" + s + "/server.jar"

另一件看起来可疑的事情是在 Linux 下使用了相对路径。这也可能是个问题。

【讨论】:

  • 这似乎也不能解决我的问题。至于相对路径的事情,我将如何解决这个问题?我目前从文件夹“MSC”运行主程序,它应该针对“/MSC/Servers/s/server.jar”。
  • 有一种简单的诊断方法。从您的应用程序打印 (1) new File(".").getAbsolutePath() 和 (2) 您正在构建的 jar 文件的路径。然后从终端确保 1 + 2 为您提供现有文件
【解决方案2】:

我认为你需要像下面这样的命令

ProcessBuilder pb = new ProcessBuilder("java", "-XX:MaxPermSize=" + permSize + "M", "-Xmx" + ramAmount + "G", "\"" +  " -jar" + (!isLinux ? DataManager.getWorkingDirectory().replace("\\", "/") : "") + "Servers/" + s + "/server.jar\"", "nogui");

【讨论】:

  • 引号不是问题,所有文件夹都没有特殊字符或空格。
  • 这与 qoutes 无关。这是关于在最终 -jar 命令之前保留 -XX:MaxPermSize 之类的参数
  • 我的错,我现在明白了。我添加了引号并移动了 -jar 参数,但似乎没有任何改变。
  • 你需要去掉引号
  • 好了!非常感谢你们!
猜你喜欢
  • 2023-02-10
  • 2011-07-30
  • 2013-09-27
  • 2018-12-17
  • 2022-12-05
  • 2012-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多