11 Replies Latest reply on Jan 5, 2010 9:50 AM by gonzalad

    how to disable BijectionInterceptor only

    asookazian

      without using @BypassInterceptors, is there a way to disable BijectionInterceptor at the global (all components), component, or method levels?


      Of course, I'm asking for a solution (config in components.xml, for example) without modifying the source code...


      And of course, this may be a hypothetical question and not used at the global level anyways.  Even if we try to use Component.getInstance("fooComponent") as much as we can to avoid the performance hit of bijection, we still most likely would use @In EntityManager em in most cases...

        • 1. Re: how to disable BijectionInterceptor only
          asookazian

          http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/performance.html#d0e30025


          @Name("foo")
          @Scope(EVENT)
          @BypassInterceptors
          public class Foo
          {
             public String getRowActions()
             {
               // Role-based security check performed inline instead of using @Restrict or other security annotation
               Identity.instance().checkRole("user");
               
               // Inline code to lookup component instead of using @In
               Bar bar = (Bar) Component.getInstance("bar");
             
               String actions;   
               // some code here that does something     
               return actions;
             }
          }



          So when you disable all interceptors via @BypassInterceptors rather than listing them one by one like hypothetical @BypassBijectionInterceptor, for example, or an element list of @BypassInterceptors you end up writing too much code like in class above.  Because all interceptors have been disabled for all methods in this case, we must also programmatically write security check code as well as any transaction code if required (which typically is required in case of a JavaBean as EJB CMT does not apply).


          So the gain in performance is offset by more code to write and maintain...

          • 2. Re: how to disable BijectionInterceptor only
            gonzalad



            without using @BypassInterceptors, is there a way to disable BijectionInterceptor at the global (all components), component, or method levels?



            From what I know only at global level, just list in components.xml all the interceptors you want to be applied, they'll replace the default ones. To know the list of default interceptors, just check seam's xsd (in seam jar).



                 <core:init debug="@debug@">
                      <core:interceptors>
                            <value>org.jboss.seam.transaction.RollbackInterceptor</value>
                      </core:interceptors>
                 </core:init>



            • 3. Re: how to disable BijectionInterceptor only
              gonzalad



              So the gain in performance is offset by more code to write and maintain...

              If you're happy with the performance of your application, there's no point in tuning it (as you said just - a little - more code).
              If you're not happy, on the other hand... BypassInterceptor is one of the ways to tune your application.


              From my experience, Seam performance with JSF is not so good.

              • 4. Re: how to disable BijectionInterceptor only
                kragoth

                From the reading I've done I think it is a little unfair to be pointing the finger at Seam as the performance bottleneck.


                I think a lot of times it comes down to how we write our code.


                Take a look at http://www.jsfcentral.com/articles/speed_up_your_jsf_app_1.html


                In that article it has a lot of very interesting ideas about performance.


                The BijectionInterceptor is not going to be a big hit unless you have got lots of calls from one Seam bean to another to another etc. A lot of times this code can be changed and common code refactored out into a straight java class (not a Seam bean). Sure you may have to pass a few more params to the method, but you wont suffer the minor performance hit that comes with Bijection.


                All that being said, a database hit will take 10 times longer then a complex bijection intercept. Always look at  your queries first before trying to optimise the java code. Java code is fast, and if it's not running fast then it's probably a design issue.



                That being said, I understand that Bijection does take up a considerable amount of time, but generally it comes down to using JSF a bit better so that methods don't get called multiple times in a single render response cycle.

                • 5. Re: how to disable BijectionInterceptor only
                  asookazian

                  Good points.  But consider that in CDI/Weld, injection occurs once and only at bean instantiation time, similar to Spring constructor injection...


                  Seam @Injection is useful in stateful architectures where we have multiple pages (e.g. a wizard) where the latest instance variables are needed in each backing bean.


                  And yes, the article has some very good points regarding rendered attribute in dataTable in particular.

                  • 6. Re: how to disable BijectionInterceptor only
                    gonzalad





                    Take a look at speed up...



                    This is one of the most interesting articles about Seam performance (I've used it a lot, with this one also SeamPerformanceProblemRewardingWorkaround).




                    I think it is a little unfair to be pointing the finger at Seam as the performance bottleneck

                    I know it looks like. I like this framework (mostly all the goodies it provided jsf (GET support, conversation support and exception management most importantly).


                    But, lately, I've needed to tune different Seam apps (JSF + Richfaces), each one developed by different developers.


                    Half of the applications had performance problems even runing with only 1 user.


                    Even after correcting db lookup, there were performance issues. I've needed to look at jsf and RF code and tune it. This kind of performance pbs never happened with traditional MVC applications (the pb there was always db hits or bad sql code).
                    If I need now to check JSF and SQL code, I'll be loosing a lot of time developing applications, and this appears to be the case when using JSF and Seam.


                    So, if half the seam (jsf) applications end up with performance problems, there's really... a pb.


                    Some problems I've found - I need some more time to write them down (I'm putting aside db hits or problems not with jsf / seam / richfaces) :





                    • too much html generated markup (jsf id's are long, also RF components generates a lot of HTML code).

                    • RF filter (will be removed with RF 4).

                    • RF limitToList pb (I've ended using limitToList on all my components).

                    • Seam bijection and interception.

                    • RF component usage (i.e : modalPanel generates too much code, there's no ajax mode), see RF-8210.

                    • RF component usage 2 : developers tend now to do too much ajax interaction when just javascript code should be enough (and I never do ajax validation ! on the positive side, it shows that with RF, ajax is just so easy).

                    • of course immediate and ajaxSingle whenever we can.




                    From my point of view, performance is one of the 2 criticals problems with Seam (the other one being that the framework is quite complicated, one of the causes being too many solutions to do the same thing). I didn't found for the moment a magic solution to resolve those performance pbs - if anyone has it, I would really glad to hear it !


                    I really hope Seam 3 will be enough to improve performance (changing bijection with dynamic proxies is really a good idea).


                    • 7. Re: how to disable BijectionInterceptor only
                      gonzalad

                      Another one :




                      • use c:if vs rendered (in datatable or iterator components in particular) whenever applicable (see build-time-vs-render-time.html to know when c:if usage is applicable.




                      • 8. Re: how to disable BijectionInterceptor only
                        kragoth

                        Arbi Sookazian wrote on Jan 05, 2010 00:49:


                        Good points.  But consider that in CDI/Weld, injection occurs once and only at bean instantiation time, similar to Spring constructor injection...



                        Spring is slightly different in that you are dealing with singletons (almost all the time).


                        I haven't used CDI or Weld, but I find it hard to believe that all injection can possibly happen at instantiation time. How then would you inject an event scoped bean? They don't live for as long as a Session or Conversation scoped bean. Thus your variable would be null upon further accesses to the injected object. (I have no experience in this area at all so I could be way off track :) )


                        I should go do some reading about Weld as I really like the Idea it represents. :)

                        • 9. Re: how to disable BijectionInterceptor only
                          kragoth

                          Gonzalez Adrian wrote on Jan 05, 2010 00:53:


                          Some problems I've found - I need some more time to write them down (I'm putting aside db hits or problems not with jsf / seam / richfaces) :




                          • too much html generated markup (jsf id's are long, also RF components generates a lot of HTML code).

                          • RF filter (will be removed with RF 4).

                          • RF limitToList pb (I've ended using limitToList on all my components).

                          • Seam bijection and interception.

                          • RF component usage (i.e : modalPanel generates too much code, there's no ajax mode), see RF-8210.

                          • RF component usage 2 : developers tend now to do too much ajax interaction when just javascript code should be enough (and I never do ajax validation ! on the positive side, it shows that with RF, ajax is just so easy).

                          • of course immediate and ajaxSingle whenever we can.





                          Interestingly enough only 1 of your points for speeding up an application involves Seam. Generally speaking it is the way JSF is used (and any component libraries that are used with it)


                          I'm not at all trying to say that Seam doesn't have issues, just that I don't believe they are quite as big as some people think they are. So far in our application I have found that the vast majority of our time is spent in database work (percentage wise) then in java code (Spring/Seam/JSF/RF) all combined.


                          We haven't hit the performance review stage yet in our app, but my first point of call will most certainly be the rendered attribute. That will make a much bigger difference then looking at the Bijection interceptor.

                          • 10. Re: how to disable BijectionInterceptor only
                            gonzalad



                            without using @BypassInterceptors, is there a way to disable BijectionInterceptor at the global (all components), component, or method levels?

                            I forgot : BypassInterceptors can also be disabled on a per component basis.
                            Just make sure your Seam component don't include any of the following annotations :




                            • In

                            • Out

                            • DataModel (or and annotations annotated itself with DataBinderClass).

                            • DataModelSelection

                            • RequestParameter



                            If you meet these requirements, BypassInterceptors won't be added to the interceptors list.


                            FYI, an interceptor isn't added to the interceptors list of a component if its isInterceptorEnabled() returns false.
                            In the case of BypassInterceptors :



                               public boolean isInterceptorEnabled()
                               {
                                  return getComponent().needsInjection() || getComponent().needsOutjection();
                               }



                            • 11. Re: how to disable BijectionInterceptor only
                              gonzalad



                              Interestingly enough only 1 of your points for speeding up an application involves Seam.

                              Most Seam users use Richfaces (or Icefaces) / JSF / Seam stack. So, from an end user perspective the trio has performance problems. By the way El has also performance problems.


                              From my test on a real application, when removing the interceptor chain, I've gained 30% performance - this wasn't the number 1 problem, I agree completely, but I'm better gaining the 30% performance than using goodies (@Role, @In, @DataModel) which just happens to reduce 10% of my action code.


                              Please note also that 30% gain was because we never outject variables (performance gain on the interceptor side can be achieved by adding BypassInterceptor or outjecting variables).