260 likes | 398 Views
Portable Portlet Development with RSF. Antranig Basman, CARET, University of Cambridge. What is it , Doctor??. Introducing RSF. RSF is a Java web programming framework, with roughly the same scope as Sun’s JSF – it takes care of:. Locating and rendering views
E N D
Portable Portlet Development with RSF Antranig Basman, CARET, University of Cambridge
What is it, Doctor?? Introducing RSF RSF is a Java web programming framework, with roughly the same scope as Sun’s JSF – it takes care of: • Locating and rendering views • Managing server-side and client-side state • Handling and abstracting the request cycle It does NOT take care of: • What lies behind your data model (ORM) Hibernate & co are highly developed solutions to this which RSF aims to facilitate, not replace.
Why (YET) another web framework? • There are now over two dozen open source Java web frameworks out there (many probably moribund/defunct) • Would properly need pretty good reason to create another • RSF grew out of work with JSF and preserves all of its key value points • JSF suffers from numerous architectural, practical and philosophical problems • Also, JSF is not adapted for lifecycles/environments typically found in academic institutional development • long maintenance lifetimes • perpetual reskinning/branding • interface aggregation/flexible delivery engines (accessibility vs. AJAX flashiness, thin/thick clients)
RSF from JSF I • JSF core value points: • JSF is portable1– can target the same code at portlet/servlet environments, • as well as different markup dialects • JSF features a bean line – communication from view layer to model is only via EL expressions, reflectively evaluating value bindings and method bindings 1 *nearly* - after 3 years and despite both being Sun standards, JSF JSR-168 integration is still incomplete (portal modes &c)
RSF from JSF II • JSF core deficits: • Neither JSF inputs nor outputs are any kind of XML (by default crummy taglibs as input, half-assed, Javascript-laden HTML as output) • Does not properly separate logic from presentation (even with Facelets, input “templates” contain iteration and model logic and are NOT safe to give to designers) • Makes heavyweight use of session state, destroys server efficiency, breaks URL idioms and browser forking • Poor testability through global visibility of kitchen sink “FacesContext” object
RSF from JSF III • JSF core deficits II • Lack of support for many core pieces of the browser idiom (bookmarkability, back button, browser forking, POST->GET, GET forms &c &c) • Fragile request lifecycle (“Phase” system) behaves erratically in presence of exceptions, is generally monolithic and uncontrollable • IoC integration is at best awkward (JSF-Spring) • Is simply in general a pain to work with – taglibs are hard to write, framework is highly intrusive, stateful and heavyweight (FacesContext) • Could go on much longer! (see RSF wiki)
Architectural Snapshots #1: JSF Haunted House • Designed on a grand scale • Lots of thought to architecture, ambitious reach • Large, complex • Lots of strange noises and inexplicable phenomena
Quick Recap of RSF Points • The key RSF features are: • Pure (REALLY pure) HTML templating • Zero server state processing • Built ENTIRELY of a set of Spring contexts, rather than merely “integrating” with Spring • Request-scope IoC container, RSAC • RSAC leads to straightforward and slick integration even with extremely peculiar environments (JSR-168, Cocoon, Hibernate, Sakai are all in the bag – IChannel is coming) • Integrations are always only a few hundred LOC • JSF JSR-168 is thousands
RSF compared to JSF • RSF preserves all the “key value points” of JSF • Abstract “component tree” isolates you from view technology • EL bindings system isolates the data model from the view layer • Abstract dispatching procedure isolates you from the hosting environment (Servlets, Portlets, Sakai – IChannel?) • But delivers on all its promises and more • Free of “model” classes coupling you to the framework • “Speak like a native” approach to HTML – anything is possible • Test your UI in the filesystem, full previewability • Output is GUARANTEED valid XML • IoC throughout the framework means application fragility does not increase with size, testability &c.
State in RSF • The key difference for folks coming from JSF is that RSF holds zero server state by default • Not only the component tree, but also the entire client model are thrown away at the end of every request • Server resource are precious, and the “time between requests” for a particular user is very large in server terms – why keep around something you could easily regenerate (your app has its own model)? • A better fit for HTTP which is a stateless protocol. RSF apps are very URL-response, and much more amenable to HTTP tools such as caches, proxies &c
Case Study I : Sakai TaskList App • Part of the Sakai “Programmers’ Cafe” exercise at Sakai Vancouver Conference June 2006 • The simplest app that could be useful • Demonstrates most of the key requirements on a Sakai app • ORM using standard Sakai SessionFactory (as well as other approaches, abstracted behind a DAO interface) • Rendering compliant with Sakai Style Guide • Exposing a Sakai-wide service API • Written in JSF • Easily the most problematic aspect of the whole tool
JSF Tasklist App Structure TaskList.jsp TaskListServiceImpl.java TaskListBean.java TaskListService.java TaskListManager.java DataModel TaskBeanWrapper.java TaskList.java
Thinking • Looking at the TaskListService API in detail, it becomes clear that it only really has value *within* the app • This API was created because it is awkward to deliver enough of the Sakai and other Spring dependencies to a JSF-managed bean • This API and Impl can be destroyed completely in the RSF version • We know that in the RSF version, the view logic in the JSP will be placed into a ViewProducer, TaskListProducer • The ViewProducer is *already* a Spring-configured bean, so the dependencies which used to be delivered to TaskListServiceImpl will be transferred onto TaskListProducer • Since the Producer is normal Java code which has full access to the application state, the “Wrapper” class is also unnecessary. • The presence of the DataModel in what should be the business layer of the app was an unconditional excrescence.
JSF Tasklist App Structure 2 TaskList.jsp TaskListServiceImpl.java TaskListBean.java TaskListService.java TaskListManager.java DataModel TaskBeanWrapper.java TaskList.java
RSF Tasklist App Structure TaskList.html TaskListProducer.java TaskListBean.java TaskListManager.java TaskList.java
It doesn’t stop there • RSF ORM “idiom” rather than “library” • OTP (= “One True Path”) assigns unique EL path to each entity of data model • RSF “EL” is slimmed down so much (only elementary reads/writes permitted) that it is safe to address arbitrarily nasty “POJO” models, even those managed by Hibernate • Abolition of “DAO”s
RSF Tasklist App Structure with OTP TaskList.html TaskListProducer.java TaskListBean.java TaskListManager.java TaskList.java
Result: • A Sakai app free of ANY SAKAI CODE • A Hibernate app free of ANY HIBERNATE CODE • Pure HTML templating makes app effortlessly reskinnable by anyone armed with a copy of Dreamweaver • Portable to any environment (where the functionality is relevant) – could become a JSR-168 app with no code changes • This is impossible with any other framework NB – could have tried this with interfaces, but this tends to create a fragile design – need to anticipate all design points up front, rather than “abstraction on demand” through request-scope IoC. This approach leads to defining an entire “abstraction platform” covering all cases with “kitchen-sink” type interfaces.
Case Study II: Spring MVC “Step by Step” Product sample • Thomas Risberg’s very useful walkthrough of a SpringMVC app • SpringMVC is worthy but modest • Hampered by “Lowest Common Denominator” of existing view technologies • Spring philosophy of “work what what is there already, do not implement” • Is NOT portable (Servlet and Portlet packages are named similarly, but are not interchangeable) http://www.springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step.html
Architectural Snapshots #2: SpringMVC Bungalow • Modest, competent • Works fairly well for everyone • Doesn’t get you very high off the ground (in terms of abstraction)
1. SpringMVC integration • The IKAT renderer from RSF has been ported to SpringMVC • Can be used as “just another SpringMVC rendering technology”, along with Velocity, FreeMarker and JSPs • Creates some duplication (Controllers/Producers), but highly useful for making reskinnable apps • “Step by Step” rewritten with drop-in replacement for JSPs, no other code changed • Resulting app is reskinnable, but still not portable
2. SpringMVC replacement • Entire app rewritten using RSF • Much code disappears, increased level of abstraction • Preserves ALL non-SpringMVC code with no changes • Business model/“manager” • DAOs • Spring Validation • Resulting app *IS* portable to JSR-168, as a result of destroying SpringMVC “Controller” layer • Not only is the Controller unit testable, but the renderer is as well!! First closed-loop UI testing.
RSF and AJAX • Everyone talks about this, so I’d better • Since RSF preserves complete autonomy on the client (*pure* HTML templates), all native client-side AJAX libraries integrate naturally – no need for AJAX “components” in the framework • Lots of success with • Prototype.js • Script.aculo.us • Rico • RSF renderer is markup agnostic, no problem rendering XML for AJAX tables (Rico), HTML fragments for divs (Ajax.Update) or full pages with embedded AJAX calls. • Ask Steve Githens (on the RSF forums)
Acknowledgements The CARET Team Raymond Chan Andrew Thornton Dan Sheppard Ian Boston and John Norman
RSF http://www2.caret.cam.ac.uk/rsfwiki