10 Replies Latest reply on Sep 13, 2006 5:26 PM by mzeijen

    multi portlet setup

    mzeijen

      This is probably not a reall seam question, but I am going to ask it here anyway ;).

      At my company we are relaunching our website and we will be using portlets (together with a CMS) to implement the dynamic parts). I am searching for a way to get a reall flexible deployment. I mean by this that I want to seperate the three layers, db-layer (entities), business layer (ejbs) and the view layer (multiple portlets implemented with Seam).

      It would look something like this:

      dblayer.ear
       entities.jar
      
      businesslayer.ear
       businesslayer.jar
      
      portlet1.ear
       seamComponents.jar
       portlet1.war
      
      portlet2.ear
       seamComponents.jar
       portlet2.war
      
      


      The portlets all use the same business layer and the same entity layer.
      That is also wy want this to be as flexible as possible. I don't want to deploy all my portlets again if I change something in my businesslayer.

      It is possible to put an EntityManager in the JNDI by setting some properties in the persistence.xml. I wanted to see if this really worked so I made a little test setup (without the seperate businesslayer):

      TestEnt.ear
       TestEntEJB.jar < contains the entities and the persistence.xml
      
      Test.ear
       TestEJB.jar < contains the seam component HelloWorld (HelloWorldAction.class)
      


      HelloWorldAction class:

      @Stateful
      @Name("HelloWorld")
      @Scope(ScopeType.CONVERSATION)
      public class HelloWorldAction implements HelloWorld {
      
       @PersistenceContext(unitName="userDatabase", type=EXTENDED)
       private EntityManager em;
      
       @SuppressWarnings("unchecked")
       public String someAction() {
      
       List<User> users = em.createQuery("from User u order by u.username").getResultList();
      
       return null;
       }
      
       @Remove @Destroy
       public void destroy() {}
      }
      


      The first time I manually deployed the testEnt.ear first and then I deployed the test.ear. To my joy everything worked. The entityManager got injected into the HelloWorldAction class and I could retrieve the users using the query.

      But then I stumpled upon some problems:

      1. If I redeploy the testEnt.ear the following exception gets thrown:

      [ServiceController] Problem starting service jboss.j2ee:ear=Test.ear,jar=TestEJB.jar,name=HelloWorldAction,service=EJB3
      javax.naming.NamingException: Could not bind user transaction for ejb name HelloWorldAction into JNDI under jndiName: /UserTransaction [Root exception is javax.naming.NameAlreadyBoundException]
       at org.jboss.ejb3.EJBContainer.resolveInjectors(EJBContainer.java:631)
       at org.jboss.ejb3.EJBContainer.initializePool(EJBContainer.java:576)
       at org.jboss.ejb3.EJBContainer.start(EJBContainer.java:507)
       at org.jboss.ejb3.SessionContainer.start(SessionContainer.java:82)
       at org.jboss.ejb3.stateful.StatefulContainer.start(StatefulContainer.java:73)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.ejb3.ServiceDelegateWrapper.startService(ServiceDelegateWrapper.java:99)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
       at $Proxy0.start(Unknown Source)
       at org.jboss.system.ServiceController.start(ServiceController.java:417)
       at org.jboss.system.ServiceController.start(ServiceController.java:435)
       at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
       at $Proxy182.start(Unknown Source)
       at org.jboss.ejb3.JmxKernelAbstraction.install(JmxKernelAbstraction.java:82)
       at org.jboss.ejb3.Ejb3Deployment.startPersistenceUnits(Ejb3Deployment.java:626)
       at org.jboss.ejb3.Ejb3Deployment.start(Ejb3Deployment.java:475)
       at org.jboss.ejb3.Ejb3Module.startService(Ejb3Module.java:139)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
       at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:978)
       at $Proxy0.start(Unknown Source)
       at org.jboss.system.ServiceController.start(ServiceController.java:417)
       at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:86)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
       at $Proxy90.start(Unknown Source)
       at org.jboss.ejb3.EJB3Deployer.start(EJB3Deployer.java:449)
       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
       at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
       at org.jboss.mx.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:97)
       at org.jboss.system.InterceptorServiceMBeanSupport.invokeNext(InterceptorServiceMBeanSupport.java:238)
       at org.jboss.ws.server.WebServiceDeployer.start(WebServiceDeployer.java:117)
       at org.jboss.deployment.SubDeployerInterceptorSupport$XMBeanInterceptor.start(SubDeployerInterceptorSupport.java:188)
       at org.jboss.deployment.SubDeployerInterceptor.invoke(SubDeployerInterceptor.java:95)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
       at $Proxy91.start(Unknown Source)
       at org.jboss.deployment.MainDeployer.start(MainDeployer.java:1007)
       at org.jboss.deployment.MainDeployer.start(MainDeployer.java:997)
       at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:808)
       at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:771)
       at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
       at java.lang.reflect.Method.invoke(Method.java:585)
       at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)
       at org.jboss.mx.server.Invocation.dispatch(Invocation.java:94)
       at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:133)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
       at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:142)
       at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
       at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
       at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
       at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:210)
       at $Proxy6.deploy(Unknown Source)
       at org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymentScanner.java:421)
       at org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentScanner.java:610)
       at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.doScan(AbstractDeploymentScanner.java:263)
       at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.loop(AbstractDeploymentScanner.java:274)
       at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.run(AbstractDeploymentScanner.java:225)
      Caused by: javax.naming.NameAlreadyBoundException
       at org.jnp.server.NamingServer.bind(NamingServer.java:144)
       at org.jnp.interfaces.NamingContext.bind(NamingContext.java:566)
       at org.jnp.interfaces.NamingContext.bind(NamingContext.java:531)
       at org.jboss.util.naming.Util.bind(Util.java:102)
       at org.jboss.util.naming.Util.bind(Util.java:89)
       at org.jboss.ejb3.EJBContainer.resolveInjectors(EJBContainer.java:628)
       ... 104 more
      


      The second problem that I have is when I restart the server. The
      test.ejb gets initialized before the testEnt.ear and then the EntityManager isn't in the JNDI yet. This results in trouble offcourse:

      14:24:56,919 ERROR [URLDeploymentScanner] Incomplete Deployment listing:
      
      --- MBeans waiting for other MBeans ---
      ObjectName: jboss.j2ee:ear=Test.ear,jar=TestEJB.jar,name=HelloWorldAction,service=EJB3
       State: NOTYETINSTALLED
       I Depend On:
       persistence.units:unitName=userDatabase
      
      --- MBEANS THAT ARE THE ROOT CAUSE OF THE PROBLEM ---
      ObjectName: persistence.units:unitName=userDatabase
       State: NOTYETINSTALLED
       Depends On Me:
       jboss.j2ee:ear=Test.ear,jar=TestEJB.jar,name=HelloWorldAction,service=EJB3
      


      Does someone know a way to solve both problems?

      I am also questioning myself if my approach is the right one. Does some one have any idea how I can handle this deployment schema the best way?


        • 1. Re: multi portlet setup
          mzeijen

          Has no one any idea? Is it such a strange thing I want?

          • 2. Re: multi portlet setup
            mzeijen

            I found a solution for both problems. Now I deploy my entities in a jar file into the deploy directory. This makes sure that the entities get deployed before the EAR package with the portlet does. I am also using the Seam-managed persistence context to avoid the problem when redeploying the entities.

            I am not quit confident about my second solution. The problem is that I don't know what the difference is between a
            Seam-managed persistence context and a normal (extende) persistence context. Can anyone elaborate on that?

            • 3. Re: multi portlet setup
              mzeijen

              I read that a Seam-managed persistence context returns a manager that is the same for the whole conversation. So that is definatly not the same as a (Extended) persistence context using the @PersistenceContext annotation.

              But how do I get an entity manager that works the same as a normal PersistenceContext or an Extended PersistenceContext?

              • 4. Re: multi portlet setup
                gavin.king

                I don't understand the question.

                • 5. Re: multi portlet setup
                  mzeijen

                  I discovered that it is possible to get an entitityManager or entityManagerFactory over the JNDI. This way it is possible to get entities from a seperate ejb package (not embeded in the EAR file of the Seam application (or in my case the multiple portlets)).

                  In my class where I want to get the enitityManager I have multiple options to retrieve one:

                  1. Use a JNDI lookup to get the entitityManager or the factory
                  2. Use the @Resource annotation
                  3. Use the Seam-managed persistence context (but that only works for a conversation long entityManager)

                  I can't use the normal @PersistenceContext annotation because I get exceptions when I redeploy the ejb package that contains the entities.

                  My problem is that I don't know how to get an Extented EntityManager without using the @PersistenceContext annotiation.

                  You, Gavin, told me in a different topic that it isn't possible to have entities in a seperate ejb. But so far I succeeded pretty well. But because I also know that you are probably right, I would like to know for what implications I am heading for (next to the fact that I can't retrieve an Extended manager). Thx.

                  • 6. Re: multi portlet setup
                    gavin.king

                    You can use an application-managed PC. ie. look up the EMF in JNDI and call createEntityManager(). Don't forget to destroy it when you are done, by calling close.

                    However, I don't know why you would want an EPC for anything other than conversation scope. Usually a very bad idea.

                    • 7. Re: multi portlet setup
                      mzeijen

                      thx for the advice. I am going to advice my colleague that we better keep the entities ejb package within the EAR. Prevents a lot of potential problems.

                      • 8. Re: multi portlet setup
                        mzeijen

                        Oh yeah. Can you give me some reasons why a application EPC is a bad idea? Thx.

                        • 9. Re: multi portlet setup
                          gavin.king

                          Because it will gradually fill up with entities and the memory will never be released unless:

                          (a) you find some way to clear() it from time to time or
                          (b) you know that the data queried into the PC is limited for some other reason

                          • 10. Re: multi portlet setup
                            mzeijen

                            Ok, so the biggest problem is that you need to manage the EPC your self. There by loosing a lot of the power that EJB3 provides and it is very easy to make big mistakes that don't get noticed easy?