4
votes

I'm trying to take a WAR, which deploys and runs fine on Tomcat, and deploy it on Glassfish. The initial error message in Glassfish is:

com.sun.enterprise.deployment.backend.IASDeploymentException: Deployment Error -- The persistence-context-ref-name [org.nhindirect.config.store.dao.impl.AnchorDaoImpl/entityManager] in module [C:\Sun\AppServer\domains\domain1\applications\j2ee-modules\config-service] resolves to a persistence unit called [config-store] which is of type RESOURCE_LOCAL. Only persistence units with transaction type JTA can be used as a container managed entity manager. Please verify your application.

The WAR does not have a persistence.xml in its META-INF folder. However, there is a JAR under WEB-INF\lib that itself contains a persistence.xml. The following are its contents:

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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_1_0.xsd"
    version="1.0">
    <persistence-unit name="config-store" transaction-type="RESOURCE_LOCAL">
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="validate" />
        </properties>
    </persistence-unit>
</persistence>

So here's my question: is it possible to run a WAR configured for RESOURCE_LOCAL on Glassfish, or must I reconfigure the WAR for JTA?

I've investigated the first option by making the following changes to the WAR's web.xml:

  1. Changed version="2.5" to version="2.4"
  2. Changed xmlns="http://java.sun.com/xml/ns/javaee"
    to
    xmlns="http://java.sun.com/xml/ns/j2ee"
  3. Changed xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    to
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

After these changes, the WAR seemed to deploy successfully, however, I could not access its WSDL and the following error was found in the Glassfish log:

Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0' defined in ServletContext resource [/WEB-INF/beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/beans.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javassist/bytecode/ClassFile at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:880) at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:596) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:365) at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4655) at org.apache.catalina.core.StandardContext.start(StandardContext.java:5364) at com.sun.enterprise.web.WebModule.start(WebModule.java:345) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:986) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:970) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:704) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1649) at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1254) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:182) at com.sun.enterprise.server.WebModuleDeployEventListener.moduleDeployed(WebModuleDeployEventListener.java:278) at com.sun.enterprise.admin.event.AdminEventMulticaster.invokeModuleDeployEventListener(AdminEventMulticaster.java:1005) at com.sun.enterprise.admin.event.AdminEventMulticaster.handleModuleDeployEvent(AdminEventMulticaster.java:992) at com.sun.enterprise.admin.event.AdminEventMulticaster.processEvent(AdminEventMulticaster.java:470) at com.sun.enterprise.admin.event.AdminEventMulticaster.multicastEvent(AdminEventMulticaster.java:182) at com.sun.enterprise.admin.server.core.DeploymentNotificationHelper.multicastEvent(DeploymentNotificationHelper.java:308) at com.sun.enterprise.deployment.phasing.DeploymentServiceUtils.multicastEvent(DeploymentServiceUtils.java:231) at com.sun.enterprise.deployment.phasing.ServerDeploymentTarget.sendStartEvent(ServerDeploymentTarget.java:298) at com.sun.enterprise.deployment.phasing.ApplicationStartPhase.runPhase(ApplicationStartPhase.java:132) at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:108) at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:966) at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:609) at com.sun.enterprise.deployment.phasing.PEDeploymentService.start(PEDeploymentService.java:653) at com.sun.enterprise.admin.mbeans.ApplicationsConfigMBean.start(ApplicationsConfigMBean.java:773) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:390) at com.sun.enterprise.admin.MBeanHelper.invokeOperationInBean(MBeanHelper.java:373) at com.sun.enterprise.admin.config.BaseConfigMBean.invoke(BaseConfigMBean.java:477) at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:836) at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:761) at sun.reflect.GeneratedMethodAccessor13.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.enterprise.admin.util.proxy.ProxyClass.invoke(ProxyClass.java:90) at $Proxy1.invoke(Unknown Source) at com.sun.enterprise.admin.server.core.jmx.SunoneInterceptor.invoke(SunoneInterceptor.java:304) at com.sun.enterprise.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:170) at com.sun.enterprise.deployment.client.DeploymentClientUtils.startApplication(DeploymentClientUtils.java:159) at com.sun.enterprise.deployment.client.DeployAction.run(DeployAction.java:538) at java.lang.Thread.run(Thread.java:619) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/beans.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javassist/bytecode/ClassFile at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409) at java.security.AccessController.doPrivileged(Native Method) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:308) at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:270) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:122) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.(PersistenceExceptionTranslationInterceptor.java:78) at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.(PersistenceExceptionTranslationAdvisor.java:70) at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:97) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1326) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473) ... 56 more Caused by: java.lang.NoClassDefFoundError: javassist/bytecode/ClassFile at org.hibernate.ejb.packaging.AbstractJarVisitor.checkAnnotationMatching(AbstractJarVisitor.java:236) at org.hibernate.ejb.packaging.AbstractJarVisitor.executeJavaElementFilter(AbstractJarVisitor.java:202) at org.hibernate.ejb.packaging.AbstractJarVisitor.addElement(AbstractJarVisitor.java:163) at org.hibernate.ejb.packaging.FileZippedJarVisitor.doProcessElements(FileZippedJarVisitor.java:100) at org.hibernate.ejb.packaging.AbstractJarVisitor.getMatchingEntries(AbstractJarVisitor.java:139) at org.hibernate.ejb.Ejb3Configuration.addScannedEntries(Ejb3Configuration.java:287) at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:614) at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:360) at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:131) at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:224) at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:291) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335) ... 73 more

Part of the above error message complains about javassist. This seems strange because the following section is in the WAR's pom.xml

<dependency>
    <groupId>javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.12.1.GA</version>
</dependency>

If helpful, here are the contents of the WAR's beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/tx       http://www.springframework.org/schema/tx/spring-tx.xsd
    http://cxf.apache.org/jaxws                    http://cxf.apache.org/schemas/jaxws.xsd" 
    default-autowire="byName">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <context:annotation-config />
    <context:component-scan base-package="org.nhindirect.config" />
    <tx:annotation-driven transaction-manager="transactionManager" />

    <jaxws:endpoint id="configurationService"
                 address="/ConfigurationService" >
        <jaxws:implementor>
            <bean id="configurationServiceImpl" 
                  class="org.nhindirect.config.service.impl.ConfigurationServiceImpl">
                  <property name="domainSvc" ref="domainSvc"/>
                  <property name="addressSvc" ref="addressSvc"/>
                  <property name="anchorSvc" ref="anchorSvc"/>
                  <property name="certSvc" ref="certSvc"/>
                  <property name="settingSvc" ref="settingSvc"/>
                  <property name="DNSSvc" ref="dnsSvc"/>
            </bean>

        </jaxws:implementor>
    </jaxws:endpoint>

    <!-- <jaxws:endpoint id="addressService" implementor="org.nhindirect.config.service.ws.AddressServiceWS" 
        address="/AddressService" /> -->

    <!--  Service Implementations -->
    <bean id="domainSvc" class="org.nhindirect.config.service.impl.DomainServiceImpl">
       <property name="dao" ref="domainDao"/>
    </bean>
    <bean id="addressSvc" class="org.nhindirect.config.service.impl.AddressServiceImpl">
       <property name="dao" ref="addressDao"/>
    </bean>
    <bean id="anchorSvc" class="org.nhindirect.config.service.impl.AnchorServiceImpl">
       <property name="dao" ref="anchorDao"/>
    </bean>
    <bean id="certSvc" class="org.nhindirect.config.service.impl.CertificateServiceImpl">
       <property name="dao" ref="certificateDao"/>
    </bean>
    <bean id="settingSvc" class="org.nhindirect.config.service.impl.SettingServiceImpl">
       <property name="dao" ref="settingDao"/>
    </bean>
    <bean id="dnsSvc" class="org.nhindirect.config.service.impl.DNSServiceImpl">
       <property name="dao" ref="dnsDao"/>
    </bean> 

    <!--  DAO's -->
    <bean id="domainDao" class="org.nhindirect.config.store.dao.impl.DomainDaoImpl"/>
    <bean id="addressDao" class="org.nhindirect.config.store.dao.impl.AddressDaoImpl"/>
    <bean id="anchorDao" class="org.nhindirect.config.store.dao.impl.AnchorDaoImpl" />
    <bean id="certificateDao" class="org.nhindirect.config.store.dao.impl.CertificateDaoImpl"/>
    <bean id="settingDao" class="org.nhindirect.config.store.dao.impl.SettingDaoImpl"/> 
    <bean id="dnsDao" class="org.nhindirect.config.store.dao.impl.DNSDaoImpl"/> 

    <!-- Exception translation bean post processor -->
    <bean
        class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

<!-- SWAP THIS JPA IMPLEMENTATION WITH THE APPROPROATE DB CONFIGURATION
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" />
            </bean>
        </property>
        <property name="persistenceUnitName" value="config-store" />
    </bean>

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url" value="jdbc:postgresql:nhindconfig" />
        <property name="username" value="nhind" />
        <property name="password" value="nhind" />
    </bean>
-->

<!-- EMBEDDED DERBY JPA CONFIGURATION FOR A WORKING OUT OF THE BOX CONFIGURATION WITH NO PREREQUISITES OF
     SETTING UP AN EXTERNAL DATABASE.  REMOVE THIS SECTION AND REPLACE WITH READ JPA CONFIGURATION (SEE
     ABOVE SECTION) FOR PRODUCTION -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <!--  <property name="databasePlatform" value="org.hibernate.dialect.PostgreSQLDialect" /> -->
                <property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect" />
            </bean>
        </property>
        <property name="dataSource" ref="dataSource"/>
        <property name="persistenceUnitName" value="config-store" />
    </bean> 
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
        <property name="url" value="jdbc:derby:nhindconfig;create=true" />
        <property name="username" value="nhind" />
        <property name="password" value="nhind" />
    </bean>     
<!--  END DERBY JPA CONFIGURATION -->

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" />

</beans>

Sorry if I've provided too much information. I'm new to JPA and wasn't sure what would and wouldn't be helpful to anyone.

Thank you in advance.

1

1 Answers

2
votes

Somewhere in your code you're probably injecting an EntityManager using code that looks something like this:

@PersistanceContext    // Requires JTA
EntityManager em;

In this situation, you're asking the container (Glassfish itself, to create and manage the EntityManager for you. Glassfish being clusterable, attempts to protect you from accidentally making a transaction across multiple servers that is not truly ACID, but requiring you to use a JTA-transaction (which is sharable between multiple clustered servers).

If you know for sure you are NEVER going to cluster your glassfish container for this application, you can safely keep using RESOURCE_LOCAL transactions, however, you cannot have Glassfish manage that EntityManager for you. You can have Glassfish manage an EntityManagerFactory though.

@PersistanceUnit    // Does NOT require JTA
EntityManagerFactory factory;

This is safe to use for persistance units that are RESOURCE_LOCAL. You just need to request an EntityManager from the factory using factory.createEntityManager().

Now your EntityManager is application-managed, not container-managed. So Glassfish will assume that you will handle transaction isolation in a cluster.