【问题标题】:OSGi with JPA: Service not starting although code seems ok带有 JPA 的 OSGi:尽管代码看起来不错,但服务没有启动
【发布时间】:2013-12-31 20:56:52
【问题描述】:

是的,我知道我应该使用 Declarative ServicesBlueprint,但是我正在尝试找出一个使用较低级别 API 的简单示例来感受 OSGi。

我只想知道代码有什么问题,为什么我根本无法启动服务!!??

我在这里使用了两种方法:一种使用ServiceTracker,另一种使用ServiceReference,我知道这两种方法不可靠但有人可以帮我解决此示例代码有效。非常感谢!

这是我的代码:

我有一个简单的Accounts实体类:

package model.account;

import javax.persistence.*;

@Entity
public class Account {

@Id @GeneratedValue
int id;
double balance;

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public double getBalance() {
    return balance;
}

public void setBalance(double balance) {
    this.balance = balance;
}

@Override
public String toString() {
    return "Account{" + "id=" + id + ", balance=" + balance + '}';
}

}

AccountClient 为:

package client;

public class AccountClient {

public void run(EntityManagerFactory emf) {
    EntityManager em = emf.createEntityManager();
    em.getTransaction().begin();

    Account a = new Account();
    a.setBalance(100.0);
    em.persist(a);

    em.getTransaction().commit();

    TypedQuery<Account> q = em.createQuery("SELECT a FROM Account a", Account.class);
    List<Account> results = q.getResultList();
    System.out.println("\n*** Account Report ***");
    for (Account acct : results) {
        System.out.println("Account: " + acct);
    }
    em.close();
}
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
 <persistence-unit name="Accounts" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>model.account.Account</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="eclipselink.target-database" value="Derby"/>
        <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/accountDB;create=true"/>
        <property name="javax.persistence.jdbc.user" value="app"/>
        <property name="javax.persistence.jdbc.password" value="app"/>

        <property name="eclipselink.logging.level" value="FINE"/>
        <property name="eclipselink.logging.timestamp" value="false"/>
        <property name="eclipselink.logging.thread" value="false"/>
        <property name="eclipselink.logging.exceptions" value="true"/>
        <property name="eclipselink.orm.throw.exceptions" value="true"/>
        <property name="eclipselink.jdbc.read-connections.min" value="1"/>
        <property name="eclipselink.jdbc.write-connections.min" value="1"/>                        
        <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/>
        <property name="eclipselink.weaving" value="true"/>

    </properties>

最后是带有ServiceReferenceActivator

package client;

public class Activator implements BundleActivator {

BundleContext ctx;
ServiceReference[] serviceReferences;
EntityManagerFactory emf;

public void start(BundleContext context) throws Exception {
    ctx = context;
    System.out.println("Gemini JPA Basic Sample started");

    try{
        serviceReferences = context.getServiceReferences(
                      EntityManagerFactory.class.getName(),
                      "(osgi.unit.name=Accounts)");
    }catch(Exception e){
        e.printStackTrace();
    }
    if(serviceReferences != null){
        emf = (EntityManagerFactory)context.getService(serviceReferences[0]);
    }
    if(emf != null){
        new AccountClient().run(emf);
    }
}

public void stop(BundleContext context) throws Exception {
    if(serviceReferences != null){
        context.ungetService(serviceReferences[0]);
    }
    System.out.println("Gemini JPA Basic Sample stopped");
}
}

ServiceTracker

package client;
public class Activator implements BundleActivator, ServiceTrackerCustomizer {

BundleContext ctx;
ServiceTracker emfTracker;

public void start(BundleContext context) throws Exception {
    ctx = context;
    System.out.println("Gemini JPA Basic Sample started");

    /* We are in the same bundle as the persistence unit so the services should be 
     * available when we start up (if nothing bad happened) and the tracker is really 
     * just saving us the lookup, but this is the idea of how you would listen for a 
     * persistence unit coming from another bundle.
     */
    emfTracker = new ServiceTracker(ctx, EntityManagerFactory.class.getName(), this);
    emfTracker.open();
    System.out.println("Started finally!!");
}

public void stop(BundleContext context) throws Exception {
    emfTracker.close();
    System.out.println("Gemini JPA Basic Sample stopped");
}

/*========================*/
/* ServiceTracker methods */
/*========================*/

public Object addingService(ServiceReference ref) {
    System.out.println("reached in add");
    Bundle b = ref.getBundle();
    System.out.println("Got ref");
    Object service = b.getBundleContext().getService(ref);
    System.out.println("service");
    String unitName = (String)ref.getProperty(EntityManagerFactoryBuilder.JPA_UNIT_NAME);
    System.out.println("search");

    if (unitName.equals("Accounts")) {
        new AccountClient().run((EntityManagerFactory)service);
        System.out.println("Found and started");
    }
    return service;
}
public void modifiedService(ServiceReference ref, Object service) {}
public void removedService(ServiceReference ref, Object service) {}    
}

【问题讨论】:

    标签: java jpa osgi


    【解决方案1】:

    您的清单是否包含 JPA Documentation 中描述的 Meta-Persistence 标头和所有依赖项? 所有捆绑包都启动了吗?

    也许这有助于Installing and Starting Gemini JPA Applications

    【讨论】:

    • 是的,我也是这样做的。我尝试了另一种方法,它将实例化 EntityManagerFactory 的对象并调用 Persistence.createEntityManagerFactory("Accounts");它给出了“找不到名为 Accounts 的持久性单元”的错误。你对此有什么意见吗?
    • Persistence.createEntityManagerFactory("Accounts") 进行类路径扫描,在 OSGi 环境中不起作用。
    • Gemini JPA 使用扩展器模式来定位您的 persistence.xml 文件。因此,JPA 扩展程序将等待清单中包含 Meta-Persistence 标头的包。如果找到一个,它将使用此捆绑包上下文来查找此捆绑包中的 persistence.xml 文件。然后 Gemini JPA 读取 persistence.xml 文件,并使用持久性 bunlde 上下文加载实体。然后将配置的 EntityManagerFactory 作为服务添加到上下文中。如果这不起作用,那么可能您的持久性捆绑包或 JPA 扩展器未启动,元持久性丢失...
    • 我检查了 MANIFEST.MF 仅在项目构建时创建。但是执行 maven clean 时它不存在。是 pom.xml 正在生成清单吗?如果是这样,我该如何更新它以使其包含 META 持久性?我通过确保所有依赖项都已启动但未创建 EMF 来尝试代码。服务不退还。现在如何更新构建以使清单包含元持久性。请帮忙。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 2019-11-26
    • 1970-01-01
    相关资源
    最近更新 更多