【问题标题】:How to load a JAR stored inside your application resources in a URLClassLoader如何在 URLClassLoader 中加载存储在应用程序资源中的 JAR
【发布时间】:2023-03-31 08:08:01
【问题描述】:

我正在尝试在 URLClassLoader 中加载 JAR 文件。这个 JAR 文件存储在我的项目的资源中,当我使用 maven 运行我的项目时,它可以使用以下代码正常工作:

new URLClassLoader(
    new URL[]{MyClass.class.getClassLoader().getResource("dependencies/dependency.jar")},
    ClassLoader.getSystemClassLoader().getParent()
);

但是,当我使用mvn clean install 构建项目然后尝试使用java -jar myapp.jar 运行生成JAR 时,似乎dependency.jar 没有加载。 dependency.jar 文件已正确存储在 dependencies/dependency.jar 下的项目 JAR 中,但未被读取。

我假设它不能从 JAR 文件中加载,但它们是一种解决方法吗?

我认为一个解决方案是使用getResourceAsStream,但我需要将此流转换为 URL。

如果可能的话,我想使用一个不涉及创建临时文件来存储dependency.jar 内容的解决方案。

【问题讨论】:

  • dependency.jar 位于您的 jar 文件中吗?如果有,具体在哪里?
  • 是的,它在我项目的资源中,所以在构建的 JAR 中它位于 dependencies/dependency.jar
  • 你试过 MyClass.class.getResource("/dependencies/dependency.jar") 吗?
  • 那么它甚至不能使用 maven ^^'
  • 是,但使用 java -jar myapp.jar

标签: java maven jar dependencies


【解决方案1】:

我认为您的问题是由于 它无法读取 zip 中的 zip,因此您应该将您的 jar 文件复制到一个临时文件中,并将此临时文件提供给您的 URLClassLoader接下来:

// Get the URL of my jar file
URL url = MyClass.class.getResource("/dependencies/dependency.jar");
// Create my temporary file
Path path = Files.createTempFile("dependency", "jar");
// Delete the file on exit
path.toFile().deleteOnExit();
// Copy the content of my jar into the temporary file
try (InputStream is = url.openStream()) {
    Files.copy(is, path, StandardCopyOption.REPLACE_EXISTING);
}
// Create my CL with this new URL
URLClassLoader myCL = new URLClassLoader(
    new URL[]{path.toUri().toURL()}, ClassLoader.getSystemClassLoader().getParent()
);

【讨论】:

  • 是的,恐怕这就是我必须做的,谢谢。我只是想知道是否有其他解决方案。
  • 我不确定是否需要 StandardCopyOption.REPLACE_EXISTING,因为 Files.createTempFile 不应该创建两次相同的文件。如果不添加,您会遇到问题吗?
  • 好吧,Files.copy 尝试创建文件。它甚至写在文档中:“默认情况下,如果目标文件已经存在或者是符号链接,则复制失败。”
猜你喜欢
  • 1970-01-01
  • 2012-04-11
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 2014-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多