2016-09-15 11 views
1

warファイルを起動せずにjarファイルを動的にロードするWebアプリケーションを作成しようとしています。java.util.serviceLoaderを使用して動的に複数のjarファイルをロードする

複数のjarファイルを作成しています。 すべてのjarファイルは、共通のインタフェースを実装しています。 すべてのjarファイルはMETA-INF/service - > package.interfaceの名前を持っています

私は別のjarファイルを追加すると、古いjarファイルの結果を出力します。それは文句を言わない私がtest.TestInterfaceクラスは、両方の瓶でを含まれている参照して第二の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; 
    } 

答えて

1

の結果を印刷します。それは確かにあなたの問題の原因です。クラス(またはインターフェース)は、同じランタイム内の1か所だけで使用可能でなければなりません。 I.E .:いくつかの場所で繰り返してはならない。

いずれかを削除するか、共通のライブラリに保存してください。

+0

Hello Santi、私の要件は、アプリケーションを再起動せずにWebプロジェクトに動的にjarファイルを追加することです。私が新しいジャーを追加するたびに特定のジャーを変更する必要がある場合、それは目的を破ります。それを達成するための他の方法があります。 –

+0

こんにちはJuniad。いいえ、それは意図ではありません。単一のjarファイルに**インターフェース**をパッケージ化するだけです。次に、必要な数の実装を追加します(ServiceLoaderの仕様を達成するために、それぞれ独自のjarファイルに実装します)。また、いずれかのジャーにインターフェイスを再度含めないように注意してください。 –

+0

こんにちはサンティ、今私は1つのjarファイル内のインターフェイスを持っています。それでも同じ振る舞いをするならば、インタフェースを持つjarの出力を表示します。 –

0

私は、ロードするインターフェイスを実装した2つの別々のjarファイルがあるが、見つかった最初のjarファイルだけが処理されていたのと同様の問題がありました。 2番目の瓶は無視されました。

私も(あなたの例あたりの)遅延ロードイテレータを使用していた

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

問題がでループコードを置き換えることで修正されました:両方とも、この単純なコード変更後

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

瓶が発見された。

関連する問題