Extension Points
By defining extension points in your plugin, you can allow other plugins to extend your plugin's functionality. There are two types of extension points:
Interface extension points allow other plugins to extend your plugins with code. When defining an interface extension point, specify an interface, and other plugins will provide classes implementing that interface. The providing plugin can then invoke methods on this interface. In most cases, the interface can be annotated with
@ApiStatus.OverrideOnly
(see Override-Only API).Bean extension points allow other plugins to extend a plugin with data. Specify the fully qualified name of an extension class, and other plugins will provide data that will be turned into instances of that class.
Declaring Extension Point
Add an
<extensionPoints>
section to plugin.xml, if it's not yet present there.Add a child element
<extensionPoint>
.Specify the extension point name with the
name
orqualifiedName
attribute *.Depending on the extension point type, specify the
interface
orbeanClass
attribute *.If required, specify the
area
attribute *.
See the Example.
* see the Attributes section for <extensionPoint>
for details
The plugin that contributes to the extension point will read the specified properties from the plugin.xml file.
If extension implementations are filtered according to dumb mode, the base class should be marked with PossiblyDumbAware
to highlight this. Use DumbService.getDumbAwareExtensions()
to retrieve dumb-aware implementations.
Base classes for extensions requiring a key:
Example
Consider example extension points declarations:
myPlugin/META-INF/plugin.xml
The com.example.MyBeanClass
bean class used in the above plugin.xml
file is implemented as follows:
myPlugin/src/com/myplugin/MyBeanClass.java
For above extension points, their usage in anotherPlugin would look like this (see also Declaring Extensions):
anotherPlugin/META-INF/plugin.xml
Using Extension Points
To refer to all registered extension instances at runtime, declare an ExtensionPointName
with private visibility passing in the fully qualified name matching its declaration in plugin.xml. If needed, provide a public method to query registered extensions (Sample: TestSourcesFilter.isTestSources()
).
myPlugin/src/com/myplugin/MyExtensionUsingService.java
A gutter icon for the ExtensionPointName
declaration allows navigating to the corresponding <extensionPoint>
declaration in plugin.xml. Code insight is available for the extension point name String literal (2022.3).
Error Handling
When processing extension implementations or registrations, there might be errors, compatibility and configuration issues. Use PluginException
to log and correctly attribute the causing plugin for builtin error reporting.
To report use of deprecated API, use PluginException.reportDeprecatedUsage()
methods.
Examples:
Dynamic Extension Points
To support Dynamic Plugins, an extension point must adhere to specific usage rules:
extensions are enumerated on every use and extensions instances are not stored anywhere
alternatively, an
ExtensionPointListener
can perform any necessary updates of data structures (register viaExtensionPointName.addExtensionPointListener()
)
Extension points matching these conditions can then be marked as dynamic by adding dynamic="true"
in their declaration:
All non-dynamic extension points are highlighted via Plugin DevKit | Plugin descriptor | Plugin.xml dynamic plugin verification inspection.