2 Replies Latest reply on May 21, 2015 8:50 AM by jkraushaar

    How to add sequencers dynamically in an OSGi environment?

    jkraushaar

      Hi there,

       

      I know that it is possible to add sequencers dynamically if you edit the configuration. This works perfectly if ModeShape and the sequencer share the same Classloader. But we like to add sequencers dynamically in an OSGi environment. The ModeShape OSGi bundle does not know the sequencer bundle. I cannot add the sequencer by editing the configuration because I can only set the class name and not an instance of the sequencer (which is provided as OSGi service).

       

      Are there other ways to add an sequencer instance to ModeShape?

       

      Regards

      Jochen

        • 1. Re: How to add sequencers dynamically in an OSGi environment?
          hchiorean

          The current code always uses the classloader of the Sequencers class (from modeshape-jcr.jar) to load sequencer instances (https://github.com/ModeShape/modeshape/blob/modeshape-4.3.0.Final/modeshape-jcr/src/main/java/org/modeshape/jcr/Sequencers.java#L127)

          While you can't change the classloader which loads the sequencers, there is a "classloader" string attribute which you can use on a custom sequencer.

           

          For example:

          "sequencing" : {
                  "sequencers" : {          
                      "custom" : {
                          "classname" : "FQN",
                          "classloader" : "jar:file:/some_file.jar"
                          "pathExpressions" :
                      }
                  }
          
          
          

           

          When creating the sequencer instance, even though the root classloader will be that of the modeshape-jcr.jar, if you set the "classloader" attribute, a URLClassLoader will be used and ModeShape will attempt to find the sequencer classname not only via the default loader, but also at the path specified by "classloader" (modeshape/LocalEnvironment.java at modeshape-4.3.0.Final · ModeShape/modeshape · GitHub)

          If you look at the above code, the other workaround you can try is to change the TCCL and use another loader, since the TCCL will always be involved in the mix if it's different than the CL which loaded the Sequencer class.

           

          I don't know if any of these will work in an OSGI environment, but they might be worth a try.

          • 2. Re: How to add sequencers dynamically in an OSGi environment?
            jkraushaar

            OSGi is very restrict when it comes to ClassLoaders. The framework creates ClassLoaders for each installed bundle. Referencing the ClassLoader the way you described will not work, I think.

             

            But I found another solution to my problem:

            1. Put the custom sequencer into a fragment bundle.
            2. Add the fragment bundle to the ModeShape bundle. They share the same ClassLoader.
            3. Create an OSGi bundle tracker as part of the ModeShape bundle. The tracker tracks bundles in the RESOLVED state. When a bundle switches its state, the tracker checks if the bundle is a fragment bundle of its own bundle. Then it checks if the manifest of the fragment bundle contains information about the sequencer name, class and path expression and - if yes - adds the sequencer to the ModeShape configuration. (This is actually an implementation of the OSGi Extender Pattern.)