+

Search Tips   |   Advanced Search

Develop with the JNDI default namespace in a Liberty feature

We can make an object available in the default Java Naming and Directory Interface (JNDI) namespace. To do that, we must register it in the OSGi service registry with the osgi.jndi.service.name service property. The value of osgi.jndi.service.name is the required JNDI name. Similarly, to find an object in the default JNDI namespace, we can search the OSGi service registry with the osgi.jndi.service.name service property. The value of osgi.jndi.service.name is the JNDI name.

Compared with explicitly calling Context.bind or Context.lookup, using the service registry has the following benefits:

For more information about JNDI, see Naming.

  1. Register a service using the osgi.jndi.service.name property with the JNDI name. For more information about registering services, see Register OSGi services.

  2. Update the metatype.xml to allow a JNDI name to be specified in server configuration. To allow users to specify a JNDI name for the service, we should use the jndiName id for consistency with other features in the Liberty profile run time, for example:

      <AD id="jndiName" name="JNDI name" description="JNDI name for a widget." type="String" ibm:unique="jndiName"/>

    We can use an internal attribute to automatically set the osgi.jndi.service.name service property with the value of the jndiName attribute, for example:

      <AD id="osgi.jndi.service.name" name="internal" description="internal" type="String" default="${jndiName}"/>

    For more information about OSGi Metatype, see Advanced Configuration.

  3. Implement the ResourceFactory interface if we need Java EE resource reference information. If our service needs Java EE resource reference information, such as res-auth, we can register a ResourceFactory in the OSGi service registry with the jndiName and creates.objectClass properties. The ResourceFactory service is re-registered automatically with the osgi.jndi.service.name property. For example:

        import com.ibm.wsspi.resource.ResourceFactory;
        public class WidgetResourceFactory implements ResourceFactory { ... }
    
        Properties properties = new Properties();
        properties.put(ResourceFactory.JNDI_NAME, "widget/abc");
        properties.put(ResourceFactory.CREATES_OBJECT_CLASS, Widget.class.getName());
        bundleContext.registerService(ResourceFactory.class, new WidgetResourceFactory(), properties);
    Alternatively, the service could be registered automatically using declarative services and metatype. In that case, we can specify the creates.objectClass property as a declarative services property. You do not need to specify the jndiName property because it is set automatically from the user configuration with the <AD id="jndiName"> element in the metatype.xml file in step 2, and we do not need an <AD id="osgi.jndi.service.name> element in the metatype.xml file because the ResourceFactory service will be re-registered automatically.

  4. Locate an object using the osgi.jndi.service.name property with the JNDI name. For example:

      bundleContext.getServiceReference(DataSource.class, "(osgi.jndi.service.name=jdbc/myds)");

    Alternatively, we can locate a ResourceFactory using the jndiName and creates.objectClass properties.

  5. Update the metatype.xml to allow a resource to be specified in server.xml using the id of the resource. This allows the resource to be accessed regardless of whether or not the resource has a jndiName. For example,

      <AD id="dataSourceRef" type="String" ibm:type="pid" ibm:reference="com.ibm.ws.jdbc.dataSource" cardinality="1" name="%dataSourceRef" description="%dataSourceRef.desc"/>

    If we are using declarative services, we can use an internal attribute to set a .target service property with a filter. For example, if the declarative services component has a reference named dataSource, we can use the following attribute definition to ensure that the dataSource referenced by the dataSourceRef configuration attribute is used.

      <AD id="dataSource.target" type="String" default="(service.pid=${dataSourceRef})" ibm:final="true" name="internal" description="internal"/>


Parent topic: Develop a Liberty feature