1 2 3 Previous Next 35 Replies Latest reply on May 14, 2010 7:17 AM by nickarls

    JSR 299 vs @ManagedBean in JSF 2.0?

    sboscarine

      Perhaps this will be answered in the upcoming Weld documentation, but I was wondering what are some of the reasons someone writing a JSF 2.0 application would want to use Weld/CDI/JSR299 over the new @ManagedBean annotations in JSF 2.0?


      What are some of the more significant advantages of JSR 299 vs a @ManagedBean that a typical JSF user is likely to encounter?


      Are there situations where @ManagedBean is preferred?


      Thanks,

      Steven

        • 1. Re: JSR 299 vs @ManagedBean in JSF 2.0?
          nickarls

          Well, with CDI-beans you can have interceptors/decorators/factories/custom contexts & extensions etc. The concepts will probably be align more closely in Java EE 7. You could use plain @ManagedBean if you want to reuse some stuff at the lowest common level(?)

          • 2. Re: JSR 299 vs @ManagedBean in JSF 2.0?
            gavin.king

            Oh gawd, the JSF managed bean stuff is pretty sucky. The 299 spec provides you with:



            • typesafe dependency injection

            • producer methods

            • proper integration with EJB

            • conversation context

            • interceptors and decorators

            • events

            • stereotypes

            • modularity

            • an SPI for integrating portable extensions



            But that doesn't really capture the difference. 299 is just much more solid and better thought-out system.

            • 3. Re: JSR 299 vs @ManagedBean in JSF 2.0?
              sboscarine

              The ulterior motive was to get the discussion started as much for other readers as myself.



              299 is just much more solid and better thought-out system.

              I personally believe you, but as an early adopter and thus evangelist, I would like to give better rationale than These really smart guys at RedHat said so.


              Hopefully in the near future, the original question will look silly.  At this exact point in time, there's not much documentation for either Weld or JSF 2 beyond their formal specs (I couldn't even google the JavaDocs for @ManagedProperty today...found it from Andy Schwartz's blog, though), so I was hoping for some ideas of how to answer that question. 


              When telling other developers about Weld, I've been asked that question a few times. 


              I imagine many developers are my shoes.  We need to justify to those who pay for our time why writing our next app in Weld is a better idea than JSF2 alone, JEE5, Spring-IOC and WebFlow, etc.  I often joke that if you throw enough acronyms at someone with enough confidence, they'll just trust that you know what's going on and let you handle making the technical decisions.  However, I'd like to be able to provide some easy to understand examples as to why this technology is so useful. 


              If I could find compelling points and moderately compelling means of explaining them, I'd even like to blog about them. 


              A few of the points you gave made immediate sense. 


              Typesafe DI makes sense.  I didn't realize JSF2 wasn't typesafe.  I just assumed the @ManagedProperty worked the same as @Resource in Spring. 


              Conversation scope makes sense and is familiar from WebFlow and Seam.


              Some of the other points seem cool, but I am trying to read through them and figure out which ones will make the most impact on the conventional JSF user.  I am not sure how many of those features I could utilize or would even want to. 


              Reading through the older WebBeans documentation, I found a list of dozens of features, many of which are very new and unfamiliar.  I am trying to figure out which ones I should focus on learning. 


              • 4. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                gavin.king

                Well, instead of talking about features, I can describe things in terms of broad goals:



                • Integration: JSF managed beans are their own world, with their own particular programming model, and are not integrated with the other Java EE container services. Weld lets you write beans that take advantage of the whole Java EE environment, and use them directly within JSF (or other web framework).

                • Contextual state management: JSF managed beans do have a contextual lifecycle model, but Weld provides a much more complete state management system with things like conversation scope and support for third-party extensions.

                • Loose coupling: Weld provides a bunch of interlocking features (producer methods, alternatives, events, interceptors, decorators) that make it very easy to design and implement loosely coupled components. It's much easier to avoid spaghetti code.

                • Strong typing: The Java compiler is able to check for many errors in code that uses Weld, and the tooling we will deliver soon is able to check many more problems. In Weld, you'll find out about a lot more errors without needing to execute your code.

                • Extensibility: Weld provides very strong support for portable extensions written to the JSR-299 metamodel SPI. This means that frameworks like Seam3 will be able to provide all kinds of additional functionality without resorting to the kinds of hacks that were needed in a plain JSF environment.


                • 5. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                  gavin.king

                  i.e. all of those are things (including, at least arguably, Integration) that are relevant to an ordinary JSF user.



                  • Integration: JSF applications need to access transactional services like persistence, messaging, etc. This is much, much easier using Weld.

                  • Contextual state management: JSF applications need conversations. They just do.

                  • Loose coupling: all code should aim to minimize coupling between collaborating components. This stuff is relevant to everyone.

                  • Strong typing: again, this is relevant to all development in Java.

                  • Extensibility: it saves time to be able to re-use someone else's solution to a common problem.

                  • 6. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                    nickarls

                    Gavin King wrote on Oct 23, 2009 05:23:


                    • Strong typing: again, this is relevant to all development in Java.





                    Now if we only could get strong typing between the UI and the beans but a text file is a text file and I guess at some point we just have to rely on good tooling to catch typos etc...

                    • 7. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                      hmo

                      Gavin, can you please explain more about modularity in Weld?

                      • 8. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                        gavin.king

                        Modularity means the ability to deploy collaborating beans in different modules, and have one module specify which other modules contain its dependencies. In Java EE, modules include library jars, EJB jars and wars. You use the Java EE metadata to specify dependencies. Weld is aware of the module dependency structure of the EE application and uses this knowledge when resolving dependencies.


                        Now, Java EE modularity is definitely not as well-designed or capable as OSGi or the new Java module system. A future rev of JSR-299 will address Java modules when that stuff is available in SE. And it's easy to see how the approach taken in JSR-299 for Java EE modules could be extended to OSGi.

                        • 9. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                          gavin.king

                          I should clarify that the goal is not that Weld itself provides modularity. It's that Weld is aware of the module dependency structure and uses that to resolve cross-module dependencies.

                          • 10. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                            gavin.king

                            To round out the list of design goals, I should mention a major goal of JSR-299, which separates CDI from essentially all other solutions in the field:



                            • Configuration without tedious XML: Weld lets you change the configuration of your system at deployment time, without requiring that you write tedious lists of beans in XML or Java-based DSL, as required by other DI solutions.



                            @Alternative stereotypes. This really sets us apart.

                            • 11. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                              sboscarine

                              Gavin King wrote on Oct 23, 2009 16:46:



                              • Configuration without tedious XML: Weld lets you change the configuration of your system at deployment time, without requiring that you write tedious lists of beans in XML or Java-based DSL, as required by other DI solutions.



                              @Alternative stereotypes. This really sets us apart.


                              In fairness, Spring 2.5 doesn't require XML beyond specifying the package.   I haven't declared a bean in XML for years thanks to @Resource, @Component, and @Autowired.


                              Are you guys planning on writing anything comparing JSR299 to Spring IOC? 


                              I'm very interested in learning more about @Alternative.  Is there any info on it's use out beyond the spec?  It looks promising from the spec, but I didn't find it in the WebBeans documents or samples yet. 


                              Is the main use case for @Alternative TestNG/JUnit tests?


                              • 12. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                                gavin.king

                                In fairness, Spring 2.5 doesn't require XML beyond specifying the package. I haven't declared a bean in XML for years thanks to @Resource, @Component, and @Autowired.

                                And what about beans which are available in some deployments of the system and not others? How do you handles those without specifying each, explicitly, in XML? I was not under the impression that Spring had anything like @Alternative stereotypes.



                                Are you guys planning on writing anything comparing JSR299 to Spring IOC?

                                No, I'm not going to waste time trying to justify the existing of Weld. Instead, it's up to the Spring folks to justify why their steaming pile of proprietary legacy code that's bean accumulating cruft for six years, without ever going through a proper ground-up redesign like Hibernate did with JPA1 or like Seam is doing now, is still better than what is now provided as part of the Java standards. :-)



                                I'm very interested in learning more about @Alternative. Is there any info on it's use out beyond the spec? It looks promising from the spec, but I didn't find it in the WebBeans documents or samples yet.

                                It's more or less the thing that used to be called deployment types, but simplified to remove the precedence stuff.



                                Is the main use case for @Alternative TestNG/JUnit tests?

                                That's one usecase. An @Alternative stereotype represents a deployment scenario: testing, staging, production, etc.

                                • 13. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                                  sboscarine

                                  Gavin King wrote on Oct 23, 2009 18:43:


                                  And what about beans which are available in some deployments of the system and not others?


                                  Short answer:  JNDI...I switch the initialization parameters and keep the Java implementations the same.


                                  Since you called me out on it, I'll be more truthful and concede that, neglecting non-IOC framework boilerplate (such as MVC and SWF), I have about 20-100 lines of XML in each major project I've worked on that is nothing but String declarations in the test/resources folder and JNDI links in the main/resources.  I included an example:



                                  For TestNG, we choose to declare a String.

                                  src/main/resources/spring/myapp.xml:


                                  <bean id="smsURL" class="org.springframework.jndi.JndiObjectFactoryBean">
                                       <property name="jndiName" value="java:comp/env/myproject/smsURL" />
                                  </bean>



                                  For dev, staging, and production, we use the identical WAR and just change the values in the globabl environment entires in Tomcat's server.xml

                                  src/test/resources/spring/myapp.xml:


                                  <bean id="smsURL" class="java.lang.String">
                                       <constructor-arg value="http://localhost:8080/mock/spring/sms-test" />
                                  </bean>




                                  SMSClient.java is an example of a JNDI consumer:


                                  private final String baseURL;
                                  
                                  @Autowired
                                  public SMSClient(@Qualifier("smsURL") String baseURL) {
                                       super();
                                       this.baseURL = baseURL;
                                  }



                                  A class like SMSClient is always imported using:




                                  @Resource
                                  private SMSClient smsClient;
                                  




                                  At every shop I've worked in the last 5 years, there has been a requirement that wars are identical for each server.  For me, personally, I have never encountered a situation in which Java implementations vary from server to server. 


                                  I can see implementations changing between TestNG and your container if you like to mock your objects.  I am not a big believer in mock objects and none of my employers or coworkers have endorsed that strategy. 


                                  I worked briefly in 2 shops that required dogmatic JUnit tests in which your component had to mock all components beneath it and execute in isolation in JUnit.  It was a horrible waste of time and money and left the code much more unstable as mock objects weren't kept in sync with the implementations.  Of course just because they failed doesn't mean it's a doomed strategy. :)


                                  Mocking heavyweight resources like external web services can be very useful, but we almost never mock persistence or service layers for our tests.  When we mock web services, we actually create a mock WAR representing the webservice and change the URL via JNDI.  We don't mock DBs because we prefer to catch DB constraint violations in TestNG and not selenium.  As a DB veteran, I've encountered many errors, mostly related to constraints and indexes, which would be tolerated in one DB (HSQL) , but not in another (Oracle or MySQL). 


                                  I find maintaining TestNG test that are technically integration tests and not dogmatic unit tests is much more economical and practical.  Of course, just because mock objects aren't my preference doesn't mean they shouldn't be used.  It's just my opinion.


                                  I can obviously see situations where the Java implementation would change when you're a shop deploying for customers that use different DB platforms.  Most of my experience has been writing webapps that only support one DB platform. 


                                  • 14. Re: JSR 299 vs @ManagedBean in JSF 2.0?
                                    gavin.king

                                    Short answer: JNDI...I switch the initialization parameters and keep the Java implementations the same.

                                    yew, I hate it already :-)



                                    Since you called me out on it, I'll be more truthful and concede that, neglecting non-IOC framework boilerplate (such as MVC and SWF), I have about 20-100 lines of XML in each major project I've worked on that is nothing but String declarations in the test/resources folder and JNDI links in the main/resources.

                                    Right, so I counting 100 lines of XML as verbose. Worse, this stuff is non-typesafe.



                                    At every shop I've worked in the last 5 years, there has been a requirement that wars are identical for each server. For me, personally, I have never encountered a situation in which Java implementations vary from server to server.

                                    I think this is probably typical. But fans of Spring make a huge amount of noise about the supposed easy configurablity of their beans between different deployments. I never precisely understood why they wanted to do so much configuration, and I always thought that Spring XML was an amazingly verbose way to do it, but the fact remains that for some people this is important. I think we have a great approach to this in 299.



                                    I find maintaining TestNG test that are technically integration tests and not dogmatic unit tests is much more economical and practical. Of course, just because mock objects aren't my preference doesn't mean they shouldn't be used. It's just my opinion.

                                    Actually, I think there are great technical reasons why dogmatic unit tests are a waste of time. They don't test the any requirement of the system as understood by the user. Instead, they test some detail of a certain implementation. Worst of all, they make refactoring more difficult, not less, since refactoring of the code will always require rewriting of the dogmatic unit tests. I do not understand why this obvious fact is not better appreciated in the industry.

                                    1 2 3 Previous Next