简体   繁体   中英

SPI with Guice error

So I've been making some kind of plugins API for a Java project (to load JAR files externally) and well, I wanted to be able to add any Guice module inside any plugin to my project's dependency graph.

What I did was have a PluginsModule and in the configure method scan for other modules in plugins and install them using Java's ServiceLoader.

I made a test plugin and made a module for it, I confirmed it did get installed. No problems at this point. The problems appear when I do anything inside that module, for example I bound some interface to an implementation in that plugin (just to clear this up, I did the same thing without the plugin and it worked so it's not a binding problem) and tried to inject it, configuration errors saying there was no implementation for that interface appear.

public enum StandardGuiceModuleScanningStrategy implements GuiceModuleScanningStrategy {
INSTANCE;

@Override
public Set<Module> scan(Path directory) throws IOException {
    File directoryAsFile = directory.toFile();
    File[] childrenFiles = directoryAsFile.listFiles();

    if (!directoryAsFile.isDirectory()
            || childrenFiles == null
            || childrenFiles.length == 0) {
        return Collections.emptySet();
    }

    Set<Module> modules = new HashSet<>();

    for (File childrenFile : childrenFiles) {
        ClassLoader directoryClassLoader = new URLClassLoader(
                new URL[]{childrenFile.toURI().toURL()});
        ServiceLoader<Module> moduleServiceLoader = ServiceLoader.load(
                Module.class, directoryClassLoader);

        moduleServiceLoader.forEach(modules::add);
    }

    return modules;
}

In that implementation of my GuiceModuleScanningStrategy, as I mentioned before, I did use ServiceLoader. Anyways, I also tried other stuff, like scanning the JAR file and checking for a Module, and seeing if it has a specific annotation.

All Guice Modules annotated with @GuiceModule , will be installed into a child Injector. All classes annotated with @AutoBind will be bound to all inherited interfaces. You can also name it, which would lead to a named binding and overwrite the interfaces, which should be used. And if you don't want to use all Features, just overwrite the StartupModule and bind only the Features you want or your own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM