13 Replies Latest reply on Jun 21, 2010 7:18 AM by thomas.diesler

    Configuring the AutoInstallPlugin to cater for start levels

    bosschaert

      I'm currently working on implementing the Start Level Service and as part of this users should be able to set the start level of a bundle that is configured through the AutoInstallPlugin...

       

      Currently its configuration looks like this:

      {code:xml}  <bean name="OSGiAutoInstallPlugin">
          <!-- snip -->
          <property name="autoStart">
           <list elementClass="java.net.URL">
            <value>${osgi.home}/server/minimal/deploy/org.apache.felix.log.jar</value>
            <value>${osgi.home}/server/minimal/deploy/jboss-osgi-common.jar</value>
            <value>${osgi.home}/server/minimal/deploy/jboss-osgi-hotdeploy.jar</value>
           </list>
          </property>
        </bean>{code}

       

      I was thinking about how users would configure this in the AutoInstall configuration... I think they're 3 options:

       

      1. I could change the autoStart property into a map where the key is the url and the value is the start level, like this:

      {code:xml}  <bean name="OSGiAutoInstallPlugin">
          <!-- snip -->
          <property name="autoStart">
            <map keyClass="java.net.URL" valueClass="java.lang.Integer">
              <entry>
                <key>${osgi.home}/server/minimal/deploy/org.apache.felix.log.jar</key>
                <value>3</value>
              </entry>
              <entry>
                <key>${osgi.home}/server/minimal/deploy/jboss-osgi-common.jar</key>
                <value>4</value>
              </entry>
              <entry>
                <key>/server/minimal/deploy/jboss-osgi-hotdeploy.jar</key>
                <value>4</value>
              </entry>
            </map>
          </property>
        </bean>{code}

      I don't really like it as it's quite verbose, not backwards compatible and cannot be extended (if we want to add further metadata to the bundle list).

       

      2. Alternatively I could keep it a list like it is now, but enhance the syntax so that the start level can be part of the URL:

      {code:xml}  <bean name="OSGiAutoInstallPlugin">
          <!-- snip -->
          <property name="autoStart">
           <list elementClass="java.net.URL">
            <value>${osgi.home}/server/minimal/deploy/org.apache.felix.log.jar?startLevel=3</value>
            <value>${osgi.home}/server/minimal/deploy/jboss-osgi-common.jar?startLevel=4</value>
            <value>${osgi.home}/server/minimal/deploy/jboss-osgi-hotdeploy.jar?startLevel=4</value>
           </list>
          </property>
        </bean>{code}

      An advantage of this is that it can be made backward compatible and is fairly simple. It can also be enhanced to contain other metadata in the future...

       

      3. Finally we could introduce a value object (bean) that is strongly typed and then put in a list of these. I think this is might be overkilll...

       

      Thoughts anyone? I think I like option 2 best...

        • 1. Re: Configuring the AutoInstallPlugin to cater for start levels
          alesj
          Thoughts anyone? I think I like option 2 best...

          Both 1 and 2 are too much impl details, and 1 is even not extendable.

          I would go with 3, if this is where you meant custom xml?

           

          With JBossXB it is trivial to add new xml mapping -- see my OSGiMetaData from service-mix.

          And this way we hide the impl details, and extending is just a matter of new namespace version -- if really needed.

          • 2. Re: Configuring the AutoInstallPlugin to cater for start levels
            thomas.diesler

            AFAICS, the bundle's start level is a piece of meta data that is not directly associated with the bundle itself (i.e. it is not part of the bundles manifest). There is good reason to do so, because it allows the environment where the bundle is installed to specifiy at what start level the bundle should be started . The bundle itself does not need to be modified for this.

             

            Going forward, it is likely that we will have a number of jboss specific options that go beyond simple key/value pairs. I would agree with Ales to provide something like

             

            <jboss-osgi>
               <start-level>3</start-level>
            </jboss-osgi>
            

             

            This could be packaged with the bundle or defined externally as part of the config. Generally our bundle metadata should be the unified view of standard and non-standard (i.e. jboss specific) metadata

             

            Also, the user might want to do

             

            @StartLevel(3)
            SomeActivator implements BundleActivator
            

             

            In any case, the AutoStartPlugin should obtain the start level from the bundle's metadata and not do the processing of this specific piece of meta data itself.

            • 3. Re: Configuring the AutoInstallPlugin to cater for start levels
              bosschaert

              Hi Ales,

               

              Could you provide a URL to the OSGiMetaData file you're talking about? I have trouble finding it...

               

              David

              • 4. Re: Configuring the AutoInstallPlugin to cater for start levels
                alesj
                Could you provide a URL to the OSGiMetaData file you're talking about? I have trouble finding it...

                * http://anonsvn.jboss.org/repos/jbossas/projects/jboss-osgi/projects/runtime/framework/branches/service-mix/src/main/java/org/jboss/osgi/framework/metadata/internal/OSGiPojoMetaData.java

                 

                You need to find the equivalent in git repo.

                • 5. Re: Configuring the AutoInstallPlugin to cater for start levels
                  bosschaert

                  Ah OSGiPojoMetaData... Found it.

                   

                  At what point can I start using the custom XML in the deployment? For instance if I put your custom XML at the bottom of my xml file (attached)

                    ...

                    <osgi xmlns="urn:jboss:pojo2osgi:1.0" name="A">
                      <exposed-type>org.jboss.test.osgi.service.support.a.AMBean</exposed-type>
                    </osgi>

                  </deployment>

                  just to try out the parsing I'm getting a parse error... See below.

                   

                  Thanks,

                   

                  David

                   

                  Caused by: org.jboss.xb.binding.JBossXBException: Failed to parse source: file:/home/davidb/clones/b-jbosgi-framework_040510/bundle/target/test-classes/org/jboss/test/osgi/framework/bootstrap/test-bootstrap-auto-install.xml@329,98
                      at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:166)
                      at org.jboss.xb.binding.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:147)
                      at org.jboss.kernel.plugins.deployment.xml.BasicXMLDeployer.deploy(BasicXMLDeployer.java:147)
                      at org.jboss.osgi.framework.launch.OSGiFrameworkFactory.newFramework(OSGiFrameworkFactory.java:140)
                      ... 29 more
                  Caused by: org.jboss.xb.binding.JBossXBRuntimeException: {urn:jboss:pojo2osgi:1.0}osgi cannot appear in this position. Expected content of {urn:jboss:bean-deployer:2.0}deployment is unordered_sequence: {urn:jboss:bean-deployer:2.0}stop? {urn:jboss:bean-deployer:2.0}destroy? {urn:jboss:bean-deployer:2.0}annotation* {urn:jboss:bean-deployer:2.0}alias* {urn:jboss:bean-deployer:2.0}start? {urn:jboss:bean-deployer:2.0}classloader? {urn:jboss:bean-deployer:2.0}create? {choice}* {wildcard}*
                      at org.jboss.xb.binding.sunday.unmarshalling.position.ElementPosition.nextPosition(ElementPosition.java:206)
                      at org.jboss.xb.binding.sunday.unmarshalling.position.ElementPosition.startParticle(ElementPosition.java:499)
                      at org.jboss.xb.binding.sunday.unmarshalling.SundayContentHandler.startElement(SundayContentHandler.java:207)
                      at org.jboss.xb.binding.parser.sax.SaxJBossXBParser$DelegatingContentHandler.startElement(SaxJBossXBParser.java:382)
                      at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
                      at org.apache.xerces.xinclude.XIncludeHandler.startElement(Unknown Source)
                      at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
                      at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
                      at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
                      at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
                      at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
                      at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
                      at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
                      at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
                      at org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBParser.java:162)
                      ... 32 more

                  • 6. Re: Configuring the AutoInstallPlugin to cater for start levels
                    alesj
                    At what point can I start using the custom XML in the deployment?

                    After you register the schema / namespace against XB SchemaResolver:

                     

                      <bean name="OSGiSingletonSchemaResolverFactory">
                          <constructor factoryClass="org.jboss.xb.binding.sunday.unmarshalling.SingletonSchemaResolverFactory" factoryMethod="getInstance"/>
                      </bean>
                      
                      <bean name="Pojo2OSGiSchema">
                          <constructor factoryMethod="getSchemaBindingResolver">
                              <factory bean="OSGiSingletonSchemaResolverFactory"/>
                          </constructor>
                          <install method="mapURIToClass">
                              <parameter>urn:jboss:pojo2osgi:1.0</parameter>
                              <parameter>org.jboss.osgi.framework.metadata.internal.OSGiPojoMetaData</parameter>
                          </install>
                          <uninstall method="removeURIToClassMapping">
                              <parameter>urn:jboss:pojo2osgi:1.0</parameter>
                          </uninstall>
                      </bean>
                    • 7. Re: Configuring the AutoInstallPlugin to cater for start levels
                      bosschaert

                      Right but I guess I would then have to split my configuration files into multiple ones. Currently it looks like JBoss OSGi is only using a single configuration file but this will then have to be split up as the AutoInstall plugin is an important part of the booting process.

                       

                      I guess it makes sense to reorganize the configuration into a single shared configuration file and other config files specific to the profile that you're running (web, minimal, etc)... I'll have a look into this...

                      • 8. Re: Configuring the AutoInstallPlugin to cater for start levels
                        bosschaert

                        Where would I find any documentation on how to properly annotate my custom namespace URL handler?

                         

                        I'd probably like to configure the AutoInstall like this:

                        {code:xml}<deployment xmlns="urn:jboss:bean-deployer:2.0">

                          <auto-install xmlns="urn:jboss:autoinstall:1.0" name="OSGiAutoInstallPlugin"

                              class="org.jboss.osgi.framework.plugins.internal.AutoInstallPluginImpl">

                            <constructor><parameter><inject bean="OSGiBundleManager" /></parameter></constructor>

                            <url>file:///bundle1</url> <!-- use default start level -->

                            <url startlevel="42">file:///bundle2</url>

                          </auto-install>

                        </deployment>{code}

                         

                         

                        My current AutoInstallMetaData doesn't fully handle it yet.

                         

                        {code}@ManagementObject(properties = ManagementProperties.EXPLICIT)

                        @JBossXmlSchema(namespace = "urn:jboss:autoinstall:1.0", elementFormDefault = XmlNsForm.QUALIFIED)

                        @XmlRootElement(name = "auto-install")

                        @XmlType(name = "autoInstallType", propOrder = { "constructor", "url" })

                        public class AutoInstallMetaData extends AbstractBeanMetaData

                        {

                           @XmlElement(name = "url")

                           public void setUrl(String u)

                           {

                              // want to cater for multiple URLs here, should setUrl be a Collection<String>?

                              // how do I read out the start level attribute here?

                           }

                        }{code}

                         

                        Any tips?

                        • 9. Re: Configuring the AutoInstallPlugin to cater for start levels
                          bosschaert

                          Or is it standard JAXB? Looking into that now. I had the impression this was JBoss XB-specific...

                          • 10. Re: Configuring the AutoInstallPlugin to cater for start levels
                            bosschaert

                            Ok after digging a little deeper I got it to work. Although it mostly uses JAXB annotations, the observed behaviour is not exactly the same as with JAXB. But the good news is that what I have now works on a file that looks like this:

                             

                            {code:xml}<auto-install xmlns="urn:jboss:autoinstall:1.0" name="OSGiAutoInstallPlugin"

                                class="org.jboss.osgi.framework.plugins.internal.AutoInstallPluginImpl">

                                <constructor><parameter><inject bean="OSGiBundleManager" /></parameter></constructor>

                                <bundle>

                                    <url>file:///bundle1</url>

                                </bundle>

                                <bundle start-level="42">

                                    <url>file:///bundle2</url>

                                </bundle>

                            </auto-install>{code}

                             

                            Here's code:

                             

                            {code}@ManagementObject(properties = ManagementProperties.EXPLICIT)

                            @JBossXmlSchema(namespace = "urn:jboss:autoinstall:1.0", elementFormDefault = XmlNsForm.QUALIFIED)

                            @XmlRootElement(name = "auto-install")

                            @XmlType(name = "autoInstallType", propOrder = { "constructor", "bundle" })

                            public class AutoInstallMetaData extends AbstractBeanMetaData

                            {

                               private static final long serialVersionUID = 1L;

                             

                               private List<AutoInstallEntry> bundles;

                             

                               public List<AutoInstallEntry> getBundle()

                               {

                                  return bundles;

                               }

                             

                               @XmlElement(name = "bundle")

                               public void setBundle(List<AutoInstallEntry> b)

                               {

                                  bundles = b;

                               }

                            }{code}

                             

                            AutoInstallEntry is defined as this:

                             

                            {code}@XmlType(name = "autoInstallBundleEntry", propOrder = { "url" })
                            public class AutoInstallEntry
                            {
                               private String url;
                               private int startLevel = 1;

                               @XmlAttribute(name = "start-level")
                               public void setStartLeve(String sl)
                               {
                                  try
                                  {
                                     startLevel = Integer.parseInt(sl);
                                  }
                                  catch (NumberFormatException e)
                                  {
                                     // do something!
                                  }
                               }

                               @XmlElement(name = "url")
                               public void setUrl(String u)
                               {
                                  url = u;
                               }
                            }{code}

                             

                            Any feedback welcome

                            • 11. Re: Configuring the AutoInstallPlugin to cater for start levels
                              alesj
                              <auto-install xmlns="urn:jboss:autoinstall:1.0" name="OSGiAutoInstallPlugin"
                                  class="org.jboss.osgi.framework.plugins.internal.AutoInstallPluginImpl">
                                  <constructor><parameter><inject bean="OSGiBundleManager" /></parameter></constructor>
                              

                              Since you already have custom xml, why don't you make name, class and ctor an impl detail.

                              The defaults being what you use now, but can of course be overridden if the user wants so.

                              • 12. Re: Configuring the AutoInstallPlugin to cater for start levels
                                bosschaert

                                I moved this configuration to the start level plugin. It looks like this:

                                 

                                {code:xml}  <start-level xmlns="urn:jboss:startlevel:1.0">

                                    <bundle symbolic-name="abc" version="1.2.3" start-level="5"/>

                                    <bundle symbolic-name="def" auto-start="false"/>

                                  </start-level>{code}

                                 

                                I'd still like to do an alternative, non-centralized approach at some point as AutoInstall semantics in supported target containers....

                                • 13. Re: Configuring the AutoInstallPlugin to cater for start levels
                                  thomas.diesler
                                  <bundle symbolic-name="def" auto-start="false"/>

                                   

                                   

                                  What does the 'auto-start' property do?