Archive

Archive for the ‘Lookup’ Category

Recipe 1: Loose coupling

May 19, 2013 Leave a comment

Problem:
You would like to create a loose coupled design, i.e. depend on interface instead of implementation. Netbeans uses a component-based way of development. Modules or components developed by independent groups or individuals must be able to communicate with each other in a loose coupled way.


Fig. 1 – Loose coupling

However, the big question is how does the client find the implementation? Spring uses dependency injection or inversion of control via its xml files. Java 6 uses a Query-based approach, the ServiceLoader:

ServiceLoader<Provider> serviceLoader = ServiceLoader.load(Provider.class);
for (Provider provider : serviceLoader) { return provider; }

However, the ServiceLoader has a number of problems:

  • it isn’t dynamic (you cannot install/uninstall a plugin/service at runtime)
  • it does all service loading at startup (as a result it requires longer startup time and more memory usage)
  • it cannot be configured; there is a standard constructor and it doesn’t support factory methods
  • it doesn’t allow for ranking, i.e. we cannot choose which service to load first

Solution:
Netbeans introduces a new way to accomplish loose coupling, the ServiceProvider:

@ServiceProvider(service = Provider.class)
public class ProviderImpl implements Provider { }

The magic line is the first line which tells Netbeans that this class is an implementation of the service Provider.class. Netbeans creates a text file package.Provider inside build/classes/META-INF/services/ folder of the module which contains the fully qualified names of the implementation classes, e.g. package.ProviderImpl. If you have worked with ServiceLoader, then this is not new to you.

However, the big question has not been answered yet. How does the client find the implementation? In Netbeans this is done with the use of lookups! The client looks in the default lookup for the interface. The default Lookup is a Lookup that evaluates the service declarations in the META-INF/services folder. It is callable through the Lookup.getDefault() method. By asking for a service interface in this way, you receive instances of implementing classes
registered in the META-INF/services folder.

A lookup is a map with class objects as keys and sets of instances of these class objects as values, i.e. Lookup = Map<Class, Set<Class>>, e.g. Map<String, Set<String>> or Map<Provider, Set<Provider>>. Netbeans provides a number of methods to access a lookup:

Provider provider = Lookup.getDefault().lookup(Provider.class);
provider.aMethod();

or if you have more than one implementations of Provider:

Collection <? extends Provider> providers = Lookup.getDefault().lookupAll(Provider.class);
for (Provider provider : providers) { }

As you can see from the above code examples, the client has no clue about which implementation it uses; it only knows the interface. Loose coupling!

Imagine the lookup as a map in memory which stores implementations of all the services of your application. You put the service implementation in the lookup when you define it with the @ServiceProvider annotation and then you search for it using the above commands.

ServiceProvider does not have the drawbacks of ServiceLoader, mentioned above. It is dynamic, so you can plugin/unplug modules while your application is running, it doesn’t load all services at startup and allows you to set priorities (with the position attribute), e.g.:

@ServiceProvider(service = Provider.class, position=1)

NetBeans orders instances by ascending positions, i.e. instances with smaller numbers are returned before instances with larger numbers.

There are other lookups in Netbeans apart from the default lookup which is used to store services implementations, and this often brings confusions. E.g. each OutlineView or TopComponent associates with it a lookup to store the nodes that are selected at a specific time. You should not confuse this lookup with the default lookup.
More on lookups on future posts.

References:

  1. Epple A. (2009), “NetBeans Lookups Explained!“, NetBeans DZone.
  2. Lof Nicklas (2010), “That other Lookup“.
  3. Lof Nicklas (2010), “Power of Lookup“.
  4. Antonios lookup articles.
Categories: Lookup