jjs.exe和ServiceLoader

时间:2016-10-24 21:13:24

标签: java nashorn

jjs.exe运行的脚本能否像任何Java程序一样找到ServiceLoader的服务?

我已将案例简化为以下脚本:

function dump (stream)
{
    (new BufferedReader(new InputStreamReader(stream))).lines().forEach(function (x) { print(x); });
}

var BufferedReader = Java.type("java.io.BufferedReader");
var InputStreamReader = Java.type("java.io.InputStreamReader");
var ServiceLoader = Java.type("java.util.ServiceLoader");

var Sts = Java.type("prodist.sts.Sts");
print(Sts);
// A

var stsConfigStream = Sts.class.getResourceAsStream("/META-INF/services/prodist.sts.Sts");
dump(stsConfigStream);
// B

var StsImpl = Java.type("prodist.sts.internal.StsImpl");
print(new StsImpl());
// C

var stsLoader = ServiceLoader.load(Sts.class);
var stsIterator = stsLoader.iterator();
stsIterator.next();
// D

我在命令行上调用jjs.exe设置Class-Path。我的脚本在A点正确查找并打印了接口名称。它找到了服务描述资源;当我转储资源的内容时,我在B点看到预期的内容。我确保预期的实现类在C点可用。

在D点,程序抛出NoSuchElementException,我将其解释为ServiceLoader没有为界面找到任何服务描述资源。

这应该有效吗? 我错过了什么吗?

1 个答案:

答案 0 :(得分:1)

您需要设置线程上下文类加载器。请参阅jjs类路径中的任何类,获取它的Class对象,然后获取它的类加载器。然后,将该加载器设置为线程上下文类加载器。这应该在使用服务加载器API之前完成:

var StsClass = Java.type("prodist.sts.Sts").class;
java.lang.Thread.currentThread().contextClassLoader = StsClass.classLoader;