Recherche JNDI de composants blueprint

Si un bundle contient du XML Blueprint qui déclare un certain nombre de composants chacun avec un ID donné, ces composants peuvent être recherchés à l'aide de l'interface JNDI (Java™ Naming and Directory Interface).

Le code à utiliser se présente comme suit :
Object component = new InitialContext().lookup("blueprint:comp/componentId");
Ce mécanisme est utile dans deux contextes différents :
  • Vous pouvez déclarer et configurer n'importe quel nombre de composants d'un bundle d'application web (WAB) qui peuvent ensuite être recherchés à partir de servlets qui ne sont pas eux-mêmes gérés par blueprint.
  • Vous pouvez déclarer et configurer des sources de données dans un fichier XML blueprint et les référencer ensuite dans un fichier persistence.xml.

Déclaration et configuration des composants d'un bundle WAB

Un bundle WAB peut contenir un fichier XML blueprint. Cet élément peut être utilisé pour déclarer et configurer n'importe quel nombre de composants qui peuvent ensuite être recherchés à partir de servlets qui ne sont pas eux-mêmes gérés par blueprint. Une utilisation particulière de cette fonction est illustrée dans le modèle d'application de blogue OSGi, dans lequel le bundle Web contient le code de plan directeur suivant:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <reference id="blogService"
             interface="com.ibm.samples.websphere.osgi.blog.api.BloggingService"/>
</blueprint>
L'appel de méthode JNDIHelper.getBloggingService() inclut le fragment de code suivant :
  try {
    InitialContext ic = new InitialContext();
    return (BloggingService) ic.lookup("blueprint:comp/blogService");
  } catch (NamingException e) {
Ce code recherche une référence gérée par blueprint à un service OSGi. Cela est utile car les services gérés par blueprint sont amortis, comme indiqué dans la section 121.10.1 du document OSGi Service Platform Release 4 Version 4.2 Enterprise Specification. Si l'objet BloggingService n'est pas disponible lorsque le code d'application tente d'utiliser la référence, ce dernier patiente le temps que le service redevienne disponible.
Les versions précédentes de la méthode getBloggingService utilisaient une recherche au format suivant :
ic.lookup("osgi:service/com.ibm.samples.websphere.osgi.blog.api.BloggingService");
Cela n'est pas si utile, car le code de l'application peut recevoir unServiceUnavailableExceptionexception si le service n'est pas disponible lorsque le code d'application tente d'utiliser l'objet BloggingService . Par exemple, si l'objet BloggingService est temporairement indisponible car une mise à jour interne est en cours, l'utilisateur de l'application Web Blog peut obtenir unHTTP 500 (Internal Error)dans leur navigateur Web. Avec la nouvelle forme de recherche, les requêtes sur le web marquent un court délai d'attente (d'une seconde ou deux), le temps que la mise à jour se termine. Il est ainsi plus facile d'écrire une application web qui reste disponible en permanence, du point de vue de l'utilisateur, même si elle fait l'objet d'une mise à jour sur place.

Déclaration et configuration des sources de données

Les sources de données peuvent être déclarées et configurées dans un fichier XML blueprint et référencées ensuite dans un fichier persistence.xml. Par exemple, dans Apache Aries, le fichier org.apache.aries.jpa.container.itest.bundle/src/main/resources/OSGI-INF/blueprint/config.xml inclut le code suivant :

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">

  <bean id="nonjta" class="org.apache.derby.jdbc.EmbeddedDataSource">
    <property name="databaseName" value="memory:testDB"/> 
    <property name="createDatabase" value="create"/>
  </bean>

  <service interface="javax.sql.XADataSource">
    <service-properties>
      <entry key="transactional" value="true"/>
    </service-properties>
    <bean class="org.apache.derby.jdbc.EmbeddedXADataSource">
      <property name="databaseName" value="memory:testDB"/>
      <property name="createDatabase" value="create"/> 
    </bean>
  </service>

  <reference id="jta" availability="optional" interface="javax.sql.DataSource"
             filter="(transactional=true)"/>

</blueprint>
Le fichier org.apache.aries.jpa.container.itest.bundle/src/main/resources/META-INF/persistence.xml inclut le code correspondant suivant :
... 
  <persistence-unit name="bp-test-unit" transaction-type="JTA">
    <description>Test persistence unit for the JPA Container and Context iTests</description>
    <jta-data-source>blueprint:comp/jta</jta-data-source>
    <non-jta-data-source>blueprint:comp/nonjta</non-jta-data-source>
    <class>org.apache.aries.jpa.container.itest.entities.Car</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
      <!-- These properties are creating the database on the fly. -->
      <!-- We are using them to avoid the tests having to create a database  -->
      <property name=''eclipselink.ddl-generation'' value=''create-tables/>
    </properties>
  </persistence-unit>
</persistence>
Dans ce fragment de code, les éléments jta-data-source et non-jta-datasource sont configurés par le biais des références d'espace de nom blueprint:comp/.