Just as Jenkins core defines a set of extension points, your plugin can define new extension points so that other plugins can contribute implementations. This page shows how to do that.
Extension points may be defined in either of two ways:
- Singleton pattern
- Describable/Descriptor pattern (builds on singleton pattern)
First, you define your contract in terms of an abstract class. (You can do this in interfaces, too, but then you'll have hard time adding new methods in later versions of your plugin.) This class should implement the marker hudson.ExtensionPoint interface, to designate that it is an extension point.
For convenience you can also define a static method conventionally named
all. The returned
ExtensionList allows you discover all the implementations at runtime.
The following code shows this in a concrete example:
In addition to these basic ingredients, your extension point can implement additional interfaces, extend from another base class, define all sorts of methods, etc. Because the extension implementations will be singletons, usually the default no-argument constructor suffices.
Also, this system is only necessary when you need to discover the implementations at runtime. So if your extension point consists of a group of several classes and interfaces, normally only the entry point needs to follow this convention. Such an example can be seen in hudson.scm.ChangeLogParser in the core —
ChangeLogParser implementations are always created by hudson.scm.SCM implementations, so
ChangeLogParser is not an extension point.
Enumerating implementations at runtime
The following code shows how you can list up all the
Animal implementations contributed by other plugins.
There are other convenience methods to find a particular instance, and so on. See hudson.ExtensionList for more details.
Implementing extension points
Implementing an extension point defined in a plugin is no different from implementing an extension point defined in the core. See hudson.Extension for more details.
If you are going to define a new extension point that follows the hudson.model.Describable/hudson.model.Descriptor pattern, the convention is bit different. This pattern is used when users should be able to configure zero or more instances of some things you define.
In this case the singleton is a
Descriptor: a description of the kind of thing a user can create and configure. There is a matching
Describable class which represents the actual things being created and configured. Confusingly, the convention is to place the
ExtensionPoint marker on the
Describable class, even though
@Extension will be put on implementations of the
For this, first you define your
Describable subtype and
An extension for Food would look like this:
Typically you will also need a
src/main/resources/…/MyFoodImpl/config.jelly providing its configuration form. The exact Jelly views needed for a describable vary according to how the extension point is used.