Uploaded image for project: 'Tuscany'
  1. Tuscany
  2. TUSCANY-3547

databinding-sdo module does not execute under OSGi

    XMLWordPrintableJSON

Details

    Description

      The databinding-sdo code does not work under OSGi and fails with a NullPointerException.

      databinding-sdo unsurprisingly uses the Tuscany SDO module, which uses a classic API / Provider pattern using META-INF/services, with the provider classes in a different JAR from the API classes.

      The provider classes are discovered through a lookup for a META-INF/services declaration for "commonj.sdo.impl.HelperProvider".
      The regular OSGi classloading will fail since the declaration is in a separate bundle from that of the API class. It is not correct to make the API bundle depend on the provider bundle, so instead Tuscany has a different classloading approach that must be used.

      This requires some special treatment in order to work under OSGi

      The class within databinding-sdo that is affected is the SDOHelperContext class and the getDefaultHelperContext method in particular. This method causes the loading of the HelperProvider implementation class and then accesses that class to obtain the defaultHelperContext.

      This is done with a simple call to HelperProvider.getDefaultContext();

      Under OSGi, this must instead be done using a Context ClassLoader created using:

      ClassLoaderContext.setContextClassLoader(SDOContextHelper.class.getClassLoader(),
      registry.getServiceDiscovery(),
      // SDO Helper Provider
      "commonj.sdo.impl.HelperProvider"
      );

      The actual loading of the HelperProvider class is unfortunately complex due to a static initializer in the API class (** NB we should get this changed ASAP - it is evil code from an OSGi perspective). The following code is necessary in order to force the use of the Context ClassLoader created by the above Tuscany method:

      ClassLoader tccl = Thread.currentThread().getContextClassLoader();
      HelperProvider.setDefaultInstance(tccl);
      defaultHelperContext = HelperProvider.getDefaultContext();

      ...note the accessing of the class loader

      • followed by the setting of the default instance for the HelperProvider - this does not avoid the static initializer of the HelperProvider class but it assumes that the initializer will fail to find the provider (under OSGi) and instead the setDefaultInstance call using the tccl will instead successfuly load the right provider class.

      This then permits successful use of the getDefaultContext method.

      Attachments

        Activity

          People

            edwardsmj Mike Edwards
            edwardsmj Mike Edwards
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: