Jan 29, 2013

    OSGI Activate & Deactivate signatures

    Posted by Nicolas Peltier

    it's sometimes a bit confusing which signature to use for activate or deactivate in an OSGI component. This is because you have the choice, and this is nice :-) 

    As long as you add the @Activate and @Deactivate tag before your methods, you can have zero, one or several arguments among following types (that will be automatically bound at component activation/deactivation): 


    • ComponentContext - the Component Context for the component
    • BundleContext - the Bundle Context of the component's bundle
    • Map - the Component Properties from ComponentContext.getProperties.     


    • int/Integer - the deactivation reason
    • ComponentContext - the Component Context for the component
    • BundleContext - the Bundle Context of the component's bundle
    • Map - the Component Properties from ComponentContext.getProperties.

    For more information on this, you can look at the dedicated Apache Felix JIRA

    Jan 10, 2013

    Using Event filters for handling JCR events through an event handler.

    Posted by Nicolas Peltier

    In a previous post, i was explaining how to handle events generally, with several solutions among which:

    • jcr observer
    • sling event handler

    a distinction was made between both around the fact jcr observers are low level, but allow to do more. While this is still true :-) this POST will explain how to do a fine-grained jcr event listening through sling event handler (and take profit of the sling event handling framework for those events).

    While in jcr, everything is content, in sling, everything is a resource, so instead of listening to node/property added/removed we'll listen to resource changed, through the 3 topics :

    1. SlingConstants.TOPIC_RESOURCE_ADDED,
    2. SlingConstants.TOPIC_RESOURCE_CHANGED,
    3. SlingConstants.TOPIC_RESOURCE_REMOVED

    Now we should have a handler that listens for all the repository, for those -very common- events, which will certainly be a performance killer. Thus we need to filter out this by adding osgi event filtering

    This EventConstants.EVENT_FILTER property takes LDAP filter syntax, and has a path attribute, so we can do e.g. (path=/content/my/root/*) or even (path=/content/my/root/*/myNode).


    A sample code would then be :

     @Property(name= EventConstants.EVENT_TOPIC,value= {SlingConstants.TOPIC_RESOURCE_ADDED,SlingConstants.TOPIC_RESOURCE_CHANGED, SlingConstants.TOPIC_RESOURCE_REMOVED}),
    public class ExampleServiceImpl implements EventHandler { 
     final String[] eventProps = { "resourceAddedAttributes", "resourceChangedAttributes", "resourceRemovedAttributes" };
     public void handleEvent(org.osgi.service.event.Event event) {
      for (String eventProp : eventProps){
       String[] props = (String[])event.getProperty(eventProp);

    Pros of this approach vs. Jcr Observer are : 

    • this is simpler.
    • this is cluster ready.
    • you have the user id information in it (userid attribute of the event).

    A con i can see is that in the particular case of a bulk save done of N concerned resources, your handler will be called N times, and then if your handler does persist, you'll have a total of N (handler persistences) + 1 (bulk save) persistences done. While with a jcr observer, you can loop through all the changes of the transaction, and do another batch save, reducing the persistences to 2.

    Apr 18, 2012

    Event Handling in CQ

    Posted by Nicolas Peltier

    Event handling can be done in a lot of different ways within CQ, that all have their cost, their impact, and their benefits.

    5 ways of doing so are detailed here :
    - At the JCR level with observation
    - At the Sling level with event handlers and jobs
    - At the CQ level with workflows & launchers
    - Particular case of scheduled events
    - Particular case of POST to the repository

    Read More »