1 2 Previous Next 16 Replies Latest reply on Jun 30, 2008 1:29 PM by salaboy21

    started with spring support

    tom.baeyens

      i just committed first spring support.

      it looks ugly, but that is because the PVM environment is not easy to match with the default hibernate support in spring.

      scanning through the docs, the most appropriate base classes to use seemed to me the TransactionTemplate and HibernateDaoSupport

      in test/java/org.jbpm.pvm.spring.SpringTest you can see the direction that i want to go:

      EnvironmentFactory environmentFactory = new SpringEnvironmentFactory("org/jbpm/pvm/spring/spring.beans.xml");
      
       CommandService commandService = environmentFactory.get(CommandService.class);
      
       commandService.execute(new Command<Object>() {
       public Object execute(Environment environment) throws Exception {
       assertNotNull(environment);
       Session session = environment.get(Session.class);
       assertNotNull(environment);
       assertNotNull(session);
       assertTrue(session.isOpen());
       assertSame(session, environment.get(Session.class));
       return null;
       }
       });
      


      it shows that i can execute a pvm command in a hibernate transaction and get the hibernate session. this is one possible way on how to make it work, i think. but maybe (hopefully) there are cleaner and simpler ways on how to accomplish this.

      the spring classes are in org.jbpm.pvm.internal.spring

      i didn't yet check how to integrate the rollback.

      Are there easier ways in spring to map spring to our command service if we want to do one transaction per command ?

        • 1. Re: started with spring support
          jbarrez

          Tom,

          I've checked your spring.beans.xml.
          What you're doing there is directly injecting a transactionTemplate. This means that you will need to be very careful not to make mistakes since you're doing programmatic transactions.

          Since you're using Spring here, it is much easier to use the declarative transaction configuration available in Spring. For example by creating a Transactional Proxy bean that wrap your service. Or, even more cool: use AOP to interecpt calls to the service and start/use a new/existing transaction. The benefit is that all of this is declarative and less error-prone.

          see http://static.springframework.org/spring/docs/2.0.x/reference/transaction.html#transaction-declarative

          Another advantage is that the service is Spring independent (no dependency on Spring classes).

          If you need some examples of declarative Spring transactions, let me know, I've done quite some projects with it.

          • 2. Re: started with spring support
            tom.baeyens

            Thanks for looking.

            Keep in mind that the main goal is to run a process persistently in a spring environment. Activity implementations should be able to fetch a hibernate session from the current environment.

            I would guess that the less dependencies we can do it, the better. So if we can do it without AOP magic. It might be less cool, but more practical, no ?

            But I'm spring newbie. So this is just the first way on how i managed to map

            Environment.getCurrent().get(Session.class)


            to a spring environment. If your solution also solves this, please elaborate a bit more.

            • 3. Re: started with spring support
              dlopezleon

              Tom, we are following this topic and looking for a different approach for the spring configuration support.
              As we point in other post abut this, we are trying to make everything as pojo as possible (APAS :P), and keeping the spring container totally out of the configuration classes.
              So our main goal is to get just the SpringEnvironmentFactory referencing the SpringApplicationContext from which retrieve the SpringEnvironment (indeed is more a PojoEnvironment maybe we can change this name). We tried to follow the behavior and conventions used in the DefaultEnvironment so we have different contexts in our environment. This contexts are not your WireContexts but a new context just being capable to set objects and get them by class or by name. At first time we tried to get all as simple as we could. Out test is

               EnvironmentFactory environmentFactory = SpringEnvironmentFactory.parseResource("org/jbpm/pvm/spring/spring-beans.xml");
              
               Environment environment = environmentFactory.openEnvironment();
               try {
               Session hibernateSessionFromString = (Session) environment.get("session");
               Session hibernateSessionFromClass = environment.get(Session.class);
               assertNotNull(hibernateSessionFromString);
               assertNotNull(hibernateSessionFromClass);
               assertSame(hibernateSessionFromString, hibernateSessionFromClass);
               } finally {
               environment.close();
               }
              

              At the moment we are having some trouble managing the tx on the session (if you like this approach we can ask jbarrez for help on this topic). I attach the spring-beans.xml so you can see how it is going and have a better view of our approach.
               ...
               <bean id="environment" class="org.jbpm.pvm.internal.env.SpringEnvironment">
               <property name="contexts">
               <map>
               <entry key="environment-block" value-ref="environmentContext"/>
               </map>
               </property>
               </bean>
              
               <bean id="environmentContext" class="org.jbpm.pvm.env.PersistenceSimpleContext">
               <property name="sessionFactory" ref="hibernateSessionFactory"/>
               </bean>
              
               <bean id="hibernateSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
               <property name="configLocation">
               <value>classpath:hibernate.cfg.xml</value>
               </property>
               </bean>
               <!-- tx stuff-->
               <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
               <property name="sessionFactory" ref="hibernateSessionFactory"/>
               </bean>
              
               <bean name="methodsTransactionAttributes" class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
               <property name="properties">
               <props>
               <prop key="get*">PROPAGATION_REQUIRED</prop>
               </props>
               </property>
               </bean>
              
               <bean id="nameMatchTxInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
               <property name="transactionManager">
               <ref bean="transactionManager"/>
               </property>
               <property name="transactionAttributeSource">
               <ref bean="methodsTransactionAttributes"/>
               </property>
               </bean>
              
               <bean id="autoTxProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
               <property name="proxyTargetClass" value="true"/>
               <property name="interceptorNames">
               <list>
               <idref bean="nameMatchTxInterceptor"/>
               </list>
               </property>
               <property name="beanNames">
               <list>
               <value>environment</value>
               </list>
               </property>
               </bean>
               ...
              

              We have to add spring-aop and aopalliance.
              So, what do you think about this?

              ps=sorry if this is so much technical for the forum, if you want i can send you the code

              • 4. Re: started with spring support
                salaboy21

                We think that this approach will be more simple and more spring like, the best way to clarify our approach is viewing and analizing our code.. let us know how can do this?
                Thanks

                • 5. Re: started with spring support
                  camunda

                  Just as a remark, even if I don't make big friends here ;-)

                  Why there is going too much effort in the Spring integration? If the reaseon is, to see how flexible the configuration mechanism of the PVM is and to avoid some mistakes in that area, ok, it makes sense.

                  If it is for the sake of Spring I don't understand it at all. Spring is a proprietary framework and if there is the need for a Spring integration it should be done by the spring guys. In my opinion it is enough to support Java EE environments out of the box...

                  But thats just my two cents...
                  Cheers
                  Bernd

                  • 6. Re: started with spring support
                    tom.baeyens

                     

                    "dlopezleon" wrote:
                    ps=sorry if this is so much technical for the forum, if you want i can send you the code


                    On the contrary. This is GREAT input ! Thanks. I'll have a look at it as soon as i get back to the office on thursday.

                    • 7. Re: started with spring support
                      tom.baeyens

                      salaboy21, dlopezleon,

                      first, i have organised the spring proposals in test packages. only when a design is adopted, we'll move that one into the codebase.

                      the code you committed, I moved into the org.jbpm.pvm.spring2 package

                      I added an assert that shows one of the problems in your proposal. Namely the session isn't closed.

                      there are indeed a couple of problems with how you have configured the spring support.

                      i have created a 3rd proposal. Basically this makes all the singleton beans available though the environment factory. And the environment context that only exposes the prototype beans. I have added a cache to the environment context so that beans are cached for the lifetime of the environment.

                      This is a solution that I think does what we need. I'm going to investigate now if the caching can be done more cleanly by plugging in an environment scope into the application context. i'll do that in the package org.jbpm.pvm.spring4

                      • 8. Re: started with spring support
                        jbarrez

                        I'll try to take a look at it somewhere next week.

                        I have a certification exam very soon, so currently all my time is going that way.


                        Bernd: The reason why I'd like Spring support is because Spring is the de facto standard (at least for the customers I have) for building EE apps.
                        If we want to make sure that jBPM is adopted, we should make the usage with Spring easy. I think it's not up to jBPM to say to Spring that it should be supported. At least not at this point in time.

                        • 9. Re: started with spring support
                          salaboy21

                          Hi Tom,, I just commited again the Spring2 Approach.. seeing your Spring3 Approach we think that we can make a Spring4 approach that behave in the way that you want.. following the Pojo Oriented way that is showed in Spring2 Approach..


                          • 10. Re: started with spring support
                            camunda

                             

                            Bernd: The reason why I'd like Spring support is because Spring is the de facto standard (at least for the customers I have) for building EE apps.
                            If we want to make sure that jBPM is adopted, we should make the usage with Spring easy. I think it's not up to jBPM to say to Spring that it should be supported. At least not at this point in time.


                            Okay, seems you have different experiences. I see less Spring apps these days or even big projects refactoring Spring OUT of the projects... And I think the problem with spring is described in your sentence, it is the "de facto standard for EE apps". What the hell? There is a real standard in that area, why using some proprietary framework instead? I don't get it...

                            But okay, completly different discussion. Don't want to hijack this thread for it ;-) Overall I think Spring is big enough so it is worth supporting it. I just don't like that effort has to be spend in supporting a proprietary framework, where a usable standard is available instead...

                            But I will be quiet about htis issue from now on :-)

                            Cheers
                            Bernd

                            • 11. Re: started with spring support
                              tom.baeyens

                               

                              "salaboy21" wrote:
                              Hi Tom,, I just commited again the Spring2 Approach.. seeing your Spring3 Approach we think that we can make a Spring4 approach that behave in the way that you want.. following the Pojo Oriented way that is showed in Spring2 Approach..


                              i moved the spring2 proposal classes to test. please keep all proposals in the test sources only.

                              with your Pojo Oriented way, i think that you're mixing up the binding layer with the actual objects that need to be configurable.

                              environment and environment factory are part of the layer that is the binding between pvm and spring. they don't really need to be pojo based in order to get a good spring integration.

                              it's in fact all the objects that are used from inside the process execution and deployment that need to be made easily spring creatable (read pojo) for as far as they are not already.

                              i'm pretty happy with the current spring integration in src/java/org/jbpm/pvm/internal/spring If you see a problem with that approach, let me know. Otherwise, I think we should take that integration as the basis.

                              You can see which objects are needed by uncommenting the remainder of the test in test/java/org/jbpm/pvm/spring/SpringTest

                              /* TODO translate the DeployerManager to a data structure that is
                               * easy to wire up with spring
                               ProcessService processService = environmentFactory.get(ProcessService.class);
                              
                               ProcessDefinition processDefinition = ProcessFactory.build("basic")
                               .node("a").initial().behaviour(WaitState.class)
                               .transition().to("b")
                               .node("b").behaviour(WaitState.class)
                               .transition().to("c")
                               .node("c").behaviour(AutomaticActivity.class)
                               .transition().to("d")
                               .node("d").behaviour(AutomaticActivity.class)
                               .transition().to("e")
                               .node("e").behaviour(WaitState.class)
                               .done();
                              
                               processService.deploy(processDefinition);
                              
                               Execution execution = processService.startExecution("basic", "one");
                              
                               assertEquals("a", execution.getNode().getName());
                              
                               execution = processService.signalExecution("basic", "one");
                              
                               assertEquals("b", execution.getNode().getName());
                              
                               execution = processService.signalExecution("basic", "one");
                              
                               assertEquals("e", execution.getNode().getName());
                               */
                              


                              When you uncomment that, you'll get errors when the process execution engine will try to get something from the environment. Each time, that object needs to be configured. The first one is the DeployerManager.

                              If you want to help out with completing the spring integration, those are the steps that I think you should be done: make the DeployerManager configurable from spring.

                              • 12. Re: started with spring support
                                dlopezleon

                                 

                                "tom.baeyens@jboss.com" wrote:
                                with your Pojo Oriented way, i think that you're mixing up the binding layer with the actual objects that need to be configurable.
                                environment and environment factory are part of the layer that is the binding between pvm and spring. they don't really need to be pojo based in order to get a good spring integration.

                                Hi Tom, thank you for clarifying that. I still think that everything should be 'spring creatable' so in that way you can build all the environment in the way you want and letting the specific 'how to get it' concerns encapsulated into the factories. I think our mistake was to think the environment inside the process execution layer. Anyway, your solution has a better balance between encapsulation and ease of development/testing.
                                "tom.baeyens@jboss.com" wrote:

                                If you want to help out with completing the spring integration, those are the steps that I think you should be done: make the DeployerManager configurable from spring.

                                Cool, that's our next step.
                                As soon we have something we commit that.

                                Now I have to run to work.

                                • 13. Re: started with spring support
                                  dlopezleon

                                  Hi Tom,
                                  We uncommented the last piece of code of your test and we could make it run.
                                  Few questions about.
                                  We have to push the SpringEnvironment into the stack of Environment calling Environment#pushEnvironment. This make the test works but we still don't get the need of this stack and its behavior.
                                  Beside that there is a reference from AutomaticActivity to Recorder which is in the test folder, probably this should be moved to main tree.
                                  Regards.

                                  ps= have you checked my contributor agreement?

                                  • 14. Re: started with spring support
                                    salaboy21

                                    Tom, with Diego have one question about the following code:

                                     public boolean has(String key) {
                                     return applicationContext.isPrototype(key);
                                     }
                                    


                                    Why this deployerManager needs to be prototype in SpringEnvironmentContext?

                                    To make things work, we must set the bean with scope=prototype. But we don't really understand why...

                                    1 2 Previous Next