【问题标题】:JavaFX program cannot run python script after it's deployedJavaFX程序部署后无法运行python脚本
【发布时间】:2019-08-24 08:09:24
【问题描述】:

我编写了一个 JavaFX 程序,该程序运行一个 python 脚本,该脚本使用谷歌控制台搜索 api 来获取数据。在我将其部署为独立程序 (.exe) 之前,它运行良好。安装程序后,它运行良好,直到我单击运行脚本的按钮;它什么也不做。

单击按钮后,它会成功检查是否安装了 python,之后在尝试运行脚本时会出现问题。我已经指定了这样的路径,“./src/com/fortunamaritime/”,我认为这可能是问题所在。

private static final String ANALYTICS_PATH ="./src/com/fortunamaritime/";

方法内部

//set up the command and parameter
String[] cmd = new String[3];
cmd[0] = "python"; 
cmd[1] = "analytics.py";
cmd[2] = "https://fortunamaritime.com.tr";
String command = cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + 
startDate + " " + endDate;
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd " + new 
File(ANALYTICS_PATH).getAbsolutePath() + " && " + command);
builder.redirectErrorStream(true);
Process p = builder.start();

我已将控制台输出重定向到一个 .txt 文件以查看发生了什么,并且只有一行说“系统找不到指定的路径”。


我已经从绝对路径切换到相对路径,它产生了这个错误: 文件名、目录名或卷标语法不正确。 我还将这一行打印到控制台

this.getClass().getResource("/com/fortunamaritime/analytics.py")

结果是:

jar:file:/D:/IdeaProjects/FortunaWebTracker/out/artifacts/FortunaWebTracker/FortunaWebTracker.jar!/com/fortunamaritime/analytics.py

是否可以通过 cmd 通过剥离该 URL 的部分来访问 jar 文件的内部并从那里运行脚本?

【问题讨论】:

  • 这确实很可能是问题所在。源文件夹中的文件很少被添加到已部署的程序中,如果是,它通常作为资源,而不是文件系统的一部分。启动程序时工作目录下是否有./src/com/fortunamaritime/(一般是.exe的位置)?
  • 我建议您检查是否安装了python,如果没有安装则显示错误消息。
  • 我会使用String.join() 而不是cmd[0]+" "+...
  • 您可以简单地使用 nio(或 io)从 jar 中复制它
  • 我在答案中添加了一个代码示例。

标签: java javafx javafx-8


【解决方案1】:

将脚本复制到(可能是临时的)文件并从该文件运行。

您可以使用 Main.class.getResourceAsStream(String resc)(相对于 main)或 Main.class.getClassLoader().getResourceAsStream(String resc)(相对于 root)将脚本作为 InputStream 获取

您可以使用java.nio.file.Files#createTempFile(String,String 并在退出时删除该文件。

您还可以将脚本复制到用户主页或相对于 exe(不要删除它)。

例如,您可以这样做:

File dir=new File("./resc");
if(!dir.exists()) {
    dir.mkdirs();
}
File analyticsFile=new File(dir,"analytics.py");
if(!analyticsFile.exists()) {
    /*
     * alternative:
     * this.getClass().getResourceAsStream("com/fortunamaritime/analytics.py")
     */
    try(InputStream analyticsIn = this.getClass().getClassLoader().getResourceAsStream("analytics.py")){
        Files.copy(analyticsIn, analyticsFile.toPath());
    }
}
/*
 * alternative: String command=String.join(" ",new String[]{"python",analyticsFile.getAbsolutePath(),"https://fortunamaritime.com.tr"});
 */
String command="python "+analyticsFile.getAbsolutePath()+" https://fortunamaritime.com.tr";
/*
 * alternative (without error redirection): Process p=Runtime.getRuntime().exec(command);
 */
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process p=builder.start();

【讨论】:

  • 我想我可能采取了不切实际的方法,但还是谢谢你
【解决方案2】:

我已经解决了我的问题。 先上代码示例,后面会解释;

String path =  new 
File(Main.class.getProtectionDomain().getCodeSource().getLocation()
     .toURI()).getPath();
path=path.substring(0,path.length()-21);
// set up the command and parameter
String[] cmd = new String[3];
cmd[0] = "python";
cmd[1] = "analytics.py";
cmd[2] = "https://fortunamaritime.com.tr";
String command0="jar xf FortunaWebTracker.jar" +                   
"com/fortunamaritime/analytics.pycom/fortunamaritime/client_secrets.json" +
" com/fortunamaritime/webmasters.dat";
String command1 = cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + startDate + " " + 
endDate;
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd " + path + " && " + 
command0+"&&"+"cd "+path+"\\com\\fortunamaritime"+" && "+command1);
builder.redirectErrorStream(true);
Process p = builder.start();

我的第一个错误是使用绝对路径,第二个问题是当我通过以下方式获得我想要的路径时出现的:

File(Main.class.getProtectionDomain().getCodeSource().getLocation()
     .toURI()).getPath();
//Jar's name is 21 characters long, minus that and I get the directory path
path=path.substring(0,path.length()-21);

第二个问题是解压 jar 中的元素,所以我在 cmd 中使用了这个命令:

jar xf FortunaWebTracker.jar
com/fortunamaritime/analytics.py com/fortunamaritime/client_secrets.json com/fortunamaritime/webmasters.dat

然后我可以让它工作。

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 2019-07-17
    • 2017-07-16
    • 1970-01-01
    • 2017-04-07
    • 2016-05-19
    • 2020-10-22
    • 1970-01-01
    • 2018-07-19
    相关资源
    最近更新 更多