Implementing a (compile-time) plugin architecture

2020-04-19 06:06发布

问题:

In a past question I asked how to design a system where:

  • A class contains one or more optional methods.
  • Optional methods are implemented by plugins that may or not may be present at compile-time.
  • If a user invokes a method whose associated plugin is not present at compile-time, they will get a compile-time error.

I provided one possible solution that works in Java 8.

Unfortunately, this solution depends on the use of split packages (two modules exporting the same package) which are disallowed by the Java 9 Module System.

How can this be implemented in Java 9?

回答1:

Services

If I have understood the question correctly what you're looking forward to using are Services from the module system.

Java has long supported services via the java.util.ServiceLoader class, which locates service providers at run time by searching the classpath.

The module system could identify uses of services by scanning the class files in module artifacts for invocations of the ServiceLoader::load method.

With your current project structure, you should define an abstract class or an interface that can be a extended of implemented in the guava, coremodule classes and is provided by them.


A module uses a particular service is an important aspect of that module’s definition, so for both efficiency and clarity its expressed in the module’s declaration with a uses clause:

module com.foo.bar.sql {
    uses com.foo.Verifiers;
}

A module provides an implementation of a particular service is equally fundamental, however, this is put in the module’s declaration with a provides clause:

module guava {
    provides com.foo.Verifiers with com.guava. GuavaVerifier;
}

module core {
    provides com.foo.CoreVerifier with com.guava. GuavaVerifier;
}