1 2 Previous Next 15 Replies Latest reply on Jun 1, 2012 3:29 AM by cirix

    How to inject PersistenceContext defined in an entity-class-only jar

    glsilver

      I want to separate my entity classes from EJBs into two separate libraries. Testing with the jboss-as-login example in Jboss Quickstarts, I removed User.java and put it in its own jar, called login.model. The jar contains the persistence.xml in META-INF, and I deploy it directly in standalone/deployments in JBOSS AS7. Then, I create a dependency to login.model.jar in jboss-as-login's MANIFEST.INF, as well as add a dependency in the POM file with provided scope so it will compile. I even added unitName="loginDatabase" to the PersistenceContext annotation in Resources.java. However, when I deploy jboss-as-login and try to login as a user in the running application, I get the following error:

       

      08:45:24,460 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost-127.0.0.1-8080-1) Error Rendering View[/users.xhtml]: java.lang.IllegalArgumentException: JBAS016069: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named loginDatabase in deployment jboss-as-login.war

                at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:96) [jboss-as-weld-7.1.2.Final-SNAPSHOT.jar:7.1.2.Final-SNAPSHOT]

                at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.resolvePersistenceContext(WeldJpaInjectionServices.java:61) [jboss-as-weld-7.1.2.Final-SNAPSHOT.jar:7.1.2.Final-SNAPSHOT]

                at org.jboss.weld.util.Beans.injectEEFields(Beans.java:622) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget$1$1.proceed(ManagedBean.java:160) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget$1.work(ManagedBean.java:157) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$FixInjectionPoint.run(ManagedBean.java:131) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.inject(ManagedBean.java:153) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:293) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:61) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:636) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.AbstractReceiverBean.getReceiver(AbstractReceiverBean.java:75) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ProducerMethod$1.produce(ProducerMethod.java:131) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:307) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.context.unbound.DependentContextImpl.get(DependentContextImpl.java:61) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:636) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:702) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.injection.FieldInjectionPoint.inject(FieldInjectionPoint.java:123) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.util.Beans.injectBoundFields(Beans.java:698) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.util.Beans.injectFieldsAndInitializers(Beans.java:707) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget$1$1.proceed(ManagedBean.java:161) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:48) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget$1.work(ManagedBean.java:157) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$FixInjectionPoint.run(ManagedBean.java:131) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.inject(ManagedBean.java:153) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:293) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:107) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.manager.BeanManagerImpl.getReference(BeanManagerImpl.java:636) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.AbstractReceiverBean.getReceiver(AbstractReceiverBean.java:75) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.ProducerMethod$1.produce(ProducerMethod.java:131) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.AbstractProducerBean.create(AbstractProducerBean.java:307) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:107) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:90) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:104) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.jboss.weld.proxies.Collection$Iterable$List$-1869897006$Proxy$_$$_WeldClientProxy.size(Collection$Iterable$List$-1869897006$Proxy$_$$_WeldClientProxy.java) [weld-core-1.1.7.Final.jar:]

                at javax.faces.model.ListDataModel.isRowAvailable(ListDataModel.java:110) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.model.ListDataModel.setRowIndex(ListDataModel.java:185) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.model.ListDataModel.setWrappedData(ListDataModel.java:220) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.model.ListDataModel.<init>(ListDataModel.java:79) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIData.getDataModel(UIData.java:1804) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIData.setRowIndex(UIData.java:473) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:820) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIData.encodeBegin(UIData.java:1118) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1777) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) [jsf-impl-2.1.7-jbossorg-2.jar:]

                at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594) [jboss-jsf-api_2.1_spec-2.0.2.Final.jar:2.0.2.Final]

                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.14.Final.jar:]

                at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.7.Final.jar:2012-04-09 10:12]

                at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.14.Final.jar:]

                at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.2.Final-SNAPSHOT.jar:7.1.2.Final-SNAPSHOT]

                at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.2.Final-SNAPSHOT.jar:7.1.2.Final-SNAPSHOT]

                at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.14.Final.jar:]

                at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.14.Final.jar:]

                at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.14.Final.jar:]

                at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.14.Final.jar:]

                at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:931) [jbossweb-7.0.14.Final.jar:]

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

       

      How else can I set things up so that PersistenceContext injection will work?

        • 1. Re: How to inject PersistenceContext defined in an entity-class-only jar
          smarlow

          Hmm, so you want to inject a PersistenceContext defined in a separate deployments entity-class-only jar.  There currently isn't a way to do that.

           

          Is there some pain that not being able to do this, causes you?  Could you explain why?  I'd like to hear more about how this helps you during development and/or deployment. 

          • 2. Re: How to inject PersistenceContext defined in an entity-class-only jar
            glsilver

            Isn't this the very essence of modularity? We've got a massively compex database with hundreds of entities that need to be managed. I don't want to have to pick apart a huge object model library just to make small changes in some data access object, as we are constantly doing now in our application. I would prefer to encapsulate functionality into more cohesive units and deploy those as needed. My idea is to create a single entity manager that can be injected into any dao that needs it, even if it is in a separate jar file. I seem to recall that the Eclipse Virgo project, an OSGi environment, allows separate packaging of entities and data access objects, and there is even a demo to illlustrate this. So assume it can be done using the module approach in Jboss AS7. Am I wrong?

            • 3. Re: How to inject PersistenceContext defined in an entity-class-only jar
              smarlow

              I'm not arguing or saying your wrong.  I'm just trying to understand the pain better at a higher level. 

              • 4. Re: How to inject PersistenceContext defined in an entity-class-only jar
                glsilver

                I hope I was able to convey the need. Basically, the more moldular and cohesive our code, the more benefits we accrue, not to mention simpler debugging and less regression testing, With a simpler database and less complex and changing business logic, you can get by with a single entity-dao library, but that's a rare situaltion.  In any case, I was hoping a solution was available.

                • 5. Re: How to inject PersistenceContext defined in an entity-class-only jar
                  glsilver

                  To be more precise, given a hundred tables in your database and assuming you have a table-per-dao, or some close facsimile, arhitecture, wouldn't you want to break things up? The simplest place to start is to separating out the entities, which tend to be much more stable than the DAOs, Then, only your dao libraries need morph as your business logic grows. The only way to really handle this in a rapid, customer-driven fashion, is to achieve true separation of concerns with respect to entity management, which is really a db cash, albeit with Java beans, and data access, which encapsulates business processes. When you think about it, there are really two different developer skill-sets involved - one requiring inimate knowledge of JPA, and not so much the business logic the other, just the opposite.

                  • 6. Re: How to inject PersistenceContext defined in an entity-class-only jar
                    glsilver

                    I'll give you a more concrete business case for this kind of separation - using Spring Data. Wouldn't it be great to just be able to put all your Resource implementations in their own libraries, separate from the entities they encapsulate? I would like to be able to accomplish this. But how to do it is the question?

                    • 7. Re: How to inject PersistenceContext defined in an entity-class-only jar
                      cirix

                      Hi Glenn,

                       

                      I had the similar debate and probably tried to do soem stuff,here is the JIRA I have created with exactly in mind what you mention:https://issues.jboss.org/browse/AS7-1769.

                      On the other hand based on the JEE 6 specification deployments should be compacted as .war .ear. I understand your point and that was also my argument.The solution that

                      I found on that was dead simple.JBoss 7.1.1 is also full OSGi compatible and a configuration as described is more likely to feet in OSGi...I OSGify my project. On the other hand the

                      JIRA is opened and you can find a discussion I had about it and comments on JIRA...to be implemented.

                       

                      kind regards

                      Nick

                      • 8. Re: How to inject PersistenceContext defined in an entity-class-only jar
                        glsilver

                        Hi, Nikos,

                         

                        Thank you for that. I might, as you suggest, have to abandone the Jboss AS7 module approach and go straight to OSGi. I'm looking at how this is done in the latest Eclipse Virgo Tomcat server, as it has some good sample code to walk through. I'l have a look at the open JIRA you mentioned, as well. The only other option I have found that works is to package the entity jar in WEB-INF/lib of each war file deployed that needs data access. In my case, that involves some 60+ war files that go into our portal configuration. That's just not acceptable.

                        • 9. Re: How to inject PersistenceContext defined in an entity-class-only jar
                          cirix

                          In case of a portal,shall i assume that you have portlets also,I would vote for an OSGi architecture.The problem with OSGi is that still isn't so well documented.You can find a project

                          from Apache(sorry JBoss guys) called Aries which allows you to OSGify jars easily.Have a look at it.Also there is another way from the Spring-Osgi but still now we are mixing stuff,frame

                          works , technologies.I understand the architecture constraint...vote for OSGi.It creates a more loosly couple architecture and also will minimize the downtime.No need to restart entire stuff

                          for a change.

                           

                          good luck

                           

                          \n\m

                          • 10. Re: How to inject PersistenceContext defined in an entity-class-only jar
                            glsilver

                            After further review, I would like to avoid porting the entire application to OSGi (managing OSGi servers seems a paradigm shift from managing Java EE servers) and to stick with the Jboss modules approach to classpath management. Since this discussion seems to have ended without a solution to that end, I'm assuming the JBoss folks are content with things as they are and to not allow modularization of the JPA persistence subsystem of an application. I'm very disappointed that something so essential has been overlooked.

                            • 11. Re: How to inject PersistenceContext defined in an entity-class-only jar
                              smarlow

                              Glenn,

                               

                              I'm not against the idea of having a standalone persistence only deployment, which is why I asked you for more details about what you wanted exactly.  Nikos and I started looking at this together but if I'm remembering correctly, we both ran out of time to work on it (plus our initial ideas didn't work).  I'd like to take another shot at solving this, just not sure when yet.

                               

                              Some of the concerns that have to be addressed:

                               

                              • other applications need a way to add a (service) dependency on the standalone persistence deployment.  This will help ensure that applications depending on persistence deployment will only be available when the persistence deployment is available.
                              • other applications need a way to add a (classloader) dependency on the standalone persistence deployment.  Since that is where the entity classes are defined.  We probably have enough infrastructure already in AS7 to handle this.
                              • other applications need a way to resolve the persistence units that are defined in the standalone persistence deployment.  For example, this might be some special syntax in the @PersistenceContext(name="PersistenceDeploymentName#sharedpu234") reference.
                              • how to package the standalone persistence only deployment (perhaps its a simple jar with some extra metadata marking it as a shared persistence deployment).

                               

                              Scott

                              • 12. Re: How to inject PersistenceContext defined in an entity-class-only jar
                                glsilver

                                Scott,

                                 

                                It seems that what I am looking for is not strictly part of the Java EE 6 spec for packaging a persistence unit, which states it must either be part of an EJB deployment, included in WEB-INF/lib of a war file or be packaged in an EAR. As you point out, it would take a lot of work to circumvent these restrictions, and even then, it may not accomplish much in the end that can't be done within an EAR structure.  The OSGi environment is definitely more flexible. I wasn't fully aware of the complexity of this issue until you enlightened me.

                                • 13. Re: How to inject PersistenceContext defined in an entity-class-only jar
                                  cirix

                                  The main problem we were facing is that you have to inject to much stuff and search for them.For example if you have a war that depends from an external jar...you have to make sure that the jar

                                  is firstly loaded before the deployment of the war will take place.It's true that based on the JEE 6 specification such packaging doesn't stands true.But also such deployment was also sometimes

                                  the root of all evil for the classloader hell many jee applications were facing in the "previous era"...Maybe the module infrastructre can be changed in order to support that but then i think it loses the full

                                  jee 6 compliance.The truth is that due the the heavy workload I never have the chance to look deep into the JIRA issue.But the other problem is that it was only me and Scott...and I had tons of work for my day life work + Scott was running to release the 7.1 Brontes.And since it's not necessary for the jee 6 compliance nor indicated as a must from any JSR that's why probably also the team didn't invest time on that. I don't want to go into details,since i don't know,how bugs are put in the hierarchy in jboss(votes probably).I can see your point but OSGi can be tricky at the begging but REALLY flexible when configured correctly...the problem is the lack of documentation...In the  JIRA issue we have also the necessary class probably that needs to be altered if I am not mistaken.Maybe we can combine resources and close the JIRA?

                                   

                                  status:waiting for input.

                                   

                                  regards

                                  Nikos

                                  • 14. Re: How to inject PersistenceContext defined in an entity-class-only jar
                                    glsilver

                                    Nikos,

                                     

                                    I guess the question is whether it is worth the effort to extend the module framework in JBoss AS7 beyond Java EE 6 compliance in this way, or to succumb entirely over to OSGi?  In any  case, isn't the next version of Java EE (8??) supposed to incorporate a module framework - sort of an OSGi-lite? And might not that resolve this issue?

                                    1 2 Previous Next