Title: Web programming
1Web 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.
2What 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)
3What is so terrible about JSF? (part 1)
- Default model is reliant on JSPs, the heart of
evil. However, this can be replaced (see Hans
Bergstens 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.
4What 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 ones 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.
5What 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.
6What is the GREAT BEAST of Web Programming?
7The GREAT BEAST
is LOGIC in the PRESENTATION LAYER
- 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.
8Web 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 aint gonna happen!
9Web 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 doesnt
actually do a lot! Takes care of dispatch, some
navigation and decoding but has no ideas about
view
10Web 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)
11Web 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.
12The 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.
13RSF/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 JSFs request-scope beans
14IKAT
- A kind of Javanese weaving. Most of the catchy
Java-name gimmicks were taken years ago!
15IKAT
- 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
rsfid. Can easily ensure validating X(HT)ML for
designer by inline internal subset.
16IKAT rendering
- During render time, IKAT template file is paired
up with a component tree, matching template
rsfid 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.
17RSF Component Hierarchy
Looks a little familiar. ?
18rsfid
- 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)
19How 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 rsfid
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
rsfid attribute with matching prefix before
colon.
20IKAT function call resolution
- The resolution of the function call is performed
using an argument matching procedure, which
compares - i) the upcoming rsfid 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.
21IKAT 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.
22MAKE YOUR WEBAPPS
A LOGIC-FREE ZONE
23RSF 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
24RSF Request Cycle
X(HT)ML View Template
Template lookup
View token
ViewParameters
IKAT
GET
Rendered X(HT)ML View
Component Tree (Logic or XML/XSLT)
25How to write an RSF component
- In general you dont 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.
26UIOutputMultiline
- 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)
-
-
27UIOutputMultilineRenderer
- StringList 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 lt value.size() i)
- if (i ! 0)
- pos.print("ltbr/gt")
-
- xmlw.write(value.stringAt(i))
-
- pos.print(close.text)
-
28RSAC 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.
29Use of RSAC within RSF
- Since much of RSFs 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.getWebApplic
ationContext(sc) protected void
service(HttpServletRequest request,
HttpServletResponse response)
wac.getBean(request.getMethod().equals(GET
)? gethandler
posthandler)
30 Summer Lightning
- RSFs 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
31Reflections on Java performance
- Benchmarking of Java primitive operations has led
to interesting conclusions/recommendations
32Results (107 its, P4-1.6Ghz)
33Performance 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.
34FastClass
- 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 45x.
FastClass is indeed VERY FAST. - Spring introspection uses javax.beans and so very
hard to accelerate. RSAC can be easily altered
however.