Pages

Thursday, 28 March 2013

Java ServiceLoader Example

Defining an API and developing the corresponding implementation has become an uber mainstream practice when developing large Java applications. Modularization is such an useful design principle, especially to avoid spaghetti code, for testing and debugging, and for re-implementation of old code.

Many developers seek to separate API interfaces and abstract classes from their implementation in separate packages. Yet, this almost always leads to cycles between java packages (api refers to impl, and vice-versa). There has been many frameworks, such as OSGi, supporting modularization, but the documentation has not always been good and complete. Many developers have struggled with class loading issues too.

Fortunately, Java has delivered the ServiceLoader utility since release 6. The example described in this post is available from Github in the Java-ServiceLoader directory. It is inspired from here.

7 comments:

Looking at the fully qualified names of the classes, such as com.service.API.Impl.MyServiceImpl makes me feel really uncomfortable (irritated, i would say) - as if there was a API class containing inner class called Impl, containing another inner class MyServiceImpl.

Is there a reason why code conventions http://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html are disobeyed?

Sure. After Java loads the code for the implementation of the service API, it needs to create a new() instance of the implementing object. But, it does not know anything about potential parameters it could/should pass to the constructor. If the implementation did not have a parameterless constructor, calling new() would trigger a runtime exception. Hence, the need for this parameterless constructor so Java can call it when new() is called to create the implementing object instance.

Thanks for the explanation. A follow up question:Consider the javadoc:http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.1-110-F.2.

It says:"In addition, the constructor of a non-private inner member class must be compiled such that it has as its first parameter, an additional implicit parameter representing the immediately enclosing instance (§8.1.3)."

So does that mean I cannot externalize a inner class. Please consider the following code:

As per described in the documentation you are pointing at, the ABC constructor does not have an instance of Y as a parameter... If you made ABC a static class of Y, you would not have an issue. You can also ask such questions on StackOverflow.com too.