2 Replies Latest reply on May 27, 2013 3:28 AM by sfcoy

    Injecting Persistence Unit from OSGI JPA Bundle

    canotech

      Hi,

       

      Perhaps some here can help me. I had a ejb jar for my persistence stuff called bar-entitites.jar. This jar contained a /META-INF/persistence.xml file descriptor. When I deployed this archive, everything went well. Then I created another project called bar-entities-dao.jar which contained my data access objects. I added the following to MANIFEST.MF to make sure the bar-entities-dao.jar found classes from bar-entities.jar

       

       

      Manifest-Version: 1.0
      Dependencies: deployment.bar-entities.jar
      

       

      I tried to deploy and I got the following exception:

       

       

      15:28:09,717 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-4) MSC000001: Failed to start service jboss.deployment.unit."bar-entities-dao.jar".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."bar-entities-dao.jar".WeldStartService: Failed to start service
                at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1930) [jboss-msc-1.1.2.Final.jar:1.1.2.Final]
                at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [rt.jar:1.7.0_01]
                at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [rt.jar:1.7.0_01]
                at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_01]
      Caused by: java.lang.IllegalArgumentException: JBAS016069: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named bar-unit in deployment bar-entities-dao.jar
                at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:116)
                at org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:74)
                at org.jboss.weld.injection.ResourceInjectionPoint.forPersistenceContext(ResourceInjectionPoint.java:53)
                at org.jboss.weld.injection.InjectionPointFactory$3.createResourceInjectionPoint(InjectionPointFactory.java:262)
                at org.jboss.weld.injection.InjectionPointFactory$3.createResourceInjectionPoint(InjectionPointFactory.java:259)
                at org.jboss.weld.injection.InjectionPointFactory$ResourceInjectionPointDiscovery.proceed(InjectionPointFactory.java:230)
                at org.jboss.weld.injection.InjectionPointFactory.getPersistenceContextInjectionPoints(InjectionPointFactory.java:259)
                at org.jboss.weld.injection.producer.ResourceInjector.<init>(ResourceInjector.java:50)
                at org.jboss.weld.injection.producer.BeanInjectionTarget.initInjector(BeanInjectionTarget.java:58)
                at org.jboss.weld.injection.producer.BasicInjectionTarget.<init>(BasicInjectionTarget.java:70)
                at org.jboss.weld.injection.producer.BeanInjectionTarget.<init>(BeanInjectionTarget.java:52)
                at org.jboss.weld.manager.InjectionTargetFactoryImpl.createInjectionTarget(InjectionTargetFactoryImpl.java:95)
                at org.jboss.weld.bean.ManagedBean.<init>(ManagedBean.java:100)
                at org.jboss.weld.bean.ManagedBean.of(ManagedBean.java:84)
                at org.jboss.weld.bootstrap.AbstractBeanDeployer.createManagedBean(AbstractBeanDeployer.java:269)
                at org.jboss.weld.bootstrap.BeanDeployer.createClassBean(BeanDeployer.java:238)
                at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:71)
                at org.jboss.weld.bootstrap.ConcurrentBeanDeployer$2.doWork(ConcurrentBeanDeployer.java:69)
                at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
                at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
                at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0_01]
                at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0_01]
                ... 3 more
      
      

       

       

      I checked around online and read that its not possible to do what I want to do as per EE spec. I understood that I would either have to package my separate modules into an ear structure.....or use OSGI.

       

       

      I added osgi support to my bar-entities.jar by modifying its MANIFEST.MF file and now it looks like this:

       

       

      Manifest-Version: 1.0
      Bundle-ManifestVersion: 2
      Meta-Persistence: META-INF/persistence.xml
      Bundle-Name: bar-entities
      Bundle-SymbolicName: com.foo.bar-entities
      Bundle-Version: 0.0.1
      
      

       

       

      I added osgi support in my standalone.xml and added the javax.enterprise.api capability. So now it looks like the following:

       

       

       

      <subsystem xmlns="urn:jboss:domain:osgi:1.2" activation="eager">
                  <properties>
                      <property name="org.osgi.framework.startlevel.beginning">
                          1
                      </property>
                  </properties>
                  <capabilities>
                      <capability name="javax.jws.api"/>
                      <capability name="javax.persistence.api"/>
                      <capability name="javax.servlet.api"/>
                      <capability name="javax.transaction.api"/>
                      <capability name="javax.ws.rs.api"/>
                      <capability name="javax.xml.bind.api"/>
                      <capability name="javax.xml.ws.api"/>
                      <capability name="javax.enterprise.api"/>
                      <capability name="javax.jms.api"/>
                      <capability name="org.slf4j"/>
                      <capability name="org.apache.felix.log" startlevel="1"/>
                      <capability name="org.jboss.osgi.logging" startlevel="1"/>
                      <capability name="org.apache.felix.configadmin" startlevel="1"/>
                      <capability name="org.jboss.as.osgi.configadmin" startlevel="1"/>
                      <capability name="org.jboss.as.osgi.http" startlevel="1"/>
                      <capability name="org.jboss.as.osgi.jpa" startlevel="1"/>
                  </capabilities>
              </subsystem>
      
      

       

       

      I redeployed bar-entities.jar and it seems to be installed correctly as an OSGI bundle as shown from the logs at server boot:

       

       

       

      15:18:10,995 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: org.apache.felix.log:1.0.0
      15:18:10,998 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: jboss-osgi-logging:1.0.0
      15:18:11,002 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: org.apache.felix.configadmin:1.2.8
      15:18:11,004 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: wildfly-osgi-configadmin:8.0.0.Alpha1
      15:18:11,241 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: com.foo.bar-utils:0.0.1
      15:18:11,244 INFO  [org.jboss.osgi.framework] (MSC service thread 1-3) JBOSGI011001: Bundle installed: com.foo.bar-entities:0.0.1
      15:18:11,532 INFO  [org.jboss.weld.deployer] (MSC service thread 1-2) JBAS016002: Processing weld deployment bar-utils.jar
      15:18:11,565 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011011: Starting bundles for start level: 1
      15:18:11,569 INFO  [org.jboss.weld.deployer] (MSC service thread 1-1) JBAS016002: Processing weld deployment bar-entities.jar
      15:18:11,578 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: wildfly-osgi-http:8.0.0.Alpha1
      15:18:11,579 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: wildfly-osgi-jpa:8.0.0.Alpha1
      15:18:11,611 WARN  [org.jboss.weld.deployer] (MSC service thread 1-2) JBAS016016: URL scanner does not understand the URL protocol bundle://com.foo.bar-entities-16-0-0/META-INF/beans.xml, CDI beans will not be scanned
      15:18:11,842 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: org.apache.felix.log:1.0.0
      15:18:12,261 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: jboss-osgi-logging:1.0.0
      15:18:12,310 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: org.apache.felix.configadmin:1.2.8
      15:18:12,335 INFO  [org.jboss.weld.deployer] (MSC service thread 1-1) JBAS016005: Starting Services for CDI deployment: bar-entities.jar
      15:18:12,719 INFO  [org.jboss.weld.deployer] (MSC service thread 1-2) JBAS016005: Starting Services for CDI deployment: bar-utils.jar
      15:18:12,835 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: wildfly-osgi-configadmin:8.0.0.Alpha1
      15:18:12,839 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011002: Bundle started: com.foo.bar-utils:0.0.1
      15:18:12,841 INFO  [org.jboss.osgi.framework] (MSC service thread 1-4) JBOSGI011000: OSGi Framework started
      15:18:12,866 INFO  [org.jboss.weld.Version] (MSC service thread 1-2) WELD-000900 2.0.0 (Final)
      15:18:12,900 INFO  [org.jboss.weld.deployer] (MSC service thread 1-4) JBAS016008: Starting weld service for deployment bar-entities.jar
      15:18:12,904 INFO  [org.jboss.osgi.framework] (MSC service thread 1-1) JBOSGI011002: Bundle started: com.foo.bar-entities:0.0.1
      
      

       

       

      Then I tried to redeploy the bar-entities-dao.jar but I got the same exception as I did before going the OSGI route. What is going on? Do I have to access the EntityManagerFactory in a different way when I have an OSGIfied persistence bundle?

       

      Of course needless to say, I have appropriate producer methods for the EntityManager and its factory in my bar-entities-dao.jar

       

       

      @Named
      @Singleton
      @Startup
      public class EntityManagerFactory implements Serializable {
      
      
                private static final long serialVersionUID = 1L;
      
                @Inject
                private EntityManagerProvider entityManagerProvider;
      
                public EntityManager getEm(){
                          return entityManagerProvider.getEntityManager();
                }
      
                public FullTextEntityManager getFullTextEm(){
                          return entityManagerProvider.getFullTextEntityManager();
                }
      
      
      }
      
      
      
      @Named
      @RequestScoped
      public class EntityManagerProvider {
      
                @PersistenceContext(unitName="bar-unit", type=PersistenceContextType.EXTENDED)
              private EntityManager entityManager;
      
                @Produces
              public EntityManager getEntityManager() {
                  return entityManager;
              }
      
                @Produces
                public FullTextEntityManager getFullTextEntityManager() {
      
                          return Search.getFullTextEntityManager( getEntityManager() );
                }
      
      
      }
      
      
      
      

       

       

      Any pointers would be greatly appreciated. Thanks.

        • 1. Re: Injecting Persistence Unit from OSGI JPA Bundle
          canotech

          Ok I solved my initial problem by changing my EntityManagerProvider class to the following:

           

           

          @Named
          @RequestScoped
          public class EntityManagerProvider {
          
          
                    @Inject
                    EntityManagerFactory emf;
          
                    @Produces
                    public EntityManager getEntityManager() {
                           return emf.getEm();
                    }
          
                    @Produces
                    public FullTextEntityManager getFullTextEntityManager() {
          
                              return Search.getFullTextEntityManager( getEntityManager() );
                    }
          
          
          }
          
          
          But it would still be nice to learn how to do this injection from the JPA OSGI bundle.
          
          • 2. Re: Injecting Persistence Unit from OSGI JPA Bundle
            sfcoy

            Why don't you want to use an EAR file?