Работает ли OpenJPA с Glassfish? - PullRequest
5 голосов
/ 17 июля 2011

Кто-нибудь успешно использует OpenJPA с Glassfish?

Я пытаюсь использовать OpenJPA 2.1 с Glassfish 3.1 Open Source. Я следовал инструкциям, чтобы объединить их здесь -> http://weblogs.java.net/blog/ss141213/archive/2006/07/using_openjpa_a.html

У меня есть очень простой EJB-проект в Eclipse Indigo со следующим:

  • com.rares.test.Person - @ Entity
  • com.rares.test.PersonManager - интерфейс
  • com.rares.test.PersonDao - @ Stateless

Однако, когда я пытаюсь развернуть, я получаю исключение ClassNotFoundException на моем Person @Entity. Похоже, что жалоба связана с параметром Person для метода create, который реализован в моем PersonDao (см. Весь код ниже).

Я попробовал тот же проект без указания поставщика в моем файле persistence.xml, и проект работает нормально (в состоянии сохранить Person @Entity в таблице PERSON в MySql). Я думаю, что я использую EclipseLink, если я не указываю провайдера (пожалуйста, исправьте меня, если я ошибаюсь). Это заставляет меня поверить, что я не настроил OpenJPA с Glassfish правильно.

Трассировка стека

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>

1 Ответ

12 голосов
/ 17 июля 2011

Примечание: ниже предполагается, что OpenJPA 2.1 и Glassfish 3.1 .Результаты могут отличаться в зависимости от версии.

Исключение, которое выдается, типично для сбоя при выполнении OpenJPA улучшения байт-кода во время выполнения.Улучшение байт-кода может быть сделано во время сборки или во время выполнения.Один из лучших вариантов получения поддержки во время выполнения - использовать javaagent, но для этого требуется некоторая странная конфигурация:

  • , для этого необходимо указать javaagent в файле конфигурации домена Glassfish (указав дополнительный элемент jvm-options в элементе java-config),
  • , а также измените путь к классу из значения по умолчанию ${com.sun.aas.installRoot}/modules/glassfish.jar, включив в него commons-lang-2.4.jar (что я не стал делать, так какэто может привести к очень хрупкой настройке).

Другие параметры, которые можно использовать во время выполнения, довольно нестабильны, и причина исключения - выбор Serp в качестве усилителя байт-кода.брошенный во время развертывания.По-видимому, расширение времени развертывания не может определить местонахождение классов, используемых в контексте постоянства, из-за неправильных загрузчиков классов, используемых для определения местоположения классов.В моем случае загрузчики классов Glassfish EarClassLoader и EarLibClassLoader использовались для загрузки классов в двух отдельных вызовах, при этом оба сбоев приводили к следующим сообщениям (трассировка стека здесь несущественна):

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)
    ...

...

Очевидно, по какой-то неизвестной причине сгенерированная область классов для EJB-компонентов не содержала классы сущностей JPA во время выполнения, что приводило к невозможности найти классы при развертывании.Наиболее вероятной причиной сбоя является тот факт, что классы сущностей, хотя и упакованы в модуле EJB, сами по себе не могли быть помещены в каталог сгенерированных классов;там могли быть размещены только аннотированные классы EJB.

Единственный разумный вариант - использовать расширение времени сборки, которое было должным образом сделано с использованием следующей конфигурации в POM Maven:

 <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>

Приведенная выше конфигурация была получена из документации OpenJPA для улучшающих классов с Maven .Обратите внимание, что я не использовал openjpa-maven-plugin, поскольку версия 2.2.0 OpenJPA доступна только как моментальный снимок на момент написания этой статьи.

Конечно, любое из вышеперечисленного также требовало установки OpenJPA 2.1в Glassfish 3.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-collection-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*), присутствующие в дистрибутиве OpenJPA 2.1, предоставляются Glassfish 3.1 как часть Java EE 6 SDK, Java DB imПлементация или клиент Derby, а также в рамках механизма проверки bean-компонента JSR 303 (Hibernate Validator).

...