Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-1105

PU Injection across JARs (separate DeploymentUnits)

    Details

    • Type: Feature Request
    • Status: Open (View Workflow)
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: JPA / Hibernate
    • Environment:
      Linux, Window, MacOS, *BSD
    • Estimated Difficulty:
      High
    • Similar Issues:
      Show 10 results 

      Description

      the following architecture of jars/wars doesn't load correctly in JBossAS 7 but it was used to load perfectly in all previous versions...i know about the new loading way so i am explaining the scenario:

      myjar-model.jar : Contains entities and the persistence.xml which defines also a persistence unit inside the META-INF folder.
      myjar-buisness.jar: Contains EJB's and Spring beans that uses the model.There is an annotation with @PersistenceContext(name="mypu") on this EJB's for the entity manager to work. The jboss-deployment-structure.xml has declared dependency in the deployment.mcube-model.jar.

      I am copying both of these files first the model and then the buisness in the standalone profile in deployments folder.The first one is loaded successfully.The second one that also uses classes from the previous one can see the classes but not the pu need it for the db operations.The exception follows:

      [code]

      10:33:49,369 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC00001: Failed to start service jboss.deployment.unit."myjar-buisness.jar".INSTALL: org.jboss.msc.service.StartException in service jboss.deployment.unit."mcube-buisness.jar".INSTALL: Failed to process phase INSTALL of deployment "myjar-buisness.jar"

      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:121)

      at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1765)

      at org.jboss.msc.service.ServiceControllerImpl$ClearTCCLTask.run(ServiceControllerImpl.java:2291)

      at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [:1.6.0_26]

      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [:1.6.0_26]

      at java.lang.Thread.run(Thread.java:662) [:1.6.0_26]

      Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: Component class **.*.GenericDAOImpl for component MyBean has errors:

      Can't find a deployment unit named myjar-persistence at deployment "myjar-buisness.jar"

      at org.jboss.as.ee.component.ModuleJndiBindingProcessor$1.handle(ModuleJndiBindingProcessor.java:133)

      at org.jboss.as.ee.component.ClassDescriptionTraversal.run(ClassDescriptionTraversal.java:52)

      at org.jboss.as.ee.component.ModuleJndiBindingProcessor.processClassConfigurations(ModuleJndiBindingProcessor.java:129)

      at org.jboss.as.ee.component.ModuleJndiBindingProcessor.deploy(ModuleJndiBindingProcessor.java:122)

      at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:115)

      ... 5 more

      [/code]

      Following scenario/arcs:
      Web application which is assembled by 4 different jars/wars:
      (1)myapp-model.jar -> contains the model + persistence.xml containing the definition of a CMT.
      (2)myapp-buisness.jar -> contains buisness EJB3's Spring Beans, whatever you can think of.
      (3)myapp-messaging.jar -> Contains MDB's for sending messages to several queues.
      (4)myapp-console.war -> Contains the web interface of the app.
      Now the > define a dependency from a project to another to function,i.e. A>B means that A project has a dependency in B. Now the graph of dependencies between projects are:
      (4)>(2)>(1).

      Currently in jboss as 7 you are able to deploy your application either as module exposing several services(even though there is no clear documentation on how you do that.You follow the old way, you have to do something else?Nowhere in any documentation isn't that documented.) or you can use the deployments folder and copy everything there.Given the previous scenario if we deploy the module(2) then even if we have as dependency in the jboss-deployment-structure.xml the reference to the module(1) then we will get an exception saying that the persistence unit defined isn't accessible or undefined for the module(2). Now with the new version of jboss that allow us to manipulate the dependencies using the module mechanism and the well defined deployment and dependencies between projects it would be really useful if.
      When we define a dependency from one module to another, in my example from (2)->(1), also the mcs services defined are also exported in the target deployment, thus allowing access to the pu with the name for example is deployed. I don't know if this can be applied for the module architecture also.

      regards
      Nick

        Gliffy Diagrams

          Activity

          Hide
          smarlow Scott Marlow added a comment -

          John, are you saying that you would package all artifacts in one (EAR) deployment? I think that is what users currently do today.

          One general question to any one that is following, I think that we might have a way to ensure that the deployment with the PU definition is deployed completely before the other deployments that depend on it but I'm not sure of the details (if there is even a way).

          As per what Stuart previously said, we can have the injecting side deployment, have a service dependency on the PU side, which would fail if the PU side is deployed last (I think).

          Scott

          Show
          smarlow Scott Marlow added a comment - John, are you saying that you would package all artifacts in one (EAR) deployment? I think that is what users currently do today. One general question to any one that is following, I think that we might have a way to ensure that the deployment with the PU definition is deployed completely before the other deployments that depend on it but I'm not sure of the details (if there is even a way). As per what Stuart previously said, we can have the injecting side deployment, have a service dependency on the PU side, which would fail if the PU side is deployed last (I think). Scott
          Hide
          jjfraney John Franey added a comment - - edited

          John, are you saying that you would package all artifacts in one (EAR) deployment? I think that is what users currently do today.

          No. The myModel.jar would be predeployed (as module or deployment) separately from the applications that depend on it.

          Applications (ear, war or deployable jars) would declare their dependency on 'external' myModel in the usual as7 way.

          Each application has its own private persistence unit, named the same but not necessarily. The persistence classes and the orm are in the shared deployment/module. The persistence unit is NOT in the shared deployment/module.

          Show
          jjfraney John Franey added a comment - - edited John, are you saying that you would package all artifacts in one (EAR) deployment? I think that is what users currently do today. No. The myModel.jar would be predeployed (as module or deployment) separately from the applications that depend on it. Applications (ear, war or deployable jars) would declare their dependency on 'external' myModel in the usual as7 way. Each application has its own private persistence unit, named the same but not necessarily. The persistence classes and the orm are in the shared deployment/module. The persistence unit is NOT in the shared deployment/module.
          Hide
          smarlow Scott Marlow added a comment -

          Thanks for clarifying John and sharing on this! Your use case is a little different than was originally brought up in this jira (the AS7-1769 related use case has persistence.xml + entities in the same deployment unit). Are you thinking about trying your approach or have tried it?

          Show
          smarlow Scott Marlow added a comment - Thanks for clarifying John and sharing on this! Your use case is a little different than was originally brought up in this jira (the AS7-1769 related use case has persistence.xml + entities in the same deployment unit). Are you thinking about trying your approach or have tried it?
          Hide
          jjfraney John Franey added a comment -

          I am in the middle of trying it. I'm able to deploy a jar file with a persistence unit depending on persistence classes in a predeployed: deployment.xxxx.ear.myModel.jar. There is no deploy error from as7.1.1, but I haven't yet invoked the service from a client just yet.

          I know it is not exactly what is asked for, but it seemed related. I think the original request is derived from a desire to isolate the application deployment from the model deployment, so that they can be upgraded independently.

          The original thinking for this is to put the persistence unit in with the model, and most of the design notes above have been around how to make that work. My suggestion takes a different approach. With the persistence unit in the application deployable, it is discovered when the application is deployed, and as7 gives access to the orm.xml and the persistence classes with the as7 classloading rules. There is not a technical problem, or so I put forth here. So, if the packaging design is acceptable to the original poster, I think the requirement of independent deployment can be met without waiting for this issue resolved.

          Show
          jjfraney John Franey added a comment - I am in the middle of trying it. I'm able to deploy a jar file with a persistence unit depending on persistence classes in a predeployed: deployment.xxxx.ear.myModel.jar. There is no deploy error from as7.1.1, but I haven't yet invoked the service from a client just yet. I know it is not exactly what is asked for, but it seemed related. I think the original request is derived from a desire to isolate the application deployment from the model deployment, so that they can be upgraded independently. The original thinking for this is to put the persistence unit in with the model, and most of the design notes above have been around how to make that work. My suggestion takes a different approach. With the persistence unit in the application deployable, it is discovered when the application is deployed, and as7 gives access to the orm.xml and the persistence classes with the as7 classloading rules. There is not a technical problem, or so I put forth here. So, if the packaging design is acceptable to the original poster, I think the requirement of independent deployment can be met without waiting for this issue resolved.
          Hide
          bmaxwell Brad Maxwell added a comment -

          I suppose it worked before because the persistence unit was being deployed into the unified classloader. In Wildlfy all deployments are in their own classloader.
          The JavaEE specs define things in terms of deployments and deployments should have everything they require packaged.

          As far as shaing a PersistenceUnit / EntityManager across deployments, it can be done by specifying the 'jboss.entity.manager.jndi.name' Hibernate property in the persistence.xml. This will bind the EntityManager in JNDI.

          <persistence-unit name="shared-jpa" transaction-type="JTA">
          ...
          <properties>
          ...
          <property name="jboss.entity.manager.jndi.name" value="java:shared/HelloWorldEntityManager"/>
          <property name="jboss.entity.manager.factory.jndi.name" value="java:shared/HelloWorldEntityManagerFactory"/>
          </properties>
          </persistence-unit>

          The deploy the jar containing the JPA Entities and persistence.xml.
          Then any other deployment that needs the Persistence unit would declare a classloading dependency on the persistence jar deployment via jboss-deployment-structure.xml
          Then just inject the EntityManager or look it up such as:

          @Resource(lookup="java:shared/HelloWorldEntityManager")
          private EntityManager entityManager;

          Show
          bmaxwell Brad Maxwell added a comment - I suppose it worked before because the persistence unit was being deployed into the unified classloader. In Wildlfy all deployments are in their own classloader. The JavaEE specs define things in terms of deployments and deployments should have everything they require packaged. As far as shaing a PersistenceUnit / EntityManager across deployments, it can be done by specifying the 'jboss.entity.manager.jndi.name' Hibernate property in the persistence.xml. This will bind the EntityManager in JNDI. <persistence-unit name="shared-jpa" transaction-type="JTA"> ... <properties> ... <property name="jboss.entity.manager.jndi.name" value="java:shared/HelloWorldEntityManager"/> <property name="jboss.entity.manager.factory.jndi.name" value="java:shared/HelloWorldEntityManagerFactory"/> </properties> </persistence-unit> The deploy the jar containing the JPA Entities and persistence.xml. Then any other deployment that needs the Persistence unit would declare a classloading dependency on the persistence jar deployment via jboss-deployment-structure.xml Then just inject the EntityManager or look it up such as: @Resource(lookup="java:shared/HelloWorldEntityManager") private EntityManager entityManager;

            People

            • Assignee:
              Unassigned
              Reporter:
              cirix Nikos Ballas
            • Votes:
              13 Vote for this issue
              Watchers:
              22 Start watching this issue

              Dates

              • Created:
                Updated:

                Development