Aries JPA EntityManager 服务未针对 WebLogic 数据源启动

Posted

技术标签:

【中文标题】Aries JPA EntityManager 服务未针对 WebLogic 数据源启动【英文标题】:Aries JPA EntityManager services not starting for WebLogic data source 【发布时间】:2019-09-22 09:33:53 【问题描述】:

我正在尝试让 OSGi 持久性捆绑包在 WebLogic 的内置 Felix 框架上运行。根据the WebLogic OSGi documentation,我的WebLogic 数据源test-ds 似乎可以作为OSGi 中的服务使用:

Service 59 - [weblogic.jdbc.common.internal.RemoteDataSource, javax.sql.DataSource, javax.sql.CommonDataSource, java.sql.Wrapper, weblogic.jdbc.extensions.WLDataSource, java.rmi.Remote, weblogic.jdbc.common.internal.DataSourceMetaData, weblogic.common.resourcepool.ObjectLifeCycle, weblogic.jndi.CrossPartitionAware] (pid: n/a)
  from Bundle 0 - System Bundle (org.apache.felix.framework), version 5.6.0
    Name: test-ds
    service.bundleid: 0
    service.scope: singleton

我使用以下实体类创建了持久性捆绑包com.test.persistence-bundle

@Entity
public class TestEntity 

    @Id
    private Integer id;

    public Integer getId() 
        return id;
    

    public void setId(Integer id) 
        this.id = id;
    

...和persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2" xmlns="http://java.sun.com/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_2.xsd">
    <persistence-unit name="test-pu" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>osgi:service/test-ds</jta-data-source>
        <non-jta-data-source>osgi:service/test-ds</non-jta-data-source>
        <class>test.model.TestEntity</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle12cDialect"/>
        </properties>
    </persistence-unit>
</persistence>

...和清单:

Manifest-Version: 1.0
Bnd-LastModified: 1556912147017
Build-Jdk: 1.8.0_171
Built-By: roadkill
Bundle-ManifestVersion: 2
Bundle-Name: test-persistence-bundle
Bundle-SymbolicName: com.test.persistence-bundle
Bundle-Version: 1.0.0.SNAPSHOT
Created-By: Apache Maven Bundle Plugin
DynamicImport-Package: org.hibernate.proxy,javassist.util.proxy
Export-Package: test.model;uses:="javax.persistence";version="1.0.0"
Import-Package: javax.persistence;version="[2.2,3)",org.hibernate.proxy;
 resolution:=optional,javassist.util.proxy;resolution:=optional
Meta-Persistence: META-INF/persistence.xml
Provide-Capability: osgi.service;effective:=active;objectClass="javax.pe
 rsistence.EntityManager";osgi.unit.name=test-pu,osgi.service;effective:
 =active;objectClass="javax.persistence.EntityManagerFactory";osgi.unit.
 name=test-pu,osgi.service;effective:=active;objectClass="org.apache.ari
 es.jpa.template.JpaTemplate";osgi.unit.name=test-pu,osgi.service;effect
 ive:=active;objectClass="org.apache.aries.jpa.supplier.EmSupplier";osgi
 .unit.name=test-pu
Require-Capability: osgi.extender;osgi.extender="aries.jpa",osgi.service
 ;effective:=active;objectClass="javax.persistence.spi.PersistenceProvid
 er";javax.persistence.provider="org.hibernate.jpa.HibernatePersistenceP
 rovider",osgi.service;effective:=active;objectClass="javax.transaction.
 TransactionManager",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-4.2.0.201903051501

我还创建了一个客户端包 com.test.service-impl,它从另一个包中实现了 TestService

@Component(service = TestService.class)
public class TestServiceImpl implements TestService 

    @PersistenceContext(unitName = "test-pu")
    EntityManager em;

    @Override
    public void foo() 
        System.out.println(em);
    

EntityManager 实例应通过服务实现的蓝图注入:

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">

    <jpa:enable />
    <tx:enable />

    <bean id="testService" class="test.service.impl.TestServiceImpl"/>
    <service ref="testService" interface="test.service.TestService"/>
</blueprint>

但是,em 始终为空。即使所有捆绑包都处于活动状态,EntityManager 服务似乎也从未启动。更新com.test.service-impl时收到以下消息:

13:20:36.380 [Blueprint Extender: 1] INFO org.apache.aries.blueprint.container.BlueprintContainerImpl - Blueprint bundle com.test.service-impl/1.0.0.SNAPSHOT is waiting for dependencies [(&(osgi.unit.name=test-pu)(objectClass=javax.persistence.EntityManager))]
13:20:36.380 [Blueprint Extender: 1] DEBUG org.apache.aries.blueprint.container.BlueprintEventDispatcher - Sending blueprint container event BlueprintEvent[type=GRACE_PERIOD, dependencies=[(&(osgi.unit.name=test-pu)(objectClass=javax.persistence.EntityManager))]] for bundle com.test.service-impl/1.0.0.SNAPSHOT

我正在使用 Aries JPA 将所有内容连接在一起,并使用 Hibernate 作为持久性提供程序。我还安装了 Aries Blueprint 和 Aries Transaction 以及所有必需的依赖项。

以下是我捆绑列表中的相关捆绑包:

com.test.persistence-api (1.0.0.SNAPSHOT) "test-persistence-api" [active, 23] 
com.test.persistence-bundle (1.0.0.SNAPSHOT) "test-persistence-bundle" [active, 25] 
com.test.service-impl (1.0.0.SNAPSHOT) "test-service-impl" [active, 21] 
javax.persistence-api (2.2) "Java(TM) Persistence API jar" [active, 45] 
javax.transaction-api (1.2) "javax.transaction API" [active, 10] 
javax.transaction-api (1.3) "javax.transaction API" [active, 18] 
org.apache.aries.blueprint.annotation.impl (1.0.1) "Apache Aries Blueprint Annotation Impl" [active, 32] 
org.apache.aries.blueprint.core (1.10.2) "Apache Aries Blueprint Core" [active, 19] 
org.apache.aries.jpa.api (2.7.2) "Apache Aries JPA Container API" [active, 44] 
org.apache.aries.jpa.blueprint (2.7.2) "Apache Aries JPA blueprint" [active, 22] 
org.apache.aries.jpa.container (2.7.2) "Apache Aries JPA container" [active, 64] 
org.apache.aries.jpa.javax.persistence_2.1 (2.7.2) "Apache Aries JPA Specification 2.1 API" [active, 67] 
org.apache.aries.jpa.support (2.7.2) "Apache Aries JPA support" [active, 66] 
org.apache.aries.proxy (1.1.4) "Apache Aries Proxy Service" [active, 70] 
org.apache.aries.transaction.blueprint (2.2.0) "Apache Aries Transaction Blueprint" [active, 52] 
org.apache.aries.transaction.manager (1.3.3) "Apache Aries Transaction Manager" [active, 34] 
org.apache.aries.util (1.1.3) "Apache Aries Util" [active, 30] 
org.hibernate.common.hibernate-commons-annotations (5.1.0.Final) "hibernate-commons-annotations" [active, 56] 
org.hibernate.orm.core (5.3.10.Final) "hibernate-core" [active, 31] 
org.hibernate.orm.core (5.4.2.Final) "hibernate-core" [active, 29] 
org.hibernate.orm.osgi (5.4.2.Final) "hibernate-osgi" [active, 59] 
org.osgi.service.blueprint (1.0.2.201505202024) "org.osgi:org.osgi.service.blueprint" [active, 27] 
org.osgi.service.cm (1.5.0.201505202024) "org.osgi:org.osgi.service.cm" [active, 6] 
org.osgi.service.coordinator (1.0.2.201505202024) "org.osgi:org.osgi.service.coordinator" [active, 73] 
org.osgi.service.jdbc (1.0.0.201505202023) "org.osgi:org.osgi.service.jdbc" [active, 37] 
org.osgi.util.function (1.1.0.201802012106) "org.osgi:org.osgi.util.function" [active, 65] 
org.osgi.util.promise (1.1.1.201810101357) "org.osgi:org.osgi.util.promise" [active, 17] 

有什么想法吗?

提前致谢!

【问题讨论】:

【参考方案1】:

TL;DR: 事实证明,这是由于 WebLogic 附带的 Felix 版本中的错误造成的。我只需将\wlserver\server\lib\org.apache.felix.org.apache.felix.main.jar\wlserver\server\lib\osgi.jar 分别替换为最新版本的felix-main 和osgi-core 即可升级框架。


在试图找出问题的根源时,我最终下载并手动阅读了 Karaf 的 jpatransactionhibernate 功能,以确保所有正确的包都已安装并以正确的方式启动命令。 WebLogic allows you to specify start levels by placing bundles inside of subdirectories within the osgi-lib folder。我不确定这从长远来看有多大帮助,但它让我确信事情是经过验证的。

这是我从 Karaf 功能中收集的包含版本和启动级别的捆绑包列表(未显示:日志记录/控制台/shell 内容):

START LEVEL 100
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (6.0.3)
[   1] [Active     ] [   10] Apache Felix Configuration Admin Service (1.9.14)
[   2] [Active     ] [   11] Apache Felix File Install (3.6.4)
[   3] [Active     ] [   20] org.objectweb.asm (7.1.0)
[   4] [Active     ] [   20] org.objectweb.asm.tree.analysis (7.1.0)
[   5] [Active     ] [   20] org.objectweb.asm.commons (7.1.0)
[   6] [Active     ] [   20] org.objectweb.asm.tree (7.1.0)
[   7] [Active     ] [   20] org.objectweb.asm.util (7.1.0)
[   8] [Active     ] [   20] Apache Aries Blueprint API (1.0.1)
[   9] [Active     ] [   20] Apache Aries Blueprint CM (1.3.1)
[  10] [Active     ] [   20] Apache Aries Blueprint Core (1.10.2)
[  11] [Resolved   ] [   20] Apache Aries Blueprint Core Compatiblity Fragment Bundle (1.0.0)
[  12] [Active     ] [   20] Apache Aries Proxy Service (1.1.4)
[  13] [Active     ] [   20] Apache Aries Util (1.1.3)
[  14] [Active     ] [   30] jaxb-api (2.3.1)
[  15] [Active     ] [   30] Apache Aries JMX API (1.1.5)
[  16] [Active     ] [   30] Apache Aries JMX Blueprint API (1.2.0)
[  17] [Active     ] [   30] Apache Aries JMX Blueprint Core (1.2.0)
[  18] [Active     ] [   30] Apache Aries JMX Core (1.1.8)
[  19] [Active     ] [   30] Apache Aries Whiteboard support for JMX DynamicMBean services (1.2.0)
[  20] [Active     ] [   30] Apache Aries JPA Container API (2.7.2)
[  21] [Active     ] [   30] Apache Aries JPA blueprint (2.7.2)
[  22] [Active     ] [   30] Apache Aries JPA container (2.7.2)
[  23] [Active     ] [   30] Apache Aries JPA support (2.7.2)
[  24] [Active     ] [   30] Apache ServiceMix :: Specs :: Activation API 1.4 (2.9.0)
[  25] [Active     ] [    5] Apache Felix EventAdmin (1.5.0)
[  26] [Active     ] [    5] Apache Felix Metatype Service (1.2.2)
[  27] [Active     ] [    8] jansi (1.17.1)
[  31] [Active     ] [   80] Byte Buddy (without dependencies) (1.9.10)
[  32] [Active     ] [   80] CDI APIs (1.2.0)
[  33] [Active     ] [   80] ClassMate (1.3.4)
[  34] [Active     ] [   80] org_dom4j_dom4j_2.1.1_dom4j-2.1.1.jar (0)
[  36] [Active     ] [   80] geronimo-jta_1.1_spec (1.1.1)
[  37] [Active     ] [   80] hibernate-commons-annotations (5.1.0.Final)
[  38] [Active     ] [   80] hibernate-core (5.4.2.Final)
[  39] [Active     ] [   80] hibernate-osgi (5.4.2.Final)
[  40] [Active     ] [   80] Java Annotation Indexer (2.0.5.Final)
[  41] [Active     ] [   80] Javassist (3.24.0.GA)
[  42] [Active     ] [   80] Expression Language 3.0 API (3.0.0)
[  43] [Active     ] [   80] javax.interceptor API (1.2)
[  44] [Active     ] [   80] Java(TM) Persistence API jar (2.2)
[  45] [Active     ] [   80] Apache Aries JPA Specification 2.1 API (2.7.2)
[  46] [Active     ] [   80] javax.transaction API (1.2)
[  47] [Active     ] [   80] JBoss Logging 3 (3.3.2.Final)
[  48] [Active     ] [   80] Java Transaction API (1.1.1.Final)
[  49] [Active     ] [   80] Apache Aries Transaction Blueprint (1.1.1)
[  50] [Active     ] [   80] Apache Aries Transaction Blueprint (2.2.0)
[  51] [Active     ] [   80] Apache ServiceMix :: Bundles :: javax.inject (1.0.0.2)
[  52] [Active     ] [   80] org.osgi:org.osgi.service.jdbc (1.0.0.201505202023)
[  53] [Active     ] [   80] pax-transx-tm-api (0.4.3)
[  54] [Active     ] [   80] pax-transx-tm-geronimo (0.4.3)
[  55] [Active     ] [    9] Apache Felix Coordinator Service (1.0.2)
[  61] [Active     ] [    1] Apache Felix Declarative Services (2.1.16)
[  65] [Active     ] [    1] org.osgi:org.osgi.util.function (1.1.0.201802012106)
[  66] [Active     ] [    1] org.osgi:org.osgi.util.promise (1.1.1.201810101357)

我还通过 WebLogic 控制台对 OSGi 框架配置本身进行了一些更改:

引导委托 - 这些主要是从 Karaf 配置中复制的,尽管绝对需要 sun.*com.sun.* 以避免来自 bytebuddy 的 ClassNotFoundExceptions:
com.sun.*, javax.transaction, javax.transaction.*, javax.xml.crypto, javax.xml.crypto.*, jdk.nashorn.*, sun.*, jdk.internal.reflect, jdk.internal.reflect.*
Init Properties - 同样,主要是从 Karaf 复制的:
felix.startlevel.bundle=80
org.apache.aries.blueprint.synchronous=true
org.apache.aries.proxy.weaving.disabled=org.objectweb.asm.*,org.slf4j.*,org.apache.log4j.*,javax.*,org.apache.xerces.*
org.apache.aries.proxy.weaving.enabled=none
org.osgi.framework.startlevel.beginning=100

最后,WebLogic 似乎将已发布 DataSource 服务的 name 属性设置为数据源本身的 JNDI 名称。因此,jta-data-source 的完整值应该类似于:

osgi:service/javax.sql.DataSource/(name=test-ds)

希望这会有所帮助。

【讨论】:

以上是关于Aries JPA EntityManager 服务未针对 WebLogic 数据源启动的主要内容,如果未能解决你的问题,请参考以下文章

Apache Aries 托管 JPA 支持哪些 JPA 提供程序?

何时将 EntityManager.find() 与 EntityManager.getReference() 与 JPA 一起使用

JPA 之 Hibernate EntityManager 使用指南

JPA EntityManager 返回没有 entityManager.clear 的陈旧值

如何从 Grails 服务 (JPA + GAE) 中访问 EntityManager

比较JPA的EntityManager接口与Hibernate的Session接口