gpt4 book ai didi

未设置 -Djava.ext.dirs 时未从目录加载 Java SPI JAR

转载 作者:行者123 更新时间:2023-11-29 08:50:55 26 4
gpt4 key购买 nike

我无法让服务提供者接口(interface)从同一目录中的另一个 JAR 加载实现。它仅在我使用 -Djava.ext.dirs= 时有效。在命令行上。没有它就不能工作吗?

我有以下界面:

package playground;

public interface TestIface {
public String test();
}

这里实现了:

package playground;

public class TestImpl implements TestIface {
public String test() {
return "TEST";
}
}

这里我尝试加载实现:

package playground;
import java.util.Iterator;
import java.util.ServiceLoader;
public class Lalala {
public static void main(String[] args) {
ServiceLoader<TestIface> loader = ServiceLoader.load(TestIface.class);
Iterator<TestIface> it = loader.iterator();
while (it.hasNext()) {
TestIface a = it.next();
System.out.println(a.test());
}
System.out.println("DONE");
}

}

接口(interface)和最后一个类封装在main.jar中,实现在impl.jar中。main.jar 有主类集,impl.jar 有 META-INF/services/playground.TestIface 文件,其中包含“playground.TestImpl”。两个 JAR 都在同一个目录中。运行

java -jar main.jar

只打印“完成”,显然没有找到实现。

如果我改为运行

java -Djava.ext.dirs=. -jar main.jar

它还会按预期打印“TEST”。

我做错了什么?为什么除非我更改 java.ext.dirs 设置,否则不会加载其他 JAR 的实现?

最佳答案

java.ext.dirs设置自动将在指定目录中找到的所有 jar 文件添加到主类加载器,这就是 ServiceLoader 可以找到并加载 TestIface.class 的原因(来自 Apidocs:“使用当前线程的上下文类加载器为给定的服务类型创建一个新的服务加载器。”)。

但是你不应该使用 java.ext.dirs为此(请参阅 here 了解其中一种危险)。当你使用 java -jar你不能使用 java -cp设置类路径(您只能使用其中一个)。这使您可以选择使用 URLClassLoader加载其他 jar ,然后调用 ServiceLoader.load(class from another jar) .

提示:要加载其他 jar 文件,请使用 main.jar 的位置文件,如 this question 的答案中所述.其他变量(如启动目录)取决于 Java 的启动方式和位置,很容易导致找不到其他 jar 文件。

关于未设置 -Djava.ext.dirs 时未从目录加载 Java SPI JAR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22737371/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com