SciJava Common is a common library for SciJava software. It provides a plugin framework, with an extensible mechanism for service discovery, backed by its own annotation processor, so that plugins can be loaded dynamically. It is used by both ImageJ and SCIFIO.

Plugin framework

First and foremost, SciJava Common is a plugin framework—a base for developing highly modular and extensible Java applications.

Plugin discovery

All plugins available on Java's classpath are automatically discovered and made available. This is accomplished by scanning classpath resources for the file path META-INF/json/org.scijava.plugin.Plugin. Such files are generated at compile time by a Java annotation processor that writes them in response to @Plugin annotations on Java classes, an idea inspired by the SezPoz project.

Application container

All program state, such as available plugins, is accessible from a root object known as the application context.

Services

Whereas ImageJ1 is a singleton, with static methods to access much of its functionality, ImageJ2 encapsulates its program state in the application context, allowing multiple simultaneous such contexts in the same JVM.

ImageJ encapsulates its various parts as separate "services" that provide related state functionality and track related program state. An instance of the ImageJ class is nothing more than a collection of these services; this instance is referred to as the "application gateway." Services are defined as interfaces, with concrete implementations as plugins. This design provides seams in the right places so that behavior at every level can be customized and overridden.

SCIFIO services

Menuing system

The SciJava menuing system is divided into several layers, to make it easier to override its behavior or customize its appearance in a user interface.

Modules

Each module known to the system (via the ModuleService can have a menuPath that says where it should live (by default) in the menu. It also has a menuRoot that says in which menu it should live, with the default being the APPLICATION_MENU_ROOT, indicating the main application menu structure.

MenuService

The MenuService takes care of constructing ShadowMenu tree structures for all available modules in the system, using their menuPath and menuRoot values. These tree structures are UI-agnostic. There is one ShadowMenu per menuRoot, which can be requested at will from the MenuService.

User interfaces

The UIService then takes care of constructing an actual UI-specific menu bar (or whatever UI components and/or widgets it wants) from the available ShadowMenus. There is a type hierarchy beneath the MenuCreator interface intended for this purpose; for example, the SwingJMenuBarCreator implements MenuCreator to create and maintain a Swing JMenuBar that reflects the state of a particular ShadowMenu.