我们有三个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注册之前加载每个实体类,而对于失败的模块则没有这样的尝试。
答案 0 :(得分:0)
这实际上是Karaf和OpenJPA之间的一个问题。
问题是Karaf中的类加载是多线程的,而OpenJPA类增强器不是线程安全的。所以你基本上有多个类加载线程调用OpenJPA类增强器的单个非线程安全实例。