在Java中访问外部jar文件

rvpgvaaj  于 2023-02-11  发布在  Java
关注(0)|答案(1)|浏览(170)

我正在尝试从外部jar库访问特定的类。我已经在属性文件中配置了路径
test-library = file:/Users/test.user/test/library.jar
test-library2 = file:/Users/test.user/test/library2.jar
然后我尝试从代码中访问它,但得到了ClassNotFoundErrorException或IllegalArgumentException:当我按如下方式修改路径时,URI不是绝对的
test-library = /Users/test.user/test/library.jar
test-library2 = /Users/test.user/test/library2.jar
当我在resources文件夹中找到jar文件并按如下方式指定路径时,工作正常。
test-library = classpath:library/library.jar
test-library2 = classpath:library/library2.jar
但是,我需要访问jar文件,因为在部署代码时,我们不能将jar文件放在resource文件夹中,而是放在外部位置。

指定外部jar文件路径的正确方法是什么,以便java可以找到我需要的类?

这是我调用外部库的代码,正如我之前所说的,如果jar文件在resource文件夹中,它可以正常工作,但我需要从机器中的外部位置访问jar文件。

@Value("${test-library}")
String library;

@Value("${test-library2}")
String library2;

  
public String testMethod(String text1, String text2) {
 try {
   log.info("[testMethod] start process");

   URLClassLoader urlClassLoader =
          new URLClassLoader(
              new URL[] {URI.create(library).toURL(), URI.create(library2).toURL()},
              this.getClass().getClassLoader());

      Class<?> classInstance = Class.forName("pro.test.service.TestService", true, urlClassLoader);
      
      Method getInstanceMethod = classInstance.getMethod("getInstance", String.class, String.class);

      Object instance = getInstanceMethod.invoke(null, data1, data2);

      Method libraryMethod = classInstance.getMethod("libraryMethod", String.class, String.class);

      log.info("[testMethod] end process");

      return (String) libraryMethod.invoke(instance, text1, text2);

    } catch (Exception e) {
      log.error("Error testing library method: ", e);
      throw e;
    }
  }```
0ve6wy6x

0ve6wy6x1#

阅读URLClassLoaderdocumentation,我们可以得到:
该类加载器用于从引用JAR文件和目录的URL的搜索路径加载类和资源。任何jar:方案URL(参见JarURLConnection)都假定引用JAR文件。
并且遵循上述linkJarURLConnection
JAR URL的语法为:
jar:<url>!/{entry}
....如果省略了条目名,则URL指的是整个JAR文件:jar:http://www.example.com/bar/baz.jar!/*¹
把这些放在一起,对于第一个有问题的JAR,我们得到:
jar:file:/Users/test.user/test/library.jar!/

1地址从foo更改为example,因为StackOverflow不接受第一个地址(显然甚至不在带引号的代码内)

相关问题