Code documentation

Development tools

Code Structure

Techniques and Standards

How To

Functional Info

Background Info

JMRI Code: Plug-in mechanisms

The original goal of the JMRI project was to produce a library upon which people could use to build their own applications. Although some people do that, more use the existing applications such as DecoderPro and PanelPro.
We want to make this more flexible by providing a way to extend those programs without having to rebuild them from scratch.

There are three supported mechanisms that can be used to plug additional capabilities into JMRI:

Script JMRI

Scripting JMRI is often the easiest way to extend JMRI, however there are limitations to that which are covered by the other mechanisms.

The principal limitations to scripting JMRI are:

The details of scripting are covered elsewhere.

Examples of scripts that modify JMRI behavior are:

Implement a Service Provider

Java contains a Service Loader that allows classes implementing a specific API to provide a service to a Java application without requiring that the application have prior dependencies defined for that service.

Services are provided by creating a JAR for that service and appending it to the JMRI classpath. See Startup Scripts for details on appending a JAR to the classpath and the Service Loader documentation concerning what needs to be in that JAR.

JMRI uses Service Loaders to allow a JMRI application to be extended in specific ways:

Every manufacturer selectable when creating a configuration is defined by a ConnectionTypeList service. Implement this (and other required classes) to create a new system connection type. See Adding a New System for details.
Add new factories for creating default instances of objects managed by the InstanceManager.
The JMRI JSON services used in the JMRI web services can be extended using service implementations of this class. See the JsonServiceFactory Javadocs for details.
Add a new preferences manager to JMRI. Preferences managers store, retrieve, and validate preferences within a JMRI configuration profile. If a plugin needs to take action very early in the JMRI application startup sequence, it would need to provide a PreferencesManager service.
Additional preferences can be displayed in the preferences window by providing an implementation of this class.
Startup Actions can be run at application start or attached to the application's main window as a button. Implementations of this factory class expose additional startup actions that can be selected by the user.
Startup Models provide a mechanism to define optional startup actions that require user-provided parameters to be automatically run. Implementations of this factory class provide the hooks so that the Startup preferences can allow a user to set the parameters for a given action.
HttpServlet with WebServlet annotation
Additional servlets in the web server can be added using these mechanisms. Note that the WebServlet annotation needs to provide a name and urlPatterns.
Additional file paths, redirections, explicitly blocked paths in the JMRI web server can be specified by providing a service that implements this.

Override jmri.JmriPlugin

The first instance of JmriPlugin will have its start method called while the JMRI application launches. This makes it possible to allow the application's main window and main menu to be extended. Use of this mechanism is limiting because JmriPlugin can only be overridden once.