title: ServiceMix unable to find OSGI data source
body: <p>I've been diving into ServiceMix 5.4.0 and OSGi, and have run across a rather weird behavior with OpenJPA.</p>
  
  <p>I have a data source defined like so:</p>
  
  <pre><code>&lt;blueprint
          xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"&gt;
  
      &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt;
          &lt;property name="driverClassName" value="org.postgresql.Driver"/&gt;
          &lt;property name="url" value="jdbc:postgresql://localhost:5432/test"/&gt;
          &lt;property name="username" value="test"/&gt;
          &lt;property name="password" value="test"/&gt;
      &lt;/bean&gt;
  
      &lt;service interface="javax.sql.DataSource" ref="dataSource"&gt;
        &lt;service-properties&gt;
          &lt;entry key="osgi.jndi.service.name" value="jdbc/test"/&gt;
        &lt;/service-properties&gt;
      &lt;/service&gt;
  &lt;/blueprint&gt;
  </code></pre>
  
  <p>Using the jndi:names command, I can verify that the data source is visible:</p>
  
  <pre><code>karaf@root&gt; jndi:names
  JNDI Name            Class Name                                                  
  osgi:service/jndi    org.apache.karaf.jndi.internal.JndiServiceImpl              
  osgi:service/jdbc/test org.apache.commons.dbcp.BasicDataSource                     
  karaf@root&gt; 
  </code></pre>
  
  <p>My persistence.xml:</p>
  
  <pre><code>&lt;persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"&gt;
  
      &lt;persistence-unit name="test" transaction-type="JTA"&gt;               
          &lt;jta-data-source&gt;osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/test)&lt;/jta-data-source&gt;
  
          &lt;class&gt;com.example.persistence.security.User&lt;/class&gt;
  
          &lt;exclude-unlisted-classes&gt;true&lt;/exclude-unlisted-classes&gt;
  
          &lt;properties&gt;
              &lt;property name="openjpa.jdbc.DBDictionary" value="postgres"/&gt;                       
              &lt;property name="openjpa.Log" value="slf4j"/&gt;
          &lt;/properties&gt;
      &lt;/persistence-unit&gt;
  &lt;/persistence&gt;
  </code></pre>
  
  <p>I then inject the persistence unit into a DAO class via Blueprint:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;blueprint  default-activation="eager" 
              xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
              xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0"
              xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"&gt;
  
      &lt;bean id="securityDAO" class="com.example.security.dao.SecurityDAOImpl" init-method="init"&gt;
          &lt;tx:transaction method="*" value="Required" /&gt;
          &lt;jpa:context property="entityManager" unitname="test" /&gt;
      &lt;/bean&gt;
  
      &lt;service ref="securityDAO" interface="com.example.security.dao.SecurityDAO"&gt;
      &lt;/service&gt;
  
  
  &lt;/blueprint&gt;
  </code></pre>
  
  <p>The persistence unit is successfully injected, which I verify in the init-method of the DAO:</p>
  
  <pre><code>public void init() {
      if (em==null) {
          log.error("Entity manager not found. Check JPA configuration.");
          throw new RuntimeException("No EntityManager found");
      }
  
      log.info("Started SecurityDAO");
  }
  </code></pre>
  
  <p>After all my diligent work, ServiceMix rewards me with the following cryptic exception when I call my DAO's method from another bean:</p>
  
  <pre><code>....
  public void setSecurityDAO (SecurityDAO dao) {
      this.dao = dao;
  }
  
  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
      String userName = req.getParameter("userName");
      String password = req.getParameter("password");
  
      // Invocation of injected DAO results in exception
      User u = dao.authenticateUser(userName, password);          
  </code></pre>
  
  <p>This results in the following:</p>
  
  <pre><code>Caused by: java.lang.RuntimeException: The DataSource osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/test) required by bundle persistence/0.0.1.SNAPSHOT could not be found.
      at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:87)
      at org.apache.aries.jpa.container.unit.impl.DelayedLookupDataSource.getConnection(DelayedLookupDataSource.java:36)
      at org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:116)
      at org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:93)
      at org.apache.openjpa.jdbc.schema.DataSourceFactory.installDBDictionary(DataSourceFactory.java:233)
      ... 54 more
  Caused by: javax.naming.NoInitialContextException: Unable to find the InitialContextFactory org.eclipse.jetty.jndi.InitialContextFactory.
      at org.apache.aries.jndi.ContextHelper.getInitialContext(ContextHelper.java:148)
      at org.apache.aries.jndi.OSGiInitialContextFactoryBuilder.getInitialContext(OSGiInitialContextFactoryBuilder.java:49)
      at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
      at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
      at javax.naming.InitialContext.init(InitialContext.java:244)
      at javax.naming.InitialContext.&lt;init&gt;(InitialContext.java:216)
      at org.apache.aries.jpa.container.unit.impl.JndiDataSource.getDs(JndiDataSource.java:64)
      ... 58 more
  </code></pre>
  
  <p>Somehow the OSGi-exported data source is not finding its way into the persistence bundle.  The strange part is that when I added the following code to the init-method to see if I could execute a test query, not only does OpenJPA not throw an exception in the init method, the invocation of the DAO that was triggering the exception now works as well:</p>
  
  <pre><code>public void init() {
      if (em==null) {
          log.error("Entity manager not found. Check JPA configuration.");
          throw new RuntimeException("No EntityManager found");
      }
  
      try {
          Query q = em.createNativeQuery("SELECT 1=1");           
          q.getFirstResult();         
      } catch (Exception ex) {
          log.error("Unable to execute test query against database", ex);
          throw new RuntimeException(ex);
      }
  
      log.info("Started SecurityDAO");
  }
  </code></pre>
  
  <p>So, to summarize:  If I call a method from a different bundle than my DAO, OpenJPA throws an exception indicating that it can't find the InitialNamingContext, and does not show any indication in the log that it has started.  If I execute a query inside my DAO before an external component calls into it, somehow OpenJPA is able to find the InitialNamingContext, OpenJPA shows up in the log, and subsequent invocations from outside the DAO bundle begin to work. </p>
  
  <p>Obviously, I'm missing something basic here. Any help or thoughtful explanation of what's breaking, or what I'm doing wrong, will be greatly appreciated.</p>
  
  <p>EDIT:</p>
  
  <p>I hadn't noticed last night, but when I added in the test query, the following lines appear in the log. They are absent when I comment out that  query:</p>
  
  <pre><code>... | Runtime | 220 - org.apache.openjpa - 2.3.0 | Starting OpenJPA 2.3.0
  ... | JDBC    | 220 - org.apache.openjpa - 2.3.0 | Using dictionary class "org.apache.openjpa.jdbc.sql.PostgresDictionary".
  ... | JDBC    | 220 - org.apache.openjpa - 2.3.0 | Connected to PostgreSQL version 9.9 using JDBC driver PostgreSQL Native Driver version PostgreSQL 9.3 JDBC4.1 (build 1102).
  </code></pre>
  
  <p>EDIT 2:</p>
  
  <p>Tried it on plain vanilla Karaf 3.0.3, and got the same error.  As a workaround, I created a separate bean in the bundle that executes the above-mentioned test query.  Apparently, as long as a single bean in the bundle makes a call to OpenJPA before a bean outside the bundle tries to make a call, OpenJPA will be correctly initialized.</p>
  
  <p>Since this is mentioned nowhere I can see in the OpenJPA/ServiceMix docs, I can only presume that I'm doing something wrong elsewhere in my configuration.</p>
  
  <p>EDIT 3:</p>
  
  <p>Per John Forth, here is the MANIFEST.MF</p>
  
  <pre><code>Manifest-Version: 1.0
  Bnd-LastModified: 1430533396366
  Build-Jdk: 1.8.0_45
  Built-By: somedude
  Bundle-Blueprint: OSGI-INF/blueprint/blueprint.xml
  Bundle-Description: Database access layer for Peer Review product
  Bundle-ManifestVersion: 2
  Bundle-Name: Example :: Persistence
  Bundle-SymbolicName: persistence-jpa
  Bundle-Version: 0.0.1.SNAPSHOT
  Created-By: Apache Maven Bundle Plugin
  Export-Package: com.example.persistence.security;version="0.0.1.SNAPSHOT",co
   m.example.security.dao;version="0.0.1.SNAPSHOT";uses:="com.example.persistence.
   security,javax.persistence"
  Export-Service: com.example.security.dao.SecurityDAO
  Import-Package: javax.persistence;version="[1.1,2)",org.osgi.service.blu
   eprint;version="[1.0.0,2.0.0)",org.slf4j;version="[1.7,2)"
  Meta-Persistence: META-INF/persistence.xml
  Require-Capability: osgi.ee;filter:="(&amp;(osgi.ee=JavaSE)(version=1.7))"
  Tool: Bnd-2.3.0.201405100607
  </code></pre>
  
  <p>And, since it may be related, the pom.xml of the JPA bundle:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;parent&gt;
          &lt;artifactId&gt;example&lt;/artifactId&gt;
          &lt;groupId&gt;com.example&lt;/groupId&gt;
          &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
      &lt;/parent&gt;
  
      &lt;artifactId&gt;persistence-jpa&lt;/artifactId&gt;
      &lt;packaging&gt;bundle&lt;/packaging&gt;
  
      &lt;name&gt;Example :: Persistence&lt;/name&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.apache.geronimo.specs&lt;/groupId&gt;
              &lt;artifactId&gt;geronimo-jpa_2.0_spec&lt;/artifactId&gt;
              &lt;version&gt;1.1&lt;/version&gt;
          &lt;/dependency&gt;
  
          &lt;dependency&gt;
              &lt;groupId&gt;org.slf4j&lt;/groupId&gt;
              &lt;artifactId&gt;slf4j-api&lt;/artifactId&gt;
              &lt;version&gt;1.7.7&lt;/version&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                  &lt;version&gt;3.3&lt;/version&gt;
                  &lt;configuration&gt;
                      &lt;source&gt;1.7&lt;/source&gt;
                      &lt;target&gt;1.7&lt;/target&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
  
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
                  &lt;artifactId&gt;maven-bundle-plugin&lt;/artifactId&gt;
                  &lt;version&gt;2.5.3&lt;/version&gt;
                  &lt;extensions&gt;true&lt;/extensions&gt;
                  &lt;configuration&gt;
                      &lt;instructions&gt;
                          &lt;Meta-Persistence&gt;META-INF/persistence.xml&lt;/Meta-Persistence&gt;
                          &lt;Bundle-SymbolicName&gt;${project.artifactId}&lt;/Bundle-SymbolicName&gt;
                          &lt;Bundle-Version&gt;${project.version}&lt;/Bundle-Version&gt;                     
                          &lt;Import-Package&gt;*&lt;/Import-Package&gt;
                          &lt;Export-Package&gt;com.example.persistence*,com.example.security.*;version=${project.version}&lt;/Export-Package&gt;
                      &lt;/instructions&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
          &lt;/plugins&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>