Imagine you have a software module, which is a plugin to some program (similar to Eclipse) and you want it to have an API which other plugins can call. Your plugin is not freely available, so you want to have a separate API module, which is freely available and is the only thing other plugins need to directly link to - API clients can compile with only the API module, and not the implementation module, on the build path. If the API is constrained to evolve in compatible ways, then client plugins could even include the API module in their own jars (to prevent any possibility of Errors resulting from nonexistent classes being accessed).

Licensing is not the only reason to put API and implementation in separate modules. It could be that the implementation module is complex, with myriad dependencies of its own. Eclipse plugins usually have internal and non-internal packages, where the non-internal packages are similar to an API module (both are included in the same module, but they could be separated).

I've seen a few different alternatives for this:

  1. The API is in a separate package (or group of packages) from the implementation. The API classes call directly into implementation classes. The API cannot be compiled from source (which is desirable in some uncommon cases) without the implementation. It is not easy to predict the exact effects of calling API methods when the implementation is not installed - so clients will usually avoid doing this.

    package com.pluginx.api;
    import com.pluginx.internal.FooFactory;
    public class PluginXAPI {
        public static Foo getFoo() {
            return FooFactory.getFoo();
  2. The API is in a separate package, and uses reflection to access the implementation classes. The API can be compiled without the implementation. The use of reflection might cause a performance hit (but reflection objects can be cached if it's a problem. It is easy to control what happens if the implementation is not available.

    package com.pluginx.api;
    public class PluginXAPI {
        public static Foo getFoo() {
            try {
                return (Foo)Class.forName("com.pluginx.internal.FooFactory").getMethod("getFoo").invoke(null);
            } catch(ReflectiveOperationException e) {
                return null;
                // or throw a RuntimeException, or add logging, or raise a fatal error in some global error handling system, etc
  3. The API consists only of interfaces and abstract classes, plus a way to get an instance of a class.

    package com.pluginx.api;
    public abstract class PluginXAPI {
        public abstract Foo getFoo();
        private static PluginXAPI instance;
        public static PluginXAPI getInstance() {return instance;}
        public static void setInstance(PluginXAPI newInstance) {
            if(instance != null)
                throw new IllegalStateException("instance already set");
                instance = newInstance;
  4. The same as above, but the client code needs to get the initial reference from somewhere else:

    // API
    package com.pluginx.api;
    public interface PluginXAPI {
        Foo getFoo();
    // Implementation
    package com.pluginx.internal;
    public class PluginX extends Plugin implements PluginXAPI {
        public Foo getFoo() { ... }
    // Client code uses it like this
    PluginXAPI xapi = (PluginXAPI)PluginManager.getPlugin("com.pluginx");
    Foo foo = xapi.getFoo();
  5. Don't. Make clients link directly to the plugin (but still prevent them from calling non-API methods). This would make it difficult for many other plugins (and most open source plugins) to use this plugin's API without writing their own wrapper.

| improve this question | | | | |

The answer to your question depends on the definition of "good" in the question "what are some good ways to separate APIs from implementation of ..."

If "good" means "pragmatic easy to implement for you as manufecturer of the api" this might be helpful:

since you are using java where jar-libraries are loaded at runtime i would suggest a slightly different alternative:

  • The API consists only of interfaces plus a dummy implementation of these interfaces that has no real function.

the customer using your api can compile against this dummy-jar and at runtime you can replace the dummy-jar with the licensed one.

something similar is done with slf4j where the actual logging-implementation to be used with your application will be chosen by replacing the logging-jar

| improve this answer | | | | |
  • To expand on the slf4j example: slf4j contains dummy implementations in the sources which then get removed after compiling. The effect of that is a strong reference (which results in a ClassDefNotFound if there's no implementation provided in your application) – dot_Sp0T Oct 5 '15 at 5:55
  • @dot_Sp0T I agree that the "ClassDefNotFound" problem exists for android because in android all jars are merged into one apk file. In ordinary java (withoit using an obfuscator) this should not be a problem. If i am wrong pleas leat me know under wich circumstances happen. – k3b Oct 5 '15 at 12:21

Have you had a look at the ServiceLoader Mechanisms in Java? Basically you can specify the implementation of an interface via the manifest file in a jar. Oracle also provides some further information about plugins in Java programs.

| improve this answer | | | | |

From what I understand people often use the factory pattern for this.

They put the API interfaces into separate module (say a jar file), and then when the clients want to use the API and has access to an implementation of the API, the implementation of the API will have a factory entry point for the clients to start creating concrete objects implementing that API.

This means that your first idea from the above is the closest resemblance.

| improve this answer | | | | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.