Application Extensions |
![]() |
An application extension is a supported SPI for application-level server startup work. An OSGi
bundle contributes an appExtension element to org.eclipse.emf.cdo.server.appExtensions; the server
instantiates the declared class, so its no-argument construction must not depend on a repository already existing.
Choose a callback interface for the context and lifecycle you need, install repository-specific listeners or
handlers in that callback, and remove those exact registrations on stop. An application extension orchestrates
application behavior; it is not itself a repository handler, a repository listener, or a managed-container factory.
| 1 | Choosing an Extension Variant | ||
| 2 | Lifecycle Discipline | ||
| 3 | Repository-aware Extension Example | ||
The interfaces extend the base IAppExtension lifecycle. The packaged server constructs one contributed
instance at startup, then calls IAppExtension.start(File) and later IAppExtension.stop(). The base
form receives the application XML file, but no repository array; look repositories up through a supported
container context only when appropriate.
IAppExtension2 adds IAppExtension2.startDynamic(Reader) for each dynamically configured
repository. The repository-configuration manager creates a separate extension instance for each dynamic start,
passes that repository's XML, and calls that instance's stop() when the repository deactivates. A dynamic
extension must therefore keep per-instance cleanup state and must not assume its base start(File) was
called for that dynamic instance.
IAppExtension3 receives the initially configured repositories and config file in its
repository-aware start callback, with a matching repository-array stop callback instead of the base callback
pair. It is the clearest choice for installing one listener/handler per configured repository. The array describes
initial startup; later dynamic repositories have their own configuration lifecycle and do not appear in it.
IAppExtension4 supplies a numeric priority: smaller values start first within their phase and stop in
reverse order; extensions without it use the default priority. IAppExtension5 supplies a logging name and
selects the early phase through IAppExtension5.startBeforeRepositories(). Early callbacks run before the
repository configurator and must not use repository state. These are orthogonal choices; an extension can
implement more than one variant.
Startup and stop callbacks run synchronously on the server application lifecycle path. Keep them bounded. Retain only the repository/listener/handler pairs needed for teardown. If setup fails after installing some listeners, remove the partial set in the start method's failure path: the packaged application logs an extension exception and continues, but does not call stop() as rollback for a failed start. On normal stop, remove those registrations before the owning repositories deactivate. Repository listener callbacks may run on the event delivery thread, so queue expensive work elsewhere. The contribution's predecessor attribute suppresses a competing extension implementation; it is not an ordering mechanism. Do not depend on internal repository classes merely because the packaged application uses them.
This repository-aware extension notifies an application service when its session state changes. It stores every listener that it adds, unwinds partial setup if installation fails, and removes exactly those listeners on shutdown.
Contribute the extension from its bundle's plugin.xml with
.