0

我对 Java陌生(来自 C# .NET 背景)。尝试通过结合使用 Google Guice 和 ServiceLoader 创建“扩展/IoC”样式架构,但似乎无法让 ServiceLoader 部分运行 Java 1.7.0_75 和 IntelliJ IDEA 14。

我的项目中有一个模块,它实际上是一个名为 ViProJ.Bcl 的基类库,其中包含一个名为 com.vipro.bcl.SimplePluginLoader 的接口。

我有另一个名为 ViProJ.TestModules 的模块,它包含一个名为 com.vipro.test.TestModule1 的 SimpleModuleLoader 实现。

在我的 src 文件夹中有一个资源文件夹(在模块设置屏幕中标记为资源),其中包含一个名为 META-INF.services 的文件夹,其中包含一个名为 com.vipro.bcl.SimpleModuleLoader 的文件。此文件中的值为 com.vipro.test.TestModule1。

我有两个由 IntelliJ 创建的工件(在同一目录中),第一个是一个具有从命令行运行的 Main 函数的模块。它像这样加载服务加载器:

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

另一个是前面提到的测试库。当我对此进行调试时,服务加载器不包含任何类,因此类的导出不起作用。

单个工件文件夹中的两个 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使用 .impl 文件而不是 pom.xml (Maven) 进行构建,如下所示:

<?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