NetBeans モジュールアプリケーションで Java ServiceLoader を使用する際に問題があります。これが私がやろうとしていることです(Eclipseの通常のJavaアプリケーションで動作します):
インターフェイスを宣言するinterface.jarがあります。そして、このインターフェースのいくつかの実装を含む implementations.jar があり、すべて spi/META-INF/services/my.package.name.MyInterface ファイルで指定されています (このファイルは implementations.jar にあります)。
クラス ImplementationHandler (さらに別の handler.jar 内) もあり、これにはすべての実装をロードする次のメソッドがあります。
private static List<MyInterface<?>> loadAllImplementations() {
List<MyInterface<?>> foundImplementations = Lists.newArrayList();
try {
for (MyInterface implementation : ServiceLoader.load(MyInterface.class)) {
foundImplementations.add(implementation);
}
} catch (ServiceConfigurationError error) {
system.out.println("Exception happened");
}
return foundImplementations;
}
このコードは、Eclipse の通常のアプリケーション (foundImplementations.size() > 0) のすべての実装を返します。
ただし、NetBeans では、何も見つかりません (foundImplementations.size() == 0)。
詳細:
NetBeans モジュール アプリケーションのソース (オープン ソース、私が作成したものではありません) があり、これを MyInterface 実装のいくつかを使用して拡張する必要があります。interface.jar、implementations.jar、および handler.jar は Eclipse で作成され、別のアプリケーションの一部です。
NetBeans で、新しい実装を使用する必要があるモジュールを開き、3 つの jar ファイルをすべて外部ライブラリとして追加しました (NetBeans はそれらを ext フォルダーにコピーしましたが、これは望ましくありませんが、何もできません。別の myext フォルダーに入れたいと思うかもしれませんが、それはまた別の話です)。次に、すべてを再構築し、実装の 1 つを使用しようとしましたが、見つかりませんでした... 実装を取得するコードは、ImplementationHandler クラスにあり、次のようになります。
public static final <T> MyInteface<T> getByName(String name) {
for (MyInteface implementation : loadAllImplementations()) {
if (implementation.getName().equals(name)) {
return implementation;
}
}
throw new IllegalArgumentException("Unable to find MyInterface class for: " + name);
}
「MyInterface クラスが見つかりません: myImplementationName」という例外が発生しました...
NetBeans に関する私の知識は非常に限られているため、これを機能させるために他に何かする必要があるのではないかと考えていました。