使用java.util.serviceLoader动态加载多个jar文件

时间:2016-09-15 09:21:43

标签: java

我正在尝试编写一个动态加载jar文件而不启动war文件的Web应用程序。

我正在创建多个jar文件。 所有jar文件都实现了一个通用接口。 所有jar文件都有META-INF / service - > package.interface name

如果只有一个jar,Web应用程序工作正常,如果我添加另一个jar文件,它会打印旧jar文件的结果。它不会打印第二个jar文件的结果

jar 1 

name: pluggin1
src
 -> test
  -> TestInterface
  -> TestInterfaceImpl
 META-INF
 > services
     -> test.TestInterface(this is the file name)
     -> content of the file = test.TestInterfaceImpl

jar 2 

 name: pluggin2
 src
  -> test
    -> TestInterface
    -> helloImpl
 META-INF
   -> services
       -> test.TestInterface(this is the file name)
          -> content of the file = test.helloImpl


   main class which loads contents of jar file dynamically


main.java

public static void main(String[] args){
    System.out.println("junaid");

    String res = getInstance().getDefinition("junaid");

    System.out.println("asdasd= "+ res);
}

private static ManagePlugins service;
private ServiceLoader<TestInterface> loader;

  /**
     * Creates a new instance of DictionaryService
     */
    private ManagePlugins() {
        loader = ServiceLoader.load(TestInterface.class);
    }

    /**
     * Retrieve the singleton static instance of DictionaryService.
     */
    public static synchronized ManagePlugins getInstance() {
        if (service == null) {
            service = new ManagePlugins();
        }
        return service;
    }


  /**
     * Retrieve definitions from the first provider
     * that contains the word.
     */
    public String getDefinition(String className) {
        String definition = null;

        try {
            Iterator<SimplePlugin> dictionaries = loader.iterator();
            while (definition == null && dictionaries.hasNext()) {
                SimplePlugin d = dictionaries.next();
                definition = d.getName();
                System.out.println("definition = "+ definition);
            }
        } catch (ServiceConfigurationError serviceError) {
            definition = null;
            serviceError.printStackTrace();

        }
        return definition;
    }  

2 个答案:

答案 0 :(得分:1)

我看到test.TestInterface类在两个广告中都包含 。这肯定是你问题的原因。类(或接口)必须仅在同一运行时中的一个位置可用。 I.E。:不得在多个地方重复。

删除其中一个,或将其带到一个公共库。

答案 1 :(得分:0)

我有一个类似的问题,我有两个独立的jar文件实现了要加载的接口,但只找到了第一个找到的jar文件。第二个罐子被忽略了。

我也在使用延迟加载迭代器(根据你的例子):

...
Iterator<SimplePlugin> dictionaries = loader.iterator();
  while (definition == null && dictionaries.hasNext()) {
    SimplePlugin d = dictionaries.next();
...

通过用以下代码替换循环代码来解决问题:

...
for(SimplePlugin d : loader) {
...

在这个简单的代码更改之后,两个罐子都被发现了。