2013-11-22 1 views
2

Я работал над демонстрационным примером, где JPA будет использоваться с OSGi.JPA с примером OSGi, возвращающим null в serviceReference

Дело в том, что я могу запустить/остановить обслуживание после комплектации, однако я не могу получить serviceReference. В связи с этим моя реализация JPA не выполняется.

Ниже приведен код:

Activator.java

package manning.osgi.jpa; 

import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 

import org.osgi.framework.BundleActivator; 
import org.osgi.framework.BundleContext; 
import org.osgi.framework.ServiceReference; 

public class Activator implements BundleActivator { 

public void start(BundleContext context) throws Exception { 
    LoginEvent loginEvent = new LoginEvent(); 

    // Set login event... 
    loginEvent.setUserid("alex"); 

    try { 
     ServiceReference [] serviceReferences = 
       context.getServiceReferences(
         EntityManagerFactory.class.toString(), 
         "(osgi.unit.name=LoginEvent)"); 

     System.out.println("Service References Created"); 

     if (serviceReferences != null) { 
      EntityManagerFactory emf = 
       (EntityManagerFactory) context.getService(serviceReferences[0]); 

      EntityManager em = emf.createEntityManager(); 

      persistLoginEvent(em, loginEvent); 
      System.out.println("Transaction started"); 

      loginEvent = retrieveLoginEvent(em, loginEvent.getId()); 
      System.out.println("Transaction completed"); 

      em.close(); 
      emf.close(); 
     } 

    } catch (Exception e) { 
     System.out.println("Exception"+e.getMessage()); 
    } 

} 

private void persistLoginEvent(EntityManager em, LoginEvent loginEvent) { 
    em.getTransaction().begin(); 

    em.persist(loginEvent); 

    em.getTransaction().commit(); 
} 

private LoginEvent retrieveLoginEvent(EntityManager em, int id) { 
    em.getTransaction().begin(); 

    LoginEvent loginEvent = em.find(LoginEvent.class, id); 
    loginEvent.getUserid(); 
    loginEvent.getId(); 
    loginEvent.getTimestamp(); 

    em.getTransaction().commit(); 

    return loginEvent; 
} 

public void stop(BundleContext context) throws Exception { 
} 

}

LoginEvent.java

package manning.osgi.jpa; 

import javax.persistence.*; 

@Entity 
public class LoginEvent { 

@Id 
@GeneratedValue 
private int id; 
private String userid; 
private long timestamp; 

public int getId() { 
    System.out.println("\nID: "+this.id); 
    return this.id; 
} 
public String getUserid() { 
    System.out.println("\nUser ID: "+this.userid); 
    return this.userid;  
} 
public void setUserid(String userid) { 
    this.userid = userid; 
} 
public long getTimestamp() { 
    System.out.println("\nTime Stamp: "+this.timestamp); 
    return this.timestamp; 
} 
public void setTimestamp(long timestamp) { 
    this.timestamp = timestamp; 
} 
} 

persistence.xml

<persistence version="1.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_1_0.xsd"> 
<persistence-unit name="LoginEvent"> 
    <class>manning.osgi.jpa.LoginEvent</class>   
     <properties> 
     <property name="javax.persistence.jdbc.driver" 
      value="org.apache.derby.jdbc.EmbeddedDriver"/> 
     <property name="javax.persistence.jdbc.url" 
      value="jdbc:derby:derbyDB;create=true"/> 
    </properties> 
</persistence-unit> 
</persistence> 

MANIFEST.MF

Manifest-Version: 1.0 
Bundle-ManifestVersion: 2 
Bundle-Name: OsgiDemo 
Bundle-SymbolicName: manning.osgi.jpa 
Bundle-Version: 1.0.0.qualifier 
Bundle-Activator: manning.osgi.jpa.Activator 
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 
Import-Package: javax.persistence, 
org.osgi.framework;version="1.3.0" 
Bundle-ActivationPolicy: lazy 
Require-Bundle: javax.persistence;bundle-version="2.1.0" 

Код компиляции, но как serviceReference равно нулю, я не могу прогрессировать. Я перепроверял имя persistence-unit и его правильно.

Может ли кто-нибудь помочь мне узнать, чего я здесь не вижу. Спасибо.

ответ

3

В вашем Активаторе вы не можете быть уверены, что нужный ServiceReference уже доступен. Может случиться так, что ваш пакет начинается до того, который регистрирует эту службу. Также возможно, что другой пакет не запускается, поэтому служба не будет зарегистрирована.

В случае, если вы хотите закодировать много, то вы можете создать ServiceTracker внутри вашей функции запуска и сделать то же самое в addingService функции трекера, как вы делали в функции запуска на BundleActivator.

Если вы хотите работать меньше, используйте Declarative Services (многие учебные пособия доступны в сети). Там вы можете определить, что ваш компонент не должен запускаться до тех пор, пока не появится доступная служба OSGi.

Btw .: Вы должны позвонить unGetService, если вы использовали getService(serviceReference) функцию.

+0

Прошел почти год с тех пор, как я сделал OSGi. Забыл о 'ServiceTracker'. Думаю, это может быть проблемой. И да, +1 для DS. –

+0

Да, вы можете быть прав насчет сервисов, которые не начинаются до регистрации. Однако я никак не могу это исправить. Я узнал, что http://en.wikipedia.org/wiki/OSGi_Specification_Implementations говорит, что JPA реализуется в Овне или Близнецах. Я использовал Eclipse & Equinox для моего примера JPA. – Amrit

+0

Овен и Близнецы не реализуют JPA. Они реализуют расширитель, который собирает пакеты с persistence.xml и создает новые сервисы OSTG EntityManagerFactory на основе механизма JPA. Более конкретно, они реализуют главу «Java Persistence API» спецификации предприятия OSGi. Если у вас есть все пакеты арий, которые вам нужны, вы должны увидеть сервис EntityManagerFactory. Как вы используете эту услугу, это не JPA, а больше вещей OSGi. Например. Yoou может ввести его в ваш класс с DS или Blueprint. –

Смежные вопросы