問題タブ [serviceloader]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java: 動作中の ServiceLoader を取得できません
私はJavaが初めてです(C#.NETのバックグラウンドから来ました)。Google Guice と ServiceLoader を組み合わせて「拡張/IoC」スタイルのアーキテクチャを作成しようとしていますが、Java 1.7.0_75 と IntelliJ IDEA 14 を実行している ServiceLoader 部分を動作させることができないようです。
プロジェクト内にモジュールがあります。これは事実上、com.vipro.bcl.SimplePluginLoader というインターフェイスを含む ViProJ.Bcl という基本クラス ライブラリです。
com.vipro.test.TestModule1 という SimpleModuleLoader の単一の実装を含む ViProJ.TestModules という別のモジュールがあります。
私の src フォルダー内には、com.vipro.bcl.SimpleModuleLoader という単一のファイルを含む META-INF.services というフォルダーを含むリソース フォルダー (モジュール設定画面内のリソースとしてマークされている) があります。このファイル内の値は com.vipro.test.TestModule1 です。
IntelliJ によって (同じディレクトリに) 2 つのアーティファクトが作成されています。1 つ目は、コマンド ラインから実行される Main 関数を含むモジュールです。次のようにサービスローダーをロードします。
もう 1 つは、前述のテスト ライブラリです。これをデバッグすると、サービス ローダーにクラスが含まれていないため、クラスのエクスポートが機能していません。
7zip の jar ファイルを開くと、META-INF\services\com.vipro.bcl.SimpleModuleLoader が表示されるため、IntelliJ はこれらのファイルを正しくパッケージ化しています。
MANIFEST.MF ファイルは次のようになります。
マニフェストが私のモジュールではなく Guice について話している理由がよくわかりませんか? おそらくこれが失敗する原因ではありませんか?これが機能しない理由を誰か教えてもらえますか? 必要なものをすべて提供していないことは確かですが、ここに他に何を含める必要があるか本当にわかりませんか?
モジュールModule
は、ビルドに pom.xml (Maven) の代わりに .impl ファイルを使用しています。これは次のようになります。
私の注入コードは、次のように MultiBinder を使用します。
android - ServiceLoader.load が META-INF/services を見つけられない
だから私は、開発者が 'CustomDevice' クラスを追加でき、メインプログラムが既存のコードを編集せずにそれらを自動的に実行する拡張可能な Android アプリケーションを構築したいと考えています。
Service Provider インターフェイスについて読んだことがありますが、それは良い方法だと思いました。
そこで私はそれをテストし、カスタム デバイス クラスが実装することが期待される「ICustomDevice」というインターフェイスを作成しました。
ICustomDevice を実装する「DummyDevice」というクラスを作成しました。
DummyDevice と ICustomDevice はどちらも同じパッケージ "CustomDevicePackage" にあります。
したがって、私のメインプログラムでは、次を実行します。
常に false を返します。これは、「DummyDevice」が見つからないことを意味します。
私のEclipseプロジェクトでは、「src」にMETA-INFというフォルダーを作成し、その下に「services」というサブフォルダーを作成しました。
「Services」には「CustomDevicePackage.ICustomDevice」という名前のファイルがあり、コンテンツ行は「CustomDevicePackage.DummyDevice」です。
私はそれを正しくやっていますか?SPI について私が目にするすべての例は、JARS のロードに関するものです。JAR をロードしていません。同じプロジェクトでクラスを実行しようとしています。この方法は JAR をロードする場合にのみ機能しますか? プログラムで、ローカル サブクラスと外部 JAR のロードを同様にサポートしたいと考えています。
java - ServiceLoader が常にサービスを再インスタンス化するのはなぜですか?
service interface があるとしましょうcom.example.Service
。
テストのために、私は
を含むファイル
インターフェースをMockServiceImpl
実装します。
これで、 aを実行ServiceLoader.load(Service.class)
して結果を反復処理すると、 myMockServiceImpl
は常に再度インスタンス化されます。の javadoc にServiceLoader
は、キャッシュを維持していると記載されていますが、私のモック サービスはキャッシュされていないようです。
なぜそうなるのですか、どうすればそれServiceLoader
をキャッシュに入れることができますか?
java - モジュラー Java アプリケーションの作成
次の構造のプロジェクトがあります。
モジュールはServiceLoader
メカニズムを使用してサービスを登録します。メインクラスはモジュール内にあり、メカニズムmain
を使用してクラスパスにサービスをロードする責任もあります。ServiceLoader
問題は、ユーザーが個別にインストールしたため、main
モジュールがmodule1
、module2
、module3
および を認識しないことです。module4
私がしたいのは、プログラムの起動時にこれらのモジュールのすべてのクラスをクラスパスに追加して、 ServiceLoader がこれらのモジュールのサービスを認識できるようにすることです。
現在、モジュールから実行時にこれらのモジュールをロードしmain
ていますが、IDE がこれらのモジュールを認識しておらず、これらのモジュールをランタイム。Elasticsearch や PrestoDB などのモジュラー Java プロジェクトがこの問題をどのように処理するかを見てきましたが、どちらも実行時にインストールされたモジュールをロードするようです。
モジュラー Java アプリケーションを開発するとき、この問題をどのように処理しますか? ユーザーがインストールしたモジュールのjarファイルを含むpluginsというディレクトリがあるとしましょう。mavenプラグインを使用して、そのディレクトリ内のすべてのjarを含むクラスパスでアプリケーションを起動する方法はありますか? または、実行時にこれらの jar をロードする必要がありますか?
java - java.util.ServiceLoader.load() 関数は役に立たず、空の結果しか返さない
Scala 2.10 で Java ServiceLoader を使用して、リフレクションによってすべてのテスト クラスを見つけようとしています。
'classOf[]' 関数を使用して同じコード スニペットでそれらを見つけることができるため、'MyClass' にはテスト ケースを含むいくつかのサブクラスがあると確信しています。
ただし、私のテストは常に終了します
ServiceLoader は Scala で動作していませんか? この問題を修正または回避するにはどうすればよいですか?
java - exec:java の実行時に SPI 実装を登録する方法
Maven プラグインを介して実行するときにVertX Mertricsを機能させようとしています。exec:java
アプリケーションをfatjarにパッケージ化して実行すると、すべてが期待どおりに機能しますjava -jar fat.jar -conf config.json -Dvertx.metrics.options.enabled=true
で実行すると、次のmvn clean package exec:java -DskipTests
ように表示されます。
2016-03-22 18:39:58.833 WARN i.v.c.i.VertxImpl:348 - Metrics has been set to enabled but no VertxMetricsFactory found on classpath
私はいくつかのアプローチを試しました:
io.vertx:vertx-dropwizard-metrics:3.2.1
コンパイルの依存関係として追加- 社内メトリクスの実装を作成し、
src/main/resources/META-INF/services/io.vertx.core.spi.VertxMetricsFactory
ファイルを使用して登録します (実際に にコピーされていることを再確認しますtarget/classes/META-INF/services/io.vertx.core.spi.VertxMetricsFactory
) 。 - また
${basedir}/src/main/resources
、追加のクラスパス要素として追加します(前のポイントに加えて)
ServiceLoader
実際に空のイテレータを返すデバッガを再確認しました。
これは私の実行プラグイン構成です:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<element>${basedir}/src/main/resources</element>
</additionalClasspathElements>
<mainClass>io.vertx.core.Launcher</mainClass>
<commandlineArgs>run ${vertx.mainVerticle} -conf ${vertx.config}</commandlineArgs>
<systemProperties>
<systemProperty>
<key>vertx.logger-delegate-factory-class-name</key>
<value>io.vertx.core.logging.SLF4JLogDelegateFactory</value>
</systemProperty>
<systemProperty>
<key>vertx.metrics.options.enabled</key>
<value>true</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
これは機能exec:exec
する構成ですが、それを行うことが(不可能)可能であるかどうか、およびその理由を理解したいexec:java
<profile>
<id>exec</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Dvertx.metrics.options.enabled=true</argument>
<argument>-Dvertx.logger-delegate-factory-class-name=${vertx.logger-delegate-factory-class-name}</argument>
<argument>-classpath</argument>
<classpath />
<argument>io.vertx.core.Launcher</argument>
<argument>run</argument>
<argument>${vertx.mainVerticle}</argument>
<argument>-conf</argument>
<argument>${vertx.config}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>