OpenJPA是否适用于Glassfish? [英] Does OpenJPA work well with Glassfish?

查看:137
本文介绍了OpenJPA是否适用于Glassfish?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人成功地使用OpenJPA和Glassfish吗?



我试图用Glassfish 3.1开源使用OpenJPA 2.1。我按照说明将这两者整合在一起 - > http: //weblogs.java.net/blog/ss141213/archive/2006/07/using_openjpa_a.html



我在Eclipse Indigo中有一个非常简单的EJB项目使用以下内容:




  • com.rares.test.Person - @Entity

  • com.rares .test.PersonManager - 界面

  • com.rares.test.PersonDao - @Stateless



但是,当我尝试部署我得到一个ClassNotFoundException对我的Person @Entity。这个投诉似乎是Person Person中的Person方法,它正在我的PersonDao中实现(见下面的所有代码)。



我没有指定一个提供者在我的persistence.xml和项目工作正常(能够持续一个Person @Entity到一个PERSON表在MySql中)。如果我没有指定提供程序,我想我正在使用EclipseLink(如果我错了,请更正我)。这导致我相信我没有正确配置OpenJPA与Glassfish。



堆栈跟踪



 导致:java.lang.IllegalArgumentException:java.lang.ClassNotFoundException:com.rares.test.Person 
at serp.util.Strings.toClass(Strings.java:164)
at serp.util.Strings.toClass(Strings.java:108)
at serp.bytecode.BCClass.getType(BCClass.java:566)
在org.apache.openjpa.enhance.PCEnhancer 。< init>(PCEnhancer.java:283)
在org.apache.openjpa.enhance.PCEnhancer。< init>(PCEnhancer.java:254)
在org.apache.openjpa.enhance .PCClassFileTransformer.transform0(PCClassFileTransformer.java:144)
在org.apache.openjpa.enhance.PCClassFileTransformer.transform(PCClassFileTransformer.java:124)
在org.apache.openjpa.persistence.PersistenceProviderImpl $ ClassTransformerImpl .transform(PersistenceProviderImpl.java:294)
在org.glassfish.persistence.jpa.ServerProviderContainerCon tractInfo $ 1.transform(ServerProviderContainerContractInfo.java:98)
在com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader.java:742)
在java.lang.ClassLoader.loadClass(ClassLoader.java :306)
在java.lang.ClassLoader.loadClass(ClassLoader.java:247)
在java.lang.Class.getDeclaredMethods0(本机方法)
在java.lang.Class.privateGetDeclaredMethods (Class.java:2427)
在java.lang.Class.privateGetPublicMethods(Class.java:2547)
在java.lang.Class.getMethods(Class.java:1410)
at com.sun.enterprise.deployment.EjbDescriptor.addAllInterfaceMethodsIn(EjbDescriptor.java:2327)
在com.sun.enterprise.deployment.EjbDescriptor.getLocalRemoteBusinessMethodDescriptors(EjbDescriptor.java:2290)
... 40更多



com.rares.test.Person



  @Entity 
@Table(name =PERSON)
public class Person implements Serializable {
private static final long serialVersionUID = 3707476467775531463L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column private Long id;
@Column private String name;



com.rares.test.PersonManager



  public interface PersonManager {
void create(com.rares.test.Person p);
}



com.rares.test.PersonDao



  @Stateless 
public class PersonDao implements PersonManager {
@PersistenceContext(unitName =RarePersistUnit)
protected EntityManager mgr;

@Override
public void create(com.rares.test.Person p){
mgr.persist(p);
}

}



persistence.xml



 < persistence version =2.0xmlns =http://java.sun.com/xml/ns/persistencexmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexsi:schemaLocation =http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ NS /持久性/ persistence_2_0.xsd> 
< persistence-unit name =RarePersistUnit>
< provider> org.apache.openjpa.persistence.PersistenceProviderImpl< / provider>
< jta-data-source> jdbc / RaresMySql< / jta-data-source>
< class> com.rares.test.Person< / class>
<属性>

< / properties>
< / persistence-unit>
< / persistence>


解决方案

注意:以下假设 OpenJPA 2.1 Glassfish 3.1



抛出的异常是无法执行 bytecode enchancement 在运行时由OpenJPA。字节码增强可以在构建时间或运行时完成。获得运行时支持的更好的选择之一是使用 javaagent ,但需要一些奇怪的配置:




  • 它需要您在Glassfish域配置文件中指定一个 javaagent (通过指定一个额外的 jvm-options 元素在 java-config 元素下),

  • ,并修改类路径从默认值 $ {com.sun.aas.installRoot} /modules/glassfish.jar 以包含 commons-lang-2.4.jar (我没有打扰,因为它会导致一个非常脆弱的设置)。



可以使用的其他选项运行时是相当片面的,使用 Serp 作为字节码增强器的选择是在部署时抛出异常的原因。显然,由于不正确的类加载器用于定位类,部署时间增强无法找到持久化上下文中使用的类。在我的情况下,Glassfish EarClassLoader EarLibClassLoader classloaders用于在两个单独的调用中加载类,使用以下消息(堆栈跟踪在此不重要):

 警告:LDR5207:ASURLClassLoader EarLibClassLoader:
doneCalled = true
doneSnapshot = ASURLClassLoader.done()调用ON EarLibClassLoader:
urlSet = []
doneCalled = false
父 - > org.glassfish.internal.api.DelegatingClassLoader@10e3c8c
AT Sun Jul 17 13:27:54 IST 2011
BY:java.lang.Throwable:printStackTraceToString
at com.sun.enterprise。 util.Print.printStackTraceToString(Print.java:639)
在com.sun.enterprise.loader.ASURLClassLoader.done(ASURLClassLoader.java:211)
...

...

警告:LDR5207:ASURLClassLoader EarClassLoader:
doneCalled = true
doneSnapshot = ASURLClassLoader.done()调用ON EarClassLoader:
urlSet = [URLEntry:file :/ C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-jsf-0.0.1-SNAPSHOT_war/WEB-INF/classes/,URLEntry:file:/ C:/ glassfish3 / glassfish / domains / domain1 / eclipseApps / app-ear / app-jsf-0.0.1-SNAPSHOT_war / WEB-INF / lib / commons-fileupload-1.2.1.jar,URLEntry:file:/ C:/ glassfish3 / glassfish / domains / domain1 / eclipseApps / app-ear / app-jsf-0.0.1-SNAPSHOT_war / WEB-INF / lib / commons-io-1.4.jar,URLEntry:file:/ C:/ glassfish3 / glassfish / domains / domain1 / eclipseApps / Ë ar / app-jsf-0.0.1-SNAPSHOT_war / WEB-INF / lib / primefaces-3.0.M2.jar,URLEntry:file:/ C:/ glassfish3 / glassfish / domains / domain1 / generated / ejb / app-ear / app-jsf-0.0.1-SNAPSHOT_war /,URLEntry:file:/ C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-ejb-0.0.1-SNAPSHOT_jar/,URLEntry:file:/ C :/glassfish3/glassfish/domains/domain1/generated/ejb/app-ear/app-ejb-0.0.1-SNAPSHOT_jar]
doneCalled = false
父 - > org.glassfish.internal.api.DelegatingClassLoader@1a3fe65
AT Sun Jul 17 13:27:54 IST 2011
BY:java.lang.Throwable:printStackTraceToString
at com.sun.enterprise。 util.Print.printStackTraceToString(Print.java:639)
在com.sun.enterprise.loader.ASURLClassLoader.done(ASURLClassLoader.java:211)
...

...

显然,由于某些未知原因,EJB的生成类区域不包含JPA实体类在运行时导致在部署时无法找到类。最可能的失败原因是实体类虽然在EJB模块中打包,但它们本身可能不会放在生成的类目录中;只有注释的EJB类可能已经被放置在那里。



唯一合理的选择是因此使用构建时间增强,这是通过使用Maven POM中的以下配置进行的:

 < build> 
< plugins>
< plugin>
< groupId> org.apache.maven.plugins< / groupId>
< artifactId> maven-antrun-plugin< / artifactId>
< version> 1.6< / version>
<执行>
< execution>
< phase> process-classes< / phase>
< configuration>
< tasks>
< taskdef name =openjpacclassname =org.apache.openjpa.ant.PCEnhancerTaskclasspathref =maven.compile.classpath/>
< openjpac>
< classpath refid =maven.compile.classpath/>
< / openjpac>
< / tasks>
< / configuration>
< goals>
< goal>运行< / goal>
< / goals>
< / execution>
< / executions>
< / plugin>
< / plugins>
< / pluginManagement>
< / build>

上述配置是从OpenJPA文档派生于使用Maven增强课程。请注意,我没有使用 openjpa-maven-plugin ,因为OpenJPA的版本2.2.0在写入时只能作为快照。



当然,任何上述内容还需要在Glassfish 3.1中安装OpenJPA 2.1,通过将以下JAR复制到 $ {com.sun来完成。 aas.installRoot} / glassfish / lib (例如, C:/ glassfishv3 / glassfish / lib ),而不是提供的建议较旧的博客文章复制到 $ {com.sun.aas.instanceRoot} / lib (例如, C:/ glassfishv3 / glassfish / domains / domain1 / lib




  • commons-beanutils-1.8.3.jar

  • commons-collections-3.2.1.jar

  • commons-dbcp-1.4.jar

  • commons-lang-2.4.jar

  • commons-logging-1.0.4.jar

  • commons-pool-1.5.4.jar

  • serp -1.13.1.jar

  • openjpa-2.1.0.jar



显然,这些JAR在 $ {com .sun.aas.instanceRoot} / lib 导致Maven Glassfish插件无法部署应用程序。



其他JAR( geronimo - * derby - * org.apache.bval *

Is anyone successfully using OpenJPA with Glassfish?

I'm trying to use OpenJPA 2.1 with Glassfish 3.1 Open Source. I've followed the instructions to integrate the two here -> http://weblogs.java.net/blog/ss141213/archive/2006/07/using_openjpa_a.html

I have a very simple EJB project in Eclipse Indigo with the following:

  • com.rares.test.Person - @Entity
  • com.rares.test.PersonManager - interface
  • com.rares.test.PersonDao - @Stateless

However, when I try to deploy I get a ClassNotFoundException on my Person @Entity. The complaint seems to be the Person parm on a create method that's being implemented in my PersonDao (see all code below).

I've tried the same project without specifying a provider in my persistence.xml and the project works fine (able to persist a Person @Entity to a PERSON table in MySql). I think I'm using EclipseLink if I don't specify a provider (please correct me if I'm wrong). This leads me to believe that I haven't configured OpenJPA with Glassfish correctly.

Stack Trace

Caused by: java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: com.rares.test.Person
    at serp.util.Strings.toClass(Strings.java:164)
    at serp.util.Strings.toClass(Strings.java:108)
    at serp.bytecode.BCClass.getType(BCClass.java:566)
    at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:283)
    at org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:254)
    at org.apache.openjpa.enhance.PCClassFileTransformer.transform0(PCClassFileTransformer.java:144)
    at org.apache.openjpa.enhance.PCClassFileTransformer.transform(PCClassFileTransformer.java:124)
    at org.apache.openjpa.persistence.PersistenceProviderImpl$ClassTransformerImpl.transform(PersistenceProviderImpl.java:294)
    at org.glassfish.persistence.jpa.ServerProviderContainerContractInfo$1.transform(ServerProviderContainerContractInfo.java:98)
    at com.sun.enterprise.loader.ASURLClassLoader.findClass(ASURLClassLoader.java:742)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
    at java.lang.Class.privateGetPublicMethods(Class.java:2547)
    at java.lang.Class.getMethods(Class.java:1410)
    at com.sun.enterprise.deployment.EjbDescriptor.addAllInterfaceMethodsIn(EjbDescriptor.java:2327)
    at com.sun.enterprise.deployment.EjbDescriptor.getLocalRemoteBusinessMethodDescriptors(EjbDescriptor.java:2290)
    ... 40 more

com.rares.test.Person

@Entity
@Table (name="PERSON")
public class Person implements Serializable {
    private static final long serialVersionUID = 3707476467775531463L;

    @Id
    @GeneratedValue (strategy=GenerationType.IDENTITY)
    @Column private Long id;
    @Column private String name;

com.rares.test.PersonManager

public interface PersonManager {
    void create (com.rares.test.Person p);
}

com.rares.test.PersonDao

@Stateless
public class PersonDao implements PersonManager {
    @PersistenceContext (unitName="RarePersistUnit")
    protected EntityManager mgr;

    @Override
    public void create(com.rares.test.Person p) {
        mgr.persist(p); 
    }

}

persistence.xml

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="RarePersistUnit">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <jta-data-source>jdbc/RaresMySql</jta-data-source>
        <class>com.rares.test.Person</class>        
        <properties>

        </properties>
    </persistence-unit>
</persistence>

解决方案

Note: The below assumes OpenJPA 2.1 and Glassfish 3.1. Results may vary across versions of both.

The exception thrown is typical of a failure to perform bytecode enchancement at runtime by OpenJPA. Bytecode enhancement can be done at either build time or at runtime. One of the better options available to get runtime support is to use a javaagent but requires some kooky configuration in that:

  • it requires you to specify a javaagent in the Glassfish domain configuration file (by specifying an additional jvm-options element under the java-config element),
  • and also modify the classpath from the default value of ${com.sun.aas.installRoot}/modules/glassfish.jar to include commons-lang-2.4.jar (which I didn't bother doing, as it would have leady to a very fragile setup).

Other options that can be used at runtime are quite flaky, and the choice of using Serp as the bytecode enhancer is the cause of the exception thrown at deploy time. Apparently, the deploy time enhancement fails to locate the classes used in the persistence context, due to incorrect classloaders being used to locate the classes. In my case, the Glassfish EarClassLoader and EarLibClassLoader classloaders were used to load the classes in two separate invocations, with both failing with the following messages (the stack traces are immaterial here):

WARNING: LDR5207: ASURLClassLoader EarLibClassLoader : 
doneCalled = true
doneSnapshot = ASURLClassLoader.done() called ON EarLibClassLoader : 
urlSet = []
doneCalled = false 
 Parent -> org.glassfish.internal.api.DelegatingClassLoader@10e3c8c
 AT Sun Jul 17 13:27:54 IST 2011 
 BY :java.lang.Throwable: printStackTraceToString
    at com.sun.enterprise.util.Print.printStackTraceToString(Print.java:639)
    at com.sun.enterprise.loader.ASURLClassLoader.done(ASURLClassLoader.java:211)
    ...

...

WARNING: LDR5207: ASURLClassLoader EarClassLoader : 
doneCalled = true
doneSnapshot = ASURLClassLoader.done() called ON EarClassLoader : 
urlSet = [URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-jsf-0.0.1-SNAPSHOT_war/WEB-INF/classes/, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-jsf-0.0.1-SNAPSHOT_war/WEB-INF/lib/commons-fileupload-1.2.1.jar, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-jsf-0.0.1-SNAPSHOT_war/WEB-INF/lib/commons-io-1.4.jar, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-jsf-0.0.1-SNAPSHOT_war/WEB-INF/lib/primefaces-3.0.M2.jar, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/generated/ejb/app-ear/app-jsf-0.0.1-SNAPSHOT_war/, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/eclipseApps/app-ear/app-ejb-0.0.1-SNAPSHOT_jar/, URLEntry : file:/C:/glassfish3/glassfish/domains/domain1/generated/ejb/app-ear/app-ejb-0.0.1-SNAPSHOT_jar]
doneCalled = false 
 Parent -> org.glassfish.internal.api.DelegatingClassLoader@1a3fe65
 AT Sun Jul 17 13:27:54 IST 2011 
 BY :java.lang.Throwable: printStackTraceToString
    at com.sun.enterprise.util.Print.printStackTraceToString(Print.java:639)
    at com.sun.enterprise.loader.ASURLClassLoader.done(ASURLClassLoader.java:211)
    ...

...

Apparently, for some unknown reason the generated classes area for EJBs did not contain the JPA entity classes at runtime, leading to the failure to locate the classes at deployment. The most possible reason for failure, is the fact that the entity classes although packaged within the EJB module, may themselves not have been placed in the generated classes directory; only the annotated EJB classes may have been placed there.

The only reasonable option is to therefore use build time enhancement, which was duly done using the following configuration in the Maven POM:

 <build>
     <plugins>
         <plugin>
             <groupId>org.apache.maven.plugins</groupId>
             <artifactId>maven-antrun-plugin</artifactId>
             <version>1.6</version>
                 <executions>
                     <execution>
                         <phase>process-classes</phase>
                         <configuration>
                             <tasks>
                                 <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask" classpathref="maven.compile.classpath"/>
                                 <openjpac>
                                     <classpath refid="maven.compile.classpath"/>
                                 </openjpac>
                             </tasks>
                         </configuration>
                         <goals>
                             <goal>run</goal>
                         </goals>
                     </execution>
                 </executions>
             </plugin>
         </plugins>
    </pluginManagement>
</build>

The above configuration was derived from the OpenJPA documentation on enhancing classes with Maven. Note that I did not use the openjpa-maven-plugin, as version 2.2.0 of OpenJPA is available only as a snapshot at the time of writing this.

Of course, any of the above also required installation of OpenJPA 2.1 in Glassfish 3.1, which was duly done by copying the following JARs to ${com.sun.aas.installRoot}/glassfish/lib (for instance, C:/glassfishv3/glassfish/lib), as opposed to the advice offered on the older blog posts of copying to ${com.sun.aas.instanceRoot}/lib (for instance, C:/glassfishv3/glassfish/domains/domain1/lib)

  • commons-beanutils-1.8.3.jar
  • commons-collections-3.2.1.jar
  • commons-dbcp-1.4.jar
  • commons-lang-2.4.jar
  • commons-logging-1.0.4.jar
  • commons-pool-1.5.4.jar
  • serp-1.13.1.jar
  • openjpa-2.1.0.jar

Apparently, placing these JARs in ${com.sun.aas.instanceRoot}/lib lead to a failure to deploy the application by the Maven Glassfish plugin.

The other JARs (geronimo-*, derby-* and org.apache.bval*) present in the OpenJPA 2.1 distribution are provided by Glassfish 3.1 as part of the Java EE 6 SDK, the Java DB implementation or the Derby client, and within the JSR 303 bean validation framework (Hibernate Validator).

这篇关于OpenJPA是否适用于Glassfish?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆