Architecture overview


This document describes mechanisms in the Judy project.

Dependency injection

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.

Plugins and autodiscovery

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.

Plugin manager

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.

Simple plugin manager

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.

Overriding plugin manager

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.

Behaviour modification

The following ways of behaviour modification are supported:

Aspects

The Guice provides an ability to use an aspect oriented programming.

Events

The application provides an access to two event buses. Both are implemented using Guava.

Event Bus

The Judy provides an asynchronous event bus for general purpose such as result printing.

Synchronous Event Bus

A synchronous event bus is intended for workflow of the application. Subscribing to this bus could dramatically decrease performance.

Event Bus Facade

In order to facilitate publishing an event a facade was introduced. It publishes given event to both buses.

Subscribing

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.

Multibindings

A multibinding mechanism provided by the Guice allows to bind several bindings simultaneously as a collection.

Overridden bindings

The binding can be substituted using the overriding plugin manager.