TomEE and OpenEJB got recently some server side events. It allows us to get some information about the container lifecycle, something you can’t get from standard APIs.
Description
The model is close to the CDI one: an event is fired and you listen to it through observer methods (exact API later in this post).
Hereafter the list of available events while I write these lines:
- ConfigurationLoaded: global configuration is loaded (tomee.xml…)
- AssemblerCreated: the assembler (the part of the container that makes the application something real, once the application metadata is loaded) is created (at container startup)
- AssemblerDestroyed: the assembler is destroyed (when the container shutdowns)
- ObserverAdded: an observer (listener) was added
- ObserverFailed: the observer invocation threw an exception
- ObserverRemoved: an observer was removed
- ComponentAdded: a component (global variable of the container) was added
- ComponentRemoved: a component was removed
- BeforeDeploymentEvent: before an application deployment
- AssemblerAfterApplicationCreated: an application is created (scanning already happened and metadata available)
- AssemblerBeforeApplicationDestroyed: an application is destroyed
Some of these events get some information. For example, the application metadata to deploy for the last ones, the urls to parse for BeforeDeploymentEvent…..
For instance, to do an extension doing something at startup, you can use the ObserverAdded event as it will be called once your observer is created. In fact you can listen yourself in such a case.
How to use it?
Note: you should be able to put your listener(s) in your webapp too even if it sometimes sounds more logical to put them in the container itself
Auto discovery
The first way to register an observer is to create a file in META-INF, named org.apache.openejb.extension, containing the qualified name(s) of your observer(s).
Manually registration
You can also define it manually using service type:
my-listener = new://Service?class-name=<qualified name>
This second way to register a listener is pretty cool, once you’ll be able to configure your service if it is a pojo:
my-listener = new://Service?class-name=<qualified name> my-listener.attr = value
For instance, in OpenEJB you can register an update checker (check that you use the latest stable release):
checker = new://Service?class-name=org.apache.openejb.util.UpdateChecker # all next config is optional checker.repoUrl = http://repo1.maven.org/maven2/ checker.groupId = org/apache/openejb/ checker.checkerProxy = http://proxy:1234 # etc...
Note: it can also be done in tomee.xml (or openejb.xml) using <Service /> tag:
<Service id="checker" class-name="org.apache.openejb.util.UpdateChecker"> repoUrl = http://repo1.maven.org/maven2/ groupId = org/apache/openejb/ checkerProxy = http://proxy:1234 # etc... </Service>
And Java?
In java, listening to an event is trivial : simply add this type of method in a class:
public void iListenObserverAddedEvent(@Observes ObserverAdded event) { // TODO: do something }
Why not using CDI?
It looks like CDI but it isn’t…Why?
Well, the first reason was to make it simple. The second one was to be able to break some CDI rules easily and to get rid of shadows of the specification. CDI is a great API for such a thing. But from a container point of view, it could have been a bit complicated. Typically with CDI, it had been difficult to be able to add your listener in your application. Another point : the events are in openejb so we’d prefer to create a custom API than to let people think it is standard or something re-usable elsewhere. But don’t worry, we still love CDI!
Next?
Next is up to you! Currently we didn’t added too much events since “there is no free lunch” (a clever idiom! Thanks Mark!). But if you have a good usecase for a new event, please simply send an e-mail to openejb mailing list, and we’ll see how to make your need possible!