web programming the rendering layer is clearly an important stress point. for example, to appear as...

34
Web programming The rendering layer is clearly an important stress point. For example, to appear as a “1st-class” Sakai tool, a lot of control is required over the HTML level (CSS class, Javascript, etc.) Initially a JSF implementation produced (with much pain) – however, much of JSF thrown away in the process. Considering variety of uses cases implies costs of JSF-like solution for skinning (RenderKits + JSF Components, JSPs) would be EXTREME CSS can only reskin so far (cannot reorder elements), and cannot “remap” – e.g. Sakai CSS classes cannot be exchanged for another set.

Upload: ginger-moore

Post on 30-Dec-2015

213 views

Category:

Documents


1 download

TRANSCRIPT

Web programming• The rendering layer is clearly an important stress point.• For example, to appear as a “1st-class” Sakai tool, a lot

of control is required over the HTML level (CSS class, Javascript, etc.)

• Initially a JSF implementation produced (with much pain) – however, much of JSF thrown away in the process.

• Considering variety of uses cases implies costs of JSF-like solution for skinning (RenderKits + JSF Components, JSPs) would be EXTREME

• CSS can only reskin so far (cannot reorder elements), and cannot “remap” – e.g. Sakai CSS classes cannot be exchanged for another set.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

What has JSF got right?

• One of the first web systems with a “clean” bean model (no external dependencies)

• With JSF-Spring integration, can be extended from request to application scope.

• Abstract component tree helps to separate logic from content.

• Clear 7-stage pipeline for handling of request logic.

• (Relatively) minimal internal interfaces allow replacement of key functionality (ViewHandler, StateHandler)

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

What is so terrible about JSF? (part 1)

• Default model is reliant on JSPs, the heart of evil. However, this can be replaced (see Hans Bergsten’s “ClassViewHandler”, basis of first FlowTalk system.

• “Jackboot” event processing pipeline leads to events happening at “awkward” times, with little control. Many extremely obscure timing problems.

• It is too complex and heavyweight. UIComponent is 750 lines, UIComponentBase is 2200, and you probably need to know them well to develop effectively. Many extraneous dependencies.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

What is so terrible about JSF? (part 2)

• Very poor, restrictive HTTP semantics - no GET/POST redirect, browser “back” button or browser forking are impossible. Too much session reliance.

• Reskinning is VERY HARD. Creating a new JSF component is a lot of work, and difficult to preview one’s results.

• JSF component tree is rather inefficient and unnecessary. Perennial problem of “where to keep it”, either on client or server, both involving various penalties.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

What is so terrible about JSF? (part 3)

• Default JSF rendering REQUIRES Javascript to operate. Already a philosophical problem, BUT

• As a result, JSF is VERY designer-unfriendly. Web designers like to move around HTML in, e.g. Dreamweaver, and apply Javascript and test it at will. JSF/JSP destroys this model.

• NB – web designers are experts in their field, and in general also cost less per man-hour/results than programmers! Their design model should be respected.

What is the GREAT BEAST of Web Programming?

The GREAT BEAST

• Fosters an amorphous, intractable design on a project – no clear point of control, and multi-way, circular dependencies

• Confuses designers who have the power to cause devastating effects, and have to tread extremely carefully through reams of incomprehensible tags/code

• Is GENERALLY BAD.

— is LOGIC in the PRESENTATION LAYER

Web Technologies compared – part 1• On these grounds, JSP is the ultimate evil, allowing

entirely arbitrary Java code to appear at the presentation level.

• JSPs appear(ed) attractive owing to near-magic performance – once compiled, pile out output at close to the maximum possible rate.

• However, JSP and still worse JSF/JSP applications are intractable, not least because the presentation files are “not anything” – neither XML or even HTML of any kind, nor are they Java.

• Special tools required, that somehow magically manage to be optimised for both designers and coders.

• It ain’t gonna happen!

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Web Technologies compared – part 2• There are more web technologies in the world than

almost anything else. (Why do you think?)• Almost all try to improve matters in some respects

by introducing some from of MVC separation. Survey a few:

• Struts/Tiles: Claims view-neutral, but really a JSP shop (loads of taglibs). Also intrudes on controller layer with Actions.

• Spring MVC: Actually IS view-neutral, but doesn’t actually do a lot! Takes care of dispatch, some navigation and decoding but has no ideas about view

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Web Technologies compared – part 3 (Tapestry)

• Tapestry – interesting in that view layer IS valid HTML. However still contains logic!!

• Full OGNL allowable, library of 12 “parameter binding prefixes” including HiveMind.

• However, main problem is at the other end – highly intrusive at the Java level with mandatory interfaces and base classes – “everything is an IComponent”

• Spring/beans integration not planned until “Tapestry 5.0” (if ever)

Web Technologies compared – part 4 (Velocity)

• Velocity is admirably simple and fast – however actually TOO simple to serve as the entire UI of a webapp!

• Understands nothing about document and tag structure, nor about HTTP submission model.

• And despite being so simple STILL depends on logic embedded in the template – macro directives #if, looping with #for.

• One of the few “safe” technologies, but continues to fall into the error of trying to be a “one-stop-shop” for specifying render behaviour.

The Holy Grail

• Technology based on pure HTML view templates, for complete pages that can be rapidly shoved around by designers or even end clients.

• Pure backing beans model, easy to integrate with other bean-friendly technologies (Hibernate data model, Spring webapp + IDEs)

• Extremely rapid rendering, simple execution model.

• Easy to write new components.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

RSF/IKAT

• RSF is a programming model with roughly the same scope as JSF (in fact derived from all the bits of it that were hacked off)

• Content rendering model is codenamed “IKAT” – largely functionally independent (in particular can be used to render pages without any active web context)

• Incorporates “Request Scope Application Context” (RSAC) which bridges Spring to provide equivalent of JSF’s request-scope beans

IKAT

• A kind of Javanese weaving. Most of the catchy Java-name gimmicks were taken years ago!

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

IKAT• IKAT is extremely fast.• Parse 10k template file in 5ms (almost no need to

cache structures)• Render 10k document in 2.5ms (cost dominated

largely by writing bytes – avoiding use of Java.io.Writer saved 25%).

• Like Tapestry, the template looks EXACTLY like a rendered page, but system is much simpler.

• Only addition to DOM is ONE special attribute – rsf:id. Can easily ensure validating X(HT)ML for designer by inline internal subset.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

IKAT rendering

• During render time, IKAT template file is “paired up” with a component tree, matching template rsf:id attribute to component ID.

• Unlike JSF, component tree exists only momentarily, between construction by producer (main app) logic and rendering – THROWN AWAY between request cycles.

• RSF UIComponent – 50 lines of code. 4 fields and one method.

• IKAT remains logic-free, while alternating (weaving) between template-driven order and component-driven order to render desired view.

RSF Component Hierarchy

Looks a little familiar…. ?

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

rsf:id• The only template attribute added to the target

render (XML) language.• Only three interpretations:

– simple string denotes a (leaf) component peer, e.g. UIOutput

– string containing colon denotes a container peer (UIContainer), which is a function call/branch point

– string containing equals sign denotes target of static rewrite rule (e.g. URL rewrite or other runtime binding)

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

How could this possibly work?

• The “interesting” step involves how the template file gets structurally rewritten, while remaining a pure X(HT)ML file free of logic.

• The “colon” type tag specifies a “branch point” within the template.

• “Normal template processing” involves scanning through template in order, pairing up each rsf:id with a leaf UIComponent with a matching ID in the current scope. V.fast.

• On hitting a “branch point” with a colon ID, renderer performs a “function call” within the template, which may resolve to ANY instance of an rsf:id attribute with matching prefix before colon.

IKAT function call resolution• The resolution of the function call is performed using an “argument

matching” procedure, which compares– i) the upcoming rsf:id attributes on children of the prospective function call

target in the template, and– ii) the ID values on UIComponent children in the component tree, representing

“producer demand on template”

• Resolution is performed first in current container scope, then at global scope across template file (ultimately across multiple template files for true modular rendering architecture with reusable components)

• Highest penalty is for “missing” components in template, second-level penalty for “extra components”

• After function call, normal scanning resumes at the target template tag, “returning” once an XML tag is encountered with lower nesting level.

• Function call is also fast, and lookup decisions are candidates for caching.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

IKAT consequences• Making large scale alterations in UI skinning (not just

reordering/reorganising components, but completely suppressing/restoring them is just a matter of editing HTML files.

• E.g. Sakai skin (will, once a competent HTML designer looks at it!) provide a “first-class” Sakai look-and-feel with correct CSS styles/JS &c, while at the same time the same codebase can serve entirely different UI requirements.

• All this while ensuring that pages are rendered ONLY ONCE – no rewrites required at consumer end, can begin copying bytes to client the moment request resolves.

• Designers can experiment with complex Javascript (AJAX) interfaces in situ.

MAKE YOUR WEBAPPS

A LOGIC-FREE ZONE

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

RSF architecture

• Larger-scale RSF architecture provides mapping between component contents and Actions

• Very similar to JSF – components have value bindings and method bindings which are expressed in EL with the same syntax: #{beanname.methodname}

• TargettedMessage system provides reliable delivery of validation/error messages across POST/GET redirect cycle (vide FacesMessage)

• Unique tokens (GUIDs) allocated to each request, allowing robust and correct behaviour in the face of i) multiple submissions, ii) back button, iii) browser forking

RSF Request Cycle

ViewParameters

GETIKAT

Component Tree (Logic or XML/XSLT)

Rendered X(HT)ML View

X(HT)ML View Template

Template lookup

View token

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

How to write an RSF component

• In general you don’t need to! • Most cases can be taken care of by just writing

some HTML. • If you really need to, extremely simple.

– Component class itself just holds “dumb data” (5 lines)– Renderer simply chucks Strings from template to

output stream (10 lines)– Since RSF is entirely Spring-based, much less

bureaucracy in registering component (RenderKit? &c)

• Unlike JSF components, RSF component is only concerned with data binding function, not with rendering.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

UIOutputMultiline

public class UIOutputMultiline extends UIBound {

public StringList value; public UIOutputMultiline(UIContainer parent, String ID, String binding, StringList value) {

this.ID = ID; this.valuebinding = binding; this.value = value; parent.addComponent(this); }}

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

UIOutputMultilineRendererStringList value = ((UIOutputMultiline) torendero).value; if (value == null) { RenderUtil.dumpTillLump(lumps, lumpindex + 1, close.lumpindex + 1, pos); } else { RenderUtil.dumpTillLump(lumps, lumpindex + 1, endopen.lumpindex + 1, pos); for (int i = 0; i < value.size(); ++ i) { if (i != 0) { pos.print("<br/>"); } xmlw.write(value.stringAt(i)); } pos.print(close.text); }

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

RSAC – Request Scope Application Context

All of RSF and its bean model is defined in pure Spring – no awkward static configuration and files to manage.

Request-scope beans have become more powerful than JSF beans, since they may contain other request-scope bean dependencies.

This has a rather interesting architectural effect, which is not yet fully understood, but seems extremely powerful.

Same “offloading” of dependency management that Spring brought to webapps happens in miniature during a request, removing much uninteresting logic and enabling static checking of application structure by Eclipse IDE.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Use of RSAC within RSF

Since much of RSF’s logic itself is implemented using RSAC, there have been startling increases in cleanliness.

The ideal final evolution of a Servlet: ??

public class ReasonableServlet extends HttpServlet { private WebApplicationContext wac;

public void init(ServletConfig config) { ServletContext sc = config.getServletContext(); wac = WebApplicationContextUtils.getWebApplicationContext(sc);}

protected void service(HttpServletRequest request, HttpServletResponse response) { wac.getBean(request.getMethod().equals(“GET”)? “gethandler” : “posthandler”); }}

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Summer Lightning• RSF’s RSAC was initially implemented very simply

using a Spring GenericApplicationContext, but performance was found to be too dreadful to be conceivable for a web request cycle (sometimes over 1s for a getBean()

• Since then, core Spring functionality has been reimplemented in a “fast and lean” clone (retaining Spring code for reading config files)

• Available in RSAC:– Autowire dependencies back to RSAC– FactoryBeans– List and Set properties– BeanPostProcessors

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Reflections on Java performance

• Benchmarking of Java primitive operations has led to interesting conclusions/recommendations:

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Results (107 its, P4-1.6Ghz)

JDK 1.4.2 JDK 1.5

Method call 8ns 5ns

Method call with catch block 5ns 6ns

ThreadLocal.get() 60ns 40ns

Synchronized method 200ns! 200ns

Reflective invocation 700ns! 530ns

Constructor (1 member) 100ns 25ns

Object.clone (1 member) 900ns!! 850ns

Constructor (6 members) 110ns 45ns

Object.clone (6 members) 1.1μs!! 900ns

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

Performance Commentary• JDK 1.5 is considerably faster than 1.4 across the

board (~20%), ESPECIALLY for object construction.• Reflection performance is AWFUL for all JDKs,

running to be nearly 100x slower than direct equivalent.

• Synchronized blocks (even uncontended) are really pretty bad, no matter what they tell you.

• Since synchronized has NOT improved in 1.5, sync block has gone from equivalent of 2 object constructions to 8.

• Object.clone is the real shocker. Consistently about 1.6x the cost of a reflective operation.

27/09/2005, Sakai Developers’ Meeting Antranig Basman, CARET, University of Cambridge

FastClass• Part of the CGLib bytecode engineering library on

sourceforge– (CGLib is used by Hibernate, AOP among other high-profile

libraries)

• Provides direct equivalents for java.reflect.Method, java.reflect.Constructor &c

• FastClass.invokeMethod() tested at 35ns on JDK 1.4.2

• I.e. down from 100x performance penalty to 4~5x. FastClass is indeed VERY FAST.

• Spring introspection uses javax.beans and so very hard to accelerate. RSAC can be easily altered however.