2

My project has the following structure:

EAR (derp.ear)
 |
 |____ derp-ui.war
 |
 |____ busctrl.jar
       |
       |____META-INF
               |
               |
               _______ persistence.xml (persistence name of "DEJPA")

The persistence.xml file:

<?xml version="1.0" encoding="UTF-8" ?>
<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"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

    <persistence-unit name="DEJPA" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>jdbc/dejpaDS</jta-data-source>
    </persistence-unit>
</persistence> 

I am making references to the Persistence Context as such:

@Named
public class ExampleDao implements ExampleDaoService {

    @PersistenceContext(name="DEJPA")
    protected EntityManager entityManager;
}

Despite this, I am getting the following stack trace when trying to deploy my EAR to a Glassfish 3.1.2 domain:

SEVERE: Exception while preparing the app : Could not resolve a persistence unit corresponding to the persistence-context-ref-name [DEJPA] in the scope of the module called [derp#derp-ui.war]. Please verify your application.
java.lang.RuntimeException: Could not resolve a persistence unit corresponding to the persistence-context-ref-name [DEJPA] in the scope of the module called [derp#derp-ui.war]. Please verify your application.
    at com.sun.enterprise.deployment.BundleDescriptor.findReferencedPUViaEMRef(BundleDescriptor.java:694)
    at com.sun.enterprise.deployment.BundleDescriptor.findReferencedPUsViaPCRefs(BundleDescriptor.java:682)
    at com.sun.enterprise.deployment.WebBundleDescriptor.findReferencedPUs(WebBundleDescriptor.java:1056)
    at org.glassfish.persistence.jpa.JPADeployer.createEMFs(JPADeployer.java:186)
    at org.glassfish.persistence.jpa.JPADeployer.prepare(JPADeployer.java:168)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:871)
    at org.glassfish.javaee.full.deployment.EarDeployer.prepareBundle(EarDeployer.java:290)
    at org.glassfish.javaee.full.deployment.EarDeployer.access$200(EarDeployer.java:86)
    at org.glassfish.javaee.full.deployment.EarDeployer$1.doBundle(EarDeployer.java:141)
    at org.glassfish.javaee.full.deployment.EarDeployer$1.doBundle(EarDeployer.java:138)
    at org.glassfish.javaee.full.deployment.EarDeployer.doOnBundles(EarDeployer.java:215)
    at org.glassfish.javaee.full.deployment.EarDeployer.doOnAllTypedBundles(EarDeployer.java:224)
    at org.glassfish.javaee.full.deployment.EarDeployer.doOnAllBundles(EarDeployer.java:250)
    at org.glassfish.javaee.full.deployment.EarDeployer.prepare(EarDeployer.java:138)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.prepareModule(ApplicationLifecycle.java:871)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:410)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:389)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:348)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:363)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1085)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:95)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1291)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1259)
    at com.sun.enterprise.v3.admin.AdminAdapter.doCommand(AdminAdapter.java:461)
    at com.sun.enterprise.v3.admin.AdminAdapter.service(AdminAdapter.java:212)
    at com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:179)
    at com.sun.enterprise.v3.server.HK2Dispatcher.dispath(HK2Dispatcher.java:117)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$Hk2DispatcherCallable.call(ContainerMapper.java:354)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:619)

I have unpacked the EAR and verified that the file is present at the given location.

Please advise - I am wholly unconvinced by the suggestion by the log that the persistence.xml file which pertains to entities and DAOs within my JAR should infact be hosted within my WAR.

8bitjunkie
  • 12,793
  • 9
  • 57
  • 70
  • If you are trying to use an EntityManager within the WAR, yep, you need a persistence.xml file within the WAR. Shouldn't you daos be instead on the JAR where the entities are defined? – German Apr 26 '13 at 22:47
  • I inject Controller Impl EJBs into JSF backing beans (WAR), which in turn pass Domain Entitites through to my DAOs for persistence. The EntityManager is not used in the WAR, it is used in the DAO JAR. The persistence.xml file is hosted at the EAR root in the busctrl.jar file. This config works in a different Application Server :-( – 8bitjunkie Apr 29 '13 at 09:27

1 Answers1

2

If busctrl.jar isn't a "deployed" component (containing EJBs) then move it into lib/busctrl.jar within the EAR file where it'll be visible on the classpath of the war file.

If it does contain EJBs, then some surgery needs to occur:

  • move EJBs definitions (implementations) into jar file(s) to be placed at the root level of the EAR file (/busEjb.jar).

  • move remote EJB declarations into their own JAR file to be placed in the EAR library (/lib/busEjbClient.jar).

  • move JPA entities & persistence.xml file into their own JAR file to be placed in the EAR library (/lib/busModel.jar).


Nothing in my review of the topic suggests that what you did in your original post shouldn't work in Glassfish, or other app servers. The class loader hierarchy should have made the persistence.xml file available.

That said, most discussions tend toward the best-practice of placing the persistence.xml file and entity classes into a separate library. I suspect this has to do with both the class loader hierarchy (possibly not a problem in this case) and with the internal search tooling to locate the persistence.xml file - which would be implemented by EclipseLink in this case. This discussion on EclipseLink may be relevant.

Richard Sitze
  • 8,262
  • 3
  • 36
  • 48
  • The busctrl.jar is hosted at the root level of the EAR and contains EJB implementations of Controller interfaces (also hosted in this jar). There is another dependency (common.jar) which contains the JPA entities - this is located in the lib folder as suggested. Similarly I have a svccom.jar located in the lib folder which contains my DAOs (Spring hosted). The hierarchy works in Oracle WebLogic Application Server so I am suprised that I cannot just deploy to an alternative (better) application server! – 8bitjunkie Apr 29 '13 at 09:25
  • Followup: I placed a copy of the persistence.xml file in the lib folder based dependency which contains the DAOs, and this solved the problem on Glassfish. Are you aware if this is a standard for laying out an EAR? I'm mystified as to how Weblogic AS is happy with it yet Glassfish can't see the persistence.xml file located in the EAR-level JAR. – 8bitjunkie Apr 29 '13 at 10:15
  • Nothing clear about the standard :-). I do see this as a best-practice though. You may also be able to resolve by working with the manifest's classpath. – Richard Sitze Apr 29 '13 at 16:23
  • 1
    Let me rephrase: nothing clear in the standard that would indicate *why* you're having a problem with Glassfish. – Richard Sitze Apr 29 '13 at 21:23