1

我们有三个 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 注册之前加载每个实体类,而对于失败的模块,则没有这样的尝试。

4

1 回答 1

0

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

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

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

于 2014-09-22T13:44:46.487 回答