0

私は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 関数を含むモジュールです。次のようにサービスローダーをロードします。

ServiceLoader<SimpleModuleLoader> loader = ServiceLoader.load(SimpleModuleLoader.class);

もう 1 つは、前述のテスト ライブラリです。これをデバッグすると、サービス ローダーにクラスが含まれていないため、クラスのエクスポートが機能していません。

1 つのアーティファクト フォルダー内の 2 つの JAR

7zip の jar ファイルを開くと、META-INF\services\com.vipro.bcl.SimpleModuleLoader が表示されるため、IntelliJ はこれらのファイルを正しくパッケージ化しています。

MANIFEST.MF ファイルは次のようになります。

Manifest-Version: 1.0
Export-Package: com.google.inject.name;version="1.3",com.google.inject
 .binder;version="1.3",com.google.inject.spi;version="1.3",com.google.
 inject.matcher;version="1.3",com.google.inject.util;version="1.3",com
 .google.inject;version="1.3"
Bundle-Name: guice
Created-By: 1.6.0_23 (Sun Microsystems Inc.)
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
Bundle-Copyright: Copyright (C) 2006 Google Inc.
Ant-Version: Apache Ant 1.7.1
Bundle-Vendor: Google, Inc.
Bundle-Version: 3.0
Bundle-ManifestVersion: 2
Bundle-Description: Guice is a lightweight dependency injection framew
 ork for Java 5 and above
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-SymbolicName: com.google.inject
Import-Package: javax.inject,org.aopalliance.intercept
Bundle-DocURL: http://code.google.com/p/google-guice/

マニフェストが私のモジュールではなく Guice について話している理由がよくわかりませんか? おそらくこれが失敗する原因ではありませんか?これが機能しない理由を誰か教えてもらえますか? 必要なものをすべて提供していないことは確かですが、ここに他に何を含める必要があるか本当にわかりませんか?

モジュールModuleは、ビルドに pom.xml (Maven) の代わりに .impl ファイルを使用しています。これは次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/src/resources" type="java-resource" />
    </content>
    <orderEntry type="inheritedJdk" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="module" module-name="ViProJ.Bcl" />
    <orderEntry type="library" name="guice-3.0" level="project" />
    <orderEntry type="library" name="guice-multibindings-3.0" level="project" />
  </component>
</module>

私の注入コードは、次のように MultiBinder を使用します。

// dynamic modules via service loader
Multibinder<IModule> modBinder = Multibinder.newSetBinder(binder(), IModule.class);
ServiceLoader<SimpleModuleLoader> loader = ServiceLoader.load(SimpleModuleLoader.class);
for (SimpleModuleLoader moduleLoader : loader) {
     for (Class<? extends IModule> moduleClass : moduleLoader.getModules()) {
        System.out.print("Found expansion module");
        modBinder.addBinding().to(moduleClass);
     }
}
4

0 に答える 0