简体   繁体   中英

java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName HorizonPU with Arquillian

I hope someone can help me with an extremely frustrating issue.

I want to use Arquillian to test a webapp I am developing and I am having a hard time trying to get the JPA tests to run. I am pretty new to Arquillian and I must admit that I find it very tricky to use.

My test case is as follows:

  @RunWith(Arquillian.class)
public class BudgetFacadeTest
{
    @Deployment
    public static WebArchive deploy(){
        WebArchive archive =  ShrinkWrap.create(WebArchive.class, "testarchive.war")
                .addClasses(Budget.class, BudgetLine.class, BudgetSection.class, BudgetFacade.class)
                .addAsManifestResource("META-INF/persistence.xml", "persistence.xml")
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
        System.out.println(archive.toString(true));
        return archive;
    }

    @EJB
    BudgetFacade instance; 


        @Test
    public void testArquillianWorking(){
        instance.count();
    }
    }

which is pretty straightforward. The persistence unit is in a separate test folder, and is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="HorizonPU" transaction-type="JTA">
        <jta-data-source>jdbc/horizonBase</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
            <property name="eclipselink.logging.level.sql" value="FINE"/>
            <property name="eclipselink.logging.parameters" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

The shrinkwrapped archive structure is as follows:

testarchive.war:
/WEB-INF/
/WEB-INF/classes/
/WEB-INF/classes/com/
/WEB-INF/classes/com/macraeanddick/
/WEB-INF/classes/com/macraeanddick/marketinghorizon/
/WEB-INF/classes/com/macraeanddick/marketinghorizon/company/
/WEB-INF/classes/com/macraeanddick/marketinghorizon/company/Budget.class
/WEB-INF/classes/com/macraeanddick/marketinghorizon/company/BudgetSection.class
/WEB-INF/classes/com/macraeanddick/marketinghorizon/company/BudgetLine.class
/WEB-INF/classes/com/macraeanddick/facades/
/WEB-INF/classes/com/macraeanddick/facades/BudgetFacade.class
/META-INF/
/META-INF/beans.xml
/META-INF/persistence.xml

Which I believe is all in order, and the POM is as follows:

    <dependency>
        <groupId>org.jboss.arquillian.junit</groupId>
        <artifactId>arquillian-junit-container</artifactId>
        <scope>test</scope>
    </dependency>        
    <dependency>
        <groupId>org.glassfish.main.extras</groupId>
        <artifactId>glassfish-embedded-all</artifactId>
        <version>4.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.arquillian.container</groupId>
        <artifactId>arquillian-glassfish-embedded-3.1</artifactId>
        <version>1.0.0.CR4</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.jboss.shrinkwrap</groupId>
        <artifactId>shrinkwrap-impl-base</artifactId>
        <scope>test</scope>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>        
</dependencies>

<!--Arquillian Dependency BOMs -->
<dependencyManagement>
    <dependencies>        
        <dependency>
            <groupId>org.jboss.arquillian</groupId>
            <artifactId>arquillian-bom</artifactId>
            <version>1.1.5.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <testResources>
        <testResource>
            <directory>src/test/resources</directory>
        </testResource>
        <testResource>
            <directory>src/test/resources-glassfish-embedded</directory>
        </testResource>
    </testResources>

and yet if I run the test, I get the following:

Caused by: java.lang.IllegalStateException: Unable to retrieve EntityManagerFactory for unitName HorizonPU
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.init(EntityManagerWrapper.java:138)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper._getDelegate(EntityManagerWrapper.java:171)
    at com.sun.enterprise.container.common.impl.EntityManagerWrapper.getCriteriaBuilder(EntityManagerWrapper.java:834)
    at com.macraeanddick.facades.AbstractFacade.count(AbstractFacade.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1081)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1153)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:4786)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:656)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at org.jboss.weld.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:46)
    at org.jboss.weld.ejb.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:608)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doCall(SystemInterceptorProxy.java:163)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:883)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:822)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:369)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:4758)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:4746)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:212)
    ... 108 more

I have absolutely no idea what I am doing wrong and have wasted a day on this already. Any advice would be greatly appreciated!

I got to the bottom of this one eventually. If you are deploying a web-app, then the persistence.xml file needs to go in WEB-INF/classes/META-INF/, in other words META-INF should not be at the top level of the archive. Typically, the documentation for Arquillian is not terribly clear on how to achieve this but the solution for my problem was to change the deployment method in my tests to:

WebArchive archive = ShrinkWrap.create(WebArchive.class, "testarchive.war")
        .addClasses(Budget.class, BudgetLine.class, BudgetSection.class, BudgetFacade.class)
        .addAsResource("META-INF/persistence.xml")
        .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");

Note that persistence.xml is now added with .addAsResource , and beans.xml is added as .addAsWebInfResource .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM