This document describes mechanisms in the Judy project.
Judy extensively relies on a dependency injection. The Guice project is the chosen approach. Using this solution modules can be relatively small and loosely coupled. This capability is very important in the Judy design because enables easier plugin switching, testing and facilitate introduction of functionality.
Before a context is initialized the application collects all reachable modules from a classpath. To achieve this the ServiceLoader is used. To put this simply each marked module is loaded to the context. However the ServiceLoader has some limitations such us lack of control on a class instantiation and does not take into account a module inheritance. This may leads to a binding conflict when one module inherits from other. To bypass this issue modules have to be small, simple and final.
A plugin manager is a mechanism which creates the application context (precisely the guice injector) from loaded modules. By default a simple plugin manager is used.
A very simple mechanism, recommended by Guice philosophy, which collects and joins all modules fairly. It promotes small plugins. Each conflict leads to an unrecoverable exception and an application halt.
A more complex mechanism, which tries to override bindings in the context. The order of discovery is nondeterministic. However each module can define other modules that should be processed earlier in order to allow overriding of predecessor’s binding and not get overridden by his. This mechanism allows a substitution of existing object in the whole application.
Circular dependencies are detected and an appropriate warn is raised. The application is not halted. Multiple and potentially unwanted overridings are not detected.
The following ways of behaviour modification are supported:
The Guice provides an ability to use an aspect oriented programming.
The application provides an access to two event buses. Both are implemented using Guava.
The Judy provides an asynchronous event bus for general purpose such as result printing.
A synchronous event bus is intended for workflow of the application. Subscribing to this bus could dramatically decrease performance.
In order to facilitate publishing an event a facade was introduced. It publishes given event to both buses.
The Guava event bus is well known of its ability to integrate easily with the Guice. However this approach requires a creation of the bus outside of the context. Then the bus cannot be parametrized using an integrated argument mechanism. Therefore other approach was chosen, where the bus is created in the context and subscribers have to be added to an appropriate multibinding.
A multibinding mechanism provided by the Guice allows to bind several bindings simultaneously as a collection.
The binding can be substituted using the overriding plugin manager.