Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

intellij idea - Java: Can't get a working ServiceLoader

I am very new to Java (coming from C# .NET background). Trying to create an "expansion/IoC" style architecture via a combination of Google Guice and ServiceLoader, but can't seem to get the ServiceLoader part working running Java 1.7.0_75 and IntelliJ IDEA 14.

I have a module within my project which is effectively a base class library called ViProJ.Bcl that contains an interface called com.vipro.bcl.SimplePluginLoader.

I have another module called ViProJ.TestModules which contains a single implementation of SimpleModuleLoader called com.vipro.test.TestModule1.

Within my src folder is a resources folder (marked as a resource within the module settings screen) that contains a folder called META-INF.services that contains a single file called com.vipro.bcl.SimpleModuleLoader. The value within this file is com.vipro.test.TestModule1.

I have two artefacts being created (into same directory) by IntelliJ, the first is a module with a Main function that runs from the command line. It loads service loader like so:

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

The other is the aforementioned test library. When I debug this, the service loader contains no classes, so the exporting of the class has not worked.

The two JARs in a single artefact folder

When I open the jar file in 7zip, I can see META-INFservicescom.vipro.bcl.SimpleModuleLoader so IntelliJ has correctly packaged these files up.

"services" resource folder got copied in successfully

The MANIFEST.MF file looks like this:

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/

Not really sure why the manifest is talking about Guice and not my module? Probably not causing this to fail though? Can anyone tell me why this isn't working? I'm sure I haven't given you everything you need, but not really sure what else I should include here?

The modules Module is using an .impl file for building instead of a pom.xml (Maven), this is what that looks like:

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

My injection code uses a MultiBinder, like this:

// 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);
     }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...