繁体   English   中英

在 Java 14 运行时将 JarFile 添加到 Classpath

[英]Add JarFile to Classpath at runtime in Java 14

嘿,我如何使用 java 14+ 在运行时将 jar 添加到类路径中? 正如我在一些示例中看到的那样,我尝试将 SystemClassLoader 转换为 URLClassLoader,但它会引发 ClassCastException。 有谁知道我如何将 jar 放到较新的 java 版本的类路径中?

“在运行时添加到系统类路径”作为一个概念,通常不受支持。 可能有各种不支持的(因为它依赖于例如一些公共的东西是某物的子类,即使规范没有做出这样的保证)黑客来使其工作,但那里的关键字是unsupported 维护负担非常高,因此只能作为最后的手段使用。 在这种情况下,没有理由这样做; 有更好的选择。

即你在问一个 X/Y 问题。 你有一些未说明的问题,你想:我知道。 我将在运行时将 jar 添加到类路径中! 现在你问的是如何做到这一点。

但错误出现在“我知道。我将在运行时将 jar 添加到类路径中”部分。 那是错误的。

好的,那什么是对的?

只需创建一个新的类加载器,它将系统类加载器作为父类。 您显然是在此处动态加载内容,因此请确保在正确的上下文中执行此操作。 (也就是说,不要运行例如Class.forName("foo.bar") ,而是运行thatClassLoaderYouMadeForThis.loadClass() )。

一个棘手的事情是以下过程:

  • 默认情况下(您可以使用自定义实现覆盖此默认值,但这会使事情变得相当复杂),ClassLoader 将首先要求其父加载器加载一个事物,并且只有在父级找不到它时才会实际加载 class 本身。

  • class 将使用其自己的类加载器加载其任何依赖项(其中使用的任何类型)。 如果该类加载器找不到它,则会出现错误。

换句话说,如果你有这个 class:

class MyClassA {
   MyClassB b;
}

以及class MyClassB extends MyClassA {} ,并且MyClassA在您的系统类路径中可用(因此,可以加载),而MyClassB不是,因此您正在使用子类加载器加载它,那么这不起作用- 行为加载MyClassB将导致MyClassA被加载,但由于父类加载器(作为系统类加载器)确实知道在哪里可以找到MyClassA ,它成为 MyClassA 的加载器,因此它将被要求加载MyClassB以了解该字段它有,这将失败,因为系统加载程序不知道如何做到这一点。 But this is quite a bizarre scenario - how did you end up in a scenario where you have a class file ( MyClassA.class ) that was compiled with access to MyClassB , but MyClassB is no longer part of either the same jar file myClassA is in ,还是一般相同的类路径条件?

所以,通常,这不是问题,但最好了解它是如何工作的。

顺便说一句:

URLClassLoader myLoader = new URLCLassLoader(new URL[] {
  new URL(Paths.get("/path/to/my/custom/lib.jar").toUri().toURL()});

myLoader.loadClass("com.foo.whateverYouWantedToLoad");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM