【问题标题】:Unenhanced entities with dynamic runtime enhancement with OpenJPA in OSGI (Karaf)在 OSGI (Karaf) 中使用 OpenJPA 进行动态运行时增强的未增强实体
【发布时间】:2014-09-15 13:38:04
【问题描述】:

我们有三个 Karaf 功能,每个功能都包含三个自定义包(api、impl、web)。每个功能的“impl”包还包含该功能使用的实体。我们在 Karaf 3.0.1 中部署这些功能,并使用 Karaf 3.0.1 附带的 OpenJPA 2.3.0 作为我们的持久性提供程序。

我们对三个功能中的实体使用动态运行时增强。对于这两个功能,实体总是在部署时得到增强并且它们工作正常。问题在于,对于第三个功能,Karaf 和 OpenJPA 偶尔会错过增强实体子集的功能,从而导致以下异常:

<openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "
<list-of-missed-unenhanced-classes>"
at org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses(ManagedClassSubclasser.java:115)
at org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:312)
at org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:236)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:212)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:155)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
...

我们知道openjpa.RuntimeUnenhancedClasses 选项,但不想使用它,因为它有已知的限制,并且在 OpenJPA 2.0.0 中默认禁用。

我们知道编译时增强并且我们正在成功使用它,但我们有理由尝试启用运行时增强。

我们目前的理解是,在 EntityManagerFactory 创建时,OpenJPA 通过 PersistenceUnitInfo 回调向 Aries JPA 注册,这是一个供 Karaf 使用的 ClassTransformer。这个 ClassTransformer 确实用于前两个特征的所有实体,但仅用于第三个特征的实体子集。

进一步调查,我们尝试记录 ClassTransformer 注册的时间和每个实体类的加载时间。我们注意到两个成功包和失败包之间的差异可能相关也可能不相关。对于后续的包,Aries JPA 功能会尝试在 ClassTransformer 注册之前加载每个实体类,而对于失败的模块则没有这样的尝试。

【问题讨论】:

  • 我认为进行运行时增强是一个糟糕的设计。在开发阶段可能没问题,但在生产阶段肯定不行。您应该使用 openjpa maven 插件进行编译时增强。
  • @AchimNierbeck 我们需要在使用 OpenJPA 的环境和使用 Hibernate 的环境中部署上述功能,这就是尝试使用 OpenJPA 进行运行时增强的原因。除了为每个环境提供单独的包之外,是否有针对这种情况的最佳实践?
  • 唯一的其他方法是将增强的类添加到一个片段包中,该片段包扩展了包含 DAO 类的主机包。这样,您可以为 Hibernate 和 OpenJPA 环境提供两个不同的片段包。

标签: osgi openjpa karaf


【解决方案1】:

这实际上是 Karaf 和 OpenJPA 之间的问题。

问题是 Karaf 中的类加载是多线程的,而 OpenJPA 类增强器不是线程安全的。因此,您基本上有多个类加载线程调用 OpenJPA 类增强器的单个非线程安全实例。

https://issues.apache.org/jira/browse/OPENJPA-2222

【讨论】:

    猜你喜欢
    • 2014-09-04
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    相关资源
    最近更新 更多