【问题标题】:java: add a file to a jar directoryjava: 将文件添加到 jar 目录
【发布时间】:2023-10-25 18:33:01
【问题描述】:

我正在做一个项目,该项目需要用户上传一个 Java 文件,该文件以后可以编译成一个类文件。我已经编写了将文件上传到项目文件夹的代码。它在使用 Eclipse 启动时完美运行。当我将项目打包为 JAR 时出现问题。代码抛出异常。我明白原因了..当我们打包项目时,JAR中只加载了类文件而不加载源文件,JAR文件的位置也有所不同。

让我解释一下我做了什么以及我需要做什么:

在项目的 IDE 版本中,我有类似的内容:
用户可以在其中浏览文件并单击上传按钮将其添加到项目结构中。这与以下代码完美配合:

String path = Paths.get(".").toAbsolutePath().normalize().toString()+"\\path\\to\\directory";
File source=new File(textField1.getText());
String fileName="";
try {
    fileName=new java.io.File(textField1.getText()).getName();
    Files.copy(source.toPath(),new java.io.File(path+fileName).toPath(),REPLACE_EXISTING);
} catch (IOException e2) {
    e2.printStackTrace();
}

当我必须使用 JAR 文件运行相同的代码时,我知道我应该更改获取项目根目录的方式,然后导航到所需的目录。不知何故,我无法让它工作。我已经尝试了以下方法:

URL location=MainClass.class.getProtectionDomain().getCodeSource().getLocation();
String p = URLDecoder.decode(location.getFile(), "UTF-8");
System.out.println(location);

这会打印出rsrc:./。如何将上传的文件复制到 Jar 文件中的所需目录?

我还尝试了另一种方法,我想创建一个 shell 脚本来执行jar uf jar-file input-file(s)。我把jar文件和这个shell脚本放在同一个目录下,执行如下代码:

try {
        String fileName = "shellFile.sh";
        URL location=MainClass.class.getProtectionDomain().getCodeSource().getLocation();
        String p = URLDecoder.decode(location.getFile(), "UTF-8");
        System.out.println(location);
        String inputFilePath = p + fileName;
        System.out.println(inputFilePath);
        Process process = Runtime.getRuntime().exec(inputFilePath);
    } catch (IOException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    }

但我得到以下异常:

java.io.IOException: Cannot run program "./shellFile.sh": CreateProcess error=2, 系统找不到指定的文件 在 java.lang.ProcessBuilder.start(未知来源)

有什么方法可以将文件上传到 JAR 文件中的目录?

【问题讨论】:

  • 运行时类路径中的任何 .jar 文件都应被视为只读。正如您所发现的,无法保证这些 .jar 文件完全是物理文件。
  • 我可以确保包存在。如果我关闭 jar 文件并运行jar uf jar-file.jar input-file.java,它工作正常。我无法弄清楚如何从 jar 文件本身以编程方式执行此操作。
  • 这无关紧要。在运行时,ClassLoader 的内部实现可以根据需要提供类。您不能可靠地假设 .jar 文件将在运行时作为文件可用。 即使在它们是文件的情况下,您也不能可靠地假设您能够修改它们。特别是,我观察到 Windows 版本的 Java 会锁定每个运行时 .jar 文件。
  • 我明白了。 Windows 操作系统确实在执行期间锁定了 jar 文件,这从运行 jar uf jar-file input-filècommand 时收到的错误中可以看出。我认为我的问题没有可行的解决方案。我可能应该考虑在运行 jar 文件本身之前添加已编译的 .class 文件。感谢大家的帮助!

标签: java eclipse maven jar processbuilder


【解决方案1】:
String cmd = "jar uvf " + <jar file name> + " " + <name of file to be added;
System.out.println(cmd);
Process p = Runtime.getRuntime().exec(cmd);

【讨论】: