You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by bu...@apache.org on 2013/08/11 21:20:53 UTC

svn commit: r874228 - in /websites/production/tapestry/content: cache/main.pageCache configuration.html session-storage.html

Author: buildbot
Date: Sun Aug 11 19:20:52 2013
New Revision: 874228

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/configuration.html
    websites/production/tapestry/content/session-storage.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/tapestry/content/configuration.html
==============================================================================
--- websites/production/tapestry/content/configuration.html (original)
+++ websites/production/tapestry/content/configuration.html Sun Aug 11 19:20:52 2013
@@ -34,9 +34,9 @@
 </div>
 
 <div id="top">
-<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em">
+<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><p>
 <span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
+</p><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
   <input type="text" name="q">
   <input type="submit" value="Search">
 </form>
@@ -62,15 +62,15 @@
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
-                         <a shape="rect" href="ioc-cookbook-service-configurations.html">IoC cookbook - Service Configurations</a>
+                         <a shape="rect" href="tapestry-ioc-configuration.html">Tapestry IoC Configuration</a>
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
-                         <a shape="rect" href="tapestry-ioc-configuration.html">Tapestry IoC Configuration</a>
+                         <a shape="rect" href="symbols.html">Symbols</a>
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
-                         <a shape="rect" href="symbols.html">Symbols</a>
+                         <a shape="rect" href="ioc-cookbook-service-configurations.html">IoC cookbook - Service Configurations</a>
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
@@ -89,33 +89,33 @@
 
 <p><b>Contents</b></p>
 <div>
-<ul><li><a shape="rect" href="#Configuration-Changestoweb.xml">Changes to web.xml</a></li><li><a shape="rect" href="#Configuration-YourApplication%27sModuleClass">Your Application's Module Class</a></li><li><a shape="rect" href="#Configuration-ConfigurationSymbolNames">Configuration Symbol Names</a></li><ul><li><a shape="rect" href="#Configuration-tapestry.appcatalog">tapestry.app-catalog</a></li><li><a shape="rect" href="#Configuration-tapestry.applicationversion">tapestry.application-version</a></li><li><a shape="rect" href="#Configuration-tapestry.applicationfolder">tapestry.application-folder</a></li><li><a shape="rect" href="#Configuration-tapestry.asseturlfullyqualified">tapestry.asset-url-fully-qualified</a></li><li><a shape="rect" href="#Configuration-tapestry.assetpathprefix">tapestry.asset-path-prefix</a></li><li><a shape="rect" href="#Configuration-tapestry.blackbirdenabled">tapestry.blackbird-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.charset">tape
 stry.charset</a></li><li><a shape="rect" href="#Configuration-tapestry.combinescripts">tapestry.combine-scripts</a></li><li><a shape="rect" href="#Configuration-tapestry.compatibility.unknowncomponentidcheck...">tapestry.compatibility.unknown-component-id-check-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.componentrendertracingenabled">tapestry.component-render-tracing-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.compresswhitespace">tapestry.compress-whitespace</a></li><li><a shape="rect" href="#Configuration-tapestry.defaultcookiemaxage">tapestry.default-cookie-max-age</a></li><li><a shape="rect" href="#Configuration-tapestry.defaultstylesheet">tapestry.default-stylesheet</a></li><li><a shape="rect" href="#Configuration-tapestry.exceptionreportpage">tapestry.exception-report-page</a></li><li><a shape="rect" href="#Configuration-tapestry.executionmode">tapestry.execution-mode</a></li><li><a shape="rect" href="#Configuration-tapestry.filechec
 kinterval">tapestry.file-check-interval</a></li><li><a shape="rect" href="#Configuration-tapestry.filecheckupdatetimeout">tapestry.file-check-update-timeout</a></li><li><a shape="rect" href="#Configuration-tapestry.forceabsoluteuris">tapestry.force-absolute-uris</a></li><li><a shape="rect" href="#Configuration-tapestry.gzipcompressionenabled">tapestry.gzip-compression-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.hmacpassphrase">tapestry.hmac-passphrase</a></li><li><a shape="rect" href="#Configuration-tapestry.mingzipsize">tapestry.min-gzip-size</a></li><li><a shape="rect" href="#Configuration-tapestry.omitgeneratormeta">tapestry.omit-generator-meta</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.activewindow">tapestry.page-pool.active-window</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepoolenabled">tapestry.page-pool-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.hardlimit">tapestry.page-pool.hard-l
 imit</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.softlimit">tapestry.page-pool.soft-limit</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.softwait">tapestry.page-pool.soft-wait</a></li><li><a shape="rect" href="#Configuration-tapestry.productionmode">tapestry.production-mode</a></li><li><a shape="rect" href="#Configuration-tapestry.secureenabled">tapestry.secure-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.securepage">tapestry.secure-page</a></li><li><a shape="rect" href="#Configuration-tapestry.servicereloadingenabled">tapestry.service-reloading-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.scriptaculous">tapestry.scriptaculous</a></li><li><a shape="rect" href="#Configuration-tapestry.startpagename">tapestry.start-page-name</a></li><li><a shape="rect" href="#Configuration-tapestry.supportedlocales">tapestry.supported-locales</a></li><li><a shape="rect" href="#Configuration-tapestry.suppressredirectfr
 omactionrequests">tapestry.suppress-redirect-from-action-requests</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.corepoolsize">tapestry.thread-pool.core-pool-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.maxpoolsize">tapestry.thread-pool.max-pool-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.queuesize">tapestry.thread-pool.queue-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.keepalive">tapestry.thread-pool.keep-alive</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpoolenabled">tapestry.thread-pool-enabled</a></li></ul><li><a shape="rect" href="#Configuration-SettingComponentParameterDefaults">Setting Component Parameter Defaults</a></li><li><a shape="rect" href="#Configuration-ConfiguringIgnoredPaths">Configuring Ignored Paths</a></li><li><a shape="rect" href="#Configuration-ConfiguringContentTypeMapping">Configuring Content Type Mapping</a></li><li><a shape="rect
 " href="#Configuration-SettingExecutionModes">Setting Execution Modes</a></li><li><a shape="rect" href="#Configuration-SegregatingApplicationsIntoFolders">Segregating Applications Into Folders</a></li></ul></div>
+<ul><li><a shape="rect" href="#Configuration-Changestoweb.xml">Changes to web.xml</a></li><li><a shape="rect" href="#Configuration-YourApplication%27sModuleClass">Your Application's Module Class</a></li><li><a shape="rect" href="#Configuration-ConfigurationSymbolNames">Configuration Symbol Names</a></li><ul><li><a shape="rect" href="#Configuration-tapestry.appcatalog">tapestry.app-catalog</a></li><li><a shape="rect" href="#Configuration-tapestry.applicationversion">tapestry.application-version</a></li><li><a shape="rect" href="#Configuration-tapestry.applicationfolder">tapestry.application-folder</a></li><li><a shape="rect" href="#Configuration-tapestry.asseturlfullyqualified">tapestry.asset-url-fully-qualified</a></li><li><a shape="rect" href="#Configuration-tapestry.assetpathprefix">tapestry.asset-path-prefix</a></li><li><a shape="rect" href="#Configuration-tapestry.blackbirdenabled">tapestry.blackbird-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.charset">tape
 stry.charset</a></li><li><a shape="rect" href="#Configuration-tapestry.combinescripts">tapestry.combine-scripts</a></li><li><a shape="rect" href="#Configuration-tapestry.compatibility.unknowncomponentidcheck...">tapestry.compatibility.unknown-component-id-check-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.componentrendertracingenabled">tapestry.component-render-tracing-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.compresswhitespace">tapestry.compress-whitespace</a></li><li><a shape="rect" href="#Configuration-tapestry.defaultcookiemaxage">tapestry.default-cookie-max-age</a></li><li><a shape="rect" href="#Configuration-tapestry.defaultstylesheet">tapestry.default-stylesheet</a></li><li><a shape="rect" href="#Configuration-tapestry.exceptionreportpage">tapestry.exception-report-page</a></li><li><a shape="rect" href="#Configuration-tapestry.executionmode">tapestry.execution-mode</a></li><li><a shape="rect" href="#Configuration-tapestry.filechec
 kinterval">tapestry.file-check-interval</a></li><li><a shape="rect" href="#Configuration-tapestry.filecheckupdatetimeout">tapestry.file-check-update-timeout</a></li><li><a shape="rect" href="#Configuration-tapestry.forceabsoluteuris">tapestry.force-absolute-uris</a></li><li><a shape="rect" href="#Configuration-tapestry.gzipcompressionenabled">tapestry.gzip-compression-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.hmacpassphrase">tapestry.hmac-passphrase</a></li><li><a shape="rect" href="#Configuration-tapestry.mingzipsize">tapestry.min-gzip-size</a></li><li><a shape="rect" href="#Configuration-tapestry.omitgeneratormeta">tapestry.omit-generator-meta</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.activewindow">tapestry.page-pool.active-window</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepoolenabled">tapestry.page-pool-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.hardlimit">tapestry.page-pool.hard-l
 imit</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.softlimit">tapestry.page-pool.soft-limit</a></li><li><a shape="rect" href="#Configuration-tapestry.pagepool.softwait">tapestry.page-pool.soft-wait</a></li><li><a shape="rect" href="#Configuration-tapestry.productionmode">tapestry.production-mode</a></li><li><a shape="rect" href="#Configuration-tapestry.secureenabled">tapestry.secure-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.securepage">tapestry.secure-page</a></li><li><a shape="rect" href="#Configuration-tapestry.servicereloadingenabled">tapestry.service-reloading-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.scriptaculous">tapestry.scriptaculous</a></li><li><a shape="rect" href="#Configuration-tapestry.sessionlockingenabled">tapestry.session-locking-enabled</a></li><li><a shape="rect" href="#Configuration-tapestry.startpagename">tapestry.start-page-name</a></li><li><a shape="rect" href="#Configuration-tapestry.support
 edlocales">tapestry.supported-locales</a></li><li><a shape="rect" href="#Configuration-tapestry.suppressredirectfromactionrequests">tapestry.suppress-redirect-from-action-requests</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.corepoolsize">tapestry.thread-pool.core-pool-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.maxpoolsize">tapestry.thread-pool.max-pool-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.queuesize">tapestry.thread-pool.queue-size</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpool.keepalive">tapestry.thread-pool.keep-alive</a></li><li><a shape="rect" href="#Configuration-tapestry.threadpoolenabled">tapestry.thread-pool-enabled</a></li></ul><li><a shape="rect" href="#Configuration-SettingComponentParameterDefaults">Setting Component Parameter Defaults</a></li><li><a shape="rect" href="#Configuration-ConfiguringIgnoredPaths">Configuring Ignored Paths</a></li><li><a shape="rec
 t" href="#Configuration-ConfiguringContentTypeMapping">Configuring Content Type Mapping</a></li><li><a shape="rect" href="#Configuration-SettingExecutionModes">Setting Execution Modes</a></li><li><a shape="rect" href="#Configuration-SegregatingApplicationsIntoFolders">Segregating Applications Into Folders</a></li></ul></div>
 
 <h2><a shape="rect" name="Configuration-Changestoweb.xml"></a>Changes to web.xml</h2>
 
 <p>Tapestry applications are configured almost entirely using Java, not XML. However, a small but necessary amount of configuration occurs inside the servlet deployment descriptor, WEB-INF/web.xml. Most of the configuration is boilerplate, nearly the same for all applications.</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-xml">
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[
 &lt;!DOCTYPE web-app
-      PUBLIC <span class="code-quote">"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"</span>
-      <span class="code-quote">"http://java.sun.com/dtd/web-app_2_3.dtd"</span>&gt;
-<span class="code-tag">&lt;web-app&gt;</span>
-    <span class="code-tag">&lt;display-name&gt;</span>My Tapestry Application<span class="code-tag">&lt;/display-name&gt;</span>
-    <span class="code-tag">&lt;context-param&gt;</span>
-        <span class="code-tag">&lt;param-name&gt;</span>tapestry.app-package<span class="code-tag">&lt;/param-name&gt;</span>
-        <span class="code-tag">&lt;param-value&gt;</span>org.example.myapp<span class="code-tag">&lt;/param-value&gt;</span>
-    <span class="code-tag">&lt;/context-param&gt;</span>
-    <span class="code-tag">&lt;filter&gt;</span>
-        <span class="code-tag">&lt;filter-name&gt;</span>app<span class="code-tag">&lt;/filter-name&gt;</span>
-        <span class="code-tag">&lt;filter-class&gt;</span>org.apache.tapestry5.TapestryFilter<span class="code-tag">&lt;/filter-class&gt;</span>
-    <span class="code-tag">&lt;/filter&gt;</span>
-    <span class="code-tag">&lt;filter-mapping&gt;</span>
-        <span class="code-tag">&lt;filter-name&gt;</span>app<span class="code-tag">&lt;/filter-name&gt;</span>
-        <span class="code-tag">&lt;url-pattern&gt;</span>/*<span class="code-tag">&lt;/url-pattern&gt;</span>
-    <span class="code-tag">&lt;/filter-mapping&gt;</span>
-<span class="code-tag">&lt;/web-app&gt;</span>
-</pre>
+      PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+      "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
+&lt;web-app&gt;
+    &lt;display-name&gt;My Tapestry Application&lt;/display-name&gt;
+    &lt;context-param&gt;
+        &lt;param-name&gt;tapestry.app-package&lt;/param-name&gt;
+        &lt;param-value&gt;org.example.myapp&lt;/param-value&gt;
+    &lt;/context-param&gt;
+    &lt;filter&gt;
+        &lt;filter-name&gt;app&lt;/filter-name&gt;
+        &lt;filter-class&gt;org.apache.tapestry5.TapestryFilter&lt;/filter-class&gt;
+    &lt;/filter&gt;
+    &lt;filter-mapping&gt;
+        &lt;filter-name&gt;app&lt;/filter-name&gt;
+        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
+    &lt;/filter-mapping&gt;
+&lt;/web-app&gt;
+]]></script>
 </div></div>
 
 <div class="navmenu" style="float:right; width:30%; background:#eee; margin:3px; padding:3px"><p><font color="#539126"><b>Tapestry Requests vs. Container Requests</b></font></p>
@@ -141,16 +141,16 @@
 <p>Your application module class (usually AppModule.java) will typically override some of Tapestry's default, or "factory", symbols, by contributing overrides to the ApplicationDefaults service configuration. For example:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>AppModule.java</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class AppModule
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class AppModule
 {
-  <span class="code-keyword">public</span> <span class="code-keyword">static</span> void contributeApplicationDefaults(MappedConfiguration&lt;<span class="code-object">String</span>,<span class="code-object">String</span>&gt; configuration)
+  public static void contributeApplicationDefaults(MappedConfiguration&lt;String,String&gt; configuration)
   {
-    configuration.add(SymbolConstants.SUPPORTED_LOCALES, <span class="code-quote">"en,fr,de"</span>);
-    configuration.add(SymbolConstants.FILE_CHECK_INTERVAL, <span class="code-quote">"10 m"</span>);
+    configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,fr,de");
+    configuration.add(SymbolConstants.FILE_CHECK_INTERVAL, "10 m");
   }
 }
-</pre>
+]]></script>
 </div></div>
 
 <h2><a shape="rect" name="Configuration-ConfigurationSymbolNames"></a>Configuration Symbol Names</h2>
@@ -374,7 +374,7 @@ re-download them on subsequent pages).  
 <div class="panelMacro"><table class="infoMacro"><colgroup span="1"><col span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1" valign="top"><img align="middle" src="/images/confluence/information.gif" width="16" height="16" alt="" border="0"></td><td colspan="1" rowspan="1"><b>Added in 5.2</b><br clear="none"></td></tr></table></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"></div>
 
-<p>If true (the default), the Tapestry IoC will attempt to reload service implementations when they change. This only applies to classes that Tapestry IoC instantiates itself, and have a known service interface (the container creates a proxy that, internally, can reload the implementation). Service reloading only works when the underlying class files are on the filesystem ... it is intended for development, not an option at deployment.</p>
+<p>If true (the default), then Tapestry IoC will attempt to reload service implementations when they change. This only applies to classes that Tapestry IoC instantiates itself, and have a known service interface (the container creates a proxy that, internally, can reload the implementation). Service reloading only works when the underlying class files are on the filesystem ... it is intended for development, not an option at deployment.</p>
 
 <p>This must be specified as a JVM system property.</p>
 
@@ -382,6 +382,17 @@ re-download them on subsequent pages).  
 
 <p>The path to the embedded copy of <a shape="rect" class="external-link" href="http://script.aculo.us/" >script.aculo.us</a> packaged with Tapestry. This value may be overridden to use a different version of the script.aculo.us library. See <a shape="rect" href="javascript.html" title="JavaScript">JavaScript</a> for the default version.</p>
 
+<h3><a shape="rect" name="Configuration-tapestry.sessionlockingenabled"></a>tapestry.session-locking-enabled</h3>
+
+
+
+<div class="panelMacro"><table class="infoMacro"><colgroup span="1"><col span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1" valign="top"><img align="middle" src="/images/confluence/information.gif" width="16" height="16" alt="" border="0"></td><td colspan="1" rowspan="1"><b>Added in 5.4</b><br clear="none"></td></tr></table></div>
+<div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"></div>
+
+<p>If true (the default), then Tapestry will use a lock when reading/updating HttpSession attributes, to avoid simultaneous access by multiple threads when using AJAX. See <a shape="rect" class="external-link" href="https://issues.apache.org/jira/browse/TAP5-2049">TAP5-2049</a>. Set to false to deactivate the session locking logic.</p>
+
+<p>Prior to version 5.4 session locking was not performed.</p>
+
 <h3><a shape="rect" name="Configuration-tapestry.startpagename"></a>tapestry.start-page-name</h3>
 
 <p>The logical name of the start page, the page that is rendered for the <em>root URL</em>. This is normally "start". This functionality is vestigial: it has been superseded by the use of Index pages.</p>
@@ -439,9 +450,9 @@ re-download them on subsequent pages).  
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;"><p> Some components, notably Grid, Pallete and Zone, have default parameter values specified in terms of symbols. This means you can use these symbols to modify the defaults for all instances of such components in your application. For example, you can set the default rows per page for all Grid instances by adding this to the <tt>contributeApplicationDefaults</tt> method in your application's module class (typically AppModule.java):</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-configuration.add(ComponentParameterConstants.GRID_ROWS_PER_PAGE, <span class="code-quote">"15"</span>);
-</pre>
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+configuration.add(ComponentParameterConstants.GRID_ROWS_PER_PAGE, "15");
+]]></script>
 </div></div>
 </div>
 
@@ -460,12 +471,12 @@ configuration.add(ComponentParameterCons
 <p>You contribution would look like:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-  <span class="code-keyword">public</span> <span class="code-keyword">static</span> void contributeIgnoredPathsFilter(Configuration&lt;<span class="code-object">String</span>&gt; configuration)
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+  public static void contributeIgnoredPathsFilter(Configuration&lt;String&gt; configuration)
   {
-    configuration.add(<span class="code-quote">"/dwr/.*"</span>);
+    configuration.add("/dwr/.*");
   }
-</pre>
+]]></script>
 </div></div>
 
 <p>The regular expression matches any path that begins with "/dwr/".</p>
@@ -488,49 +499,49 @@ configuration.add(ComponentParameterCons
 <p>1. Add the parameter to your JVM command line:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
 -Dtapestry.execution-mode=DevelopmentMode jetty:run
-</pre>
+]]></script>
 </div></div>
 
 <p>2. Add the parameter to the Jetty plugin:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>pom.xml</b></div><div class="codeContent panelContent">
-<pre class="code-xml">
-<span class="code-tag">&lt;plugin&gt;</span>
-    <span class="code-tag">&lt;groupId&gt;</span>org.mortbay.jetty<span class="code-tag">&lt;/groupId&gt;</span>
-    <span class="code-tag">&lt;artifactId&gt;</span>maven-jetty-plugin<span class="code-tag">&lt;/artifactId&gt;</span>
-    <span class="code-tag">&lt;version&gt;</span>6.1.16<span class="code-tag">&lt;/version&gt;</span>
-    <span class="code-tag">&lt;configuration&gt;</span>
-        <span class="code-tag">&lt;requestLog implementation=<span class="code-quote">"org.mortbay.jetty.NCSARequestLog"</span>&gt;</span>
-            <span class="code-tag">&lt;append&gt;</span>true<span class="code-tag">&lt;/append&gt;</span>
-        <span class="code-tag">&lt;/requestLog&gt;</span>
-        <span class="code-tag">&lt;systemProperties&gt;</span>
-	    <span class="code-tag">&lt;systemProperty&gt;</span>
-	        <span class="code-tag">&lt;name&gt;</span>tapestry.execution-mode<span class="code-tag">&lt;/name&gt;</span>
-	        <span class="code-tag">&lt;value&gt;</span>DevelopmentMode<span class="code-tag">&lt;/value&gt;</span>
-	    <span class="code-tag">&lt;/systemProperty&gt;</span>
-        <span class="code-tag">&lt;/systemProperties&gt;</span>
-    <span class="code-tag">&lt;/configuration&gt;</span>
-<span class="code-tag">&lt;/plugin&gt;</span>
-</pre>
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[
+&lt;plugin&gt;
+    &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
+    &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
+    &lt;version&gt;6.1.16&lt;/version&gt;
+    &lt;configuration&gt;
+        &lt;requestLog implementation="org.mortbay.jetty.NCSARequestLog"&gt;
+            &lt;append&gt;true&lt;/append&gt;
+        &lt;/requestLog&gt;
+        &lt;systemProperties&gt;
+	    &lt;systemProperty&gt;
+	        &lt;name&gt;tapestry.execution-mode&lt;/name&gt;
+	        &lt;value&gt;DevelopmentMode&lt;/value&gt;
+	    &lt;/systemProperty&gt;
+        &lt;/systemProperties&gt;
+    &lt;/configuration&gt;
+&lt;/plugin&gt;
+]]></script>
 </div></div>
 
 <p>3. Add the parameter to the Surfire plugin for your test:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>pom.xml</b></div><div class="codeContent panelContent">
-<pre class="code-xml">
-<span class="code-tag">&lt;plugin&gt;</span>
-    <span class="code-tag">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="code-tag">&lt;/groupId&gt;</span>
-    <span class="code-tag">&lt;artifactId&gt;</span>maven-surefire-plugin<span class="code-tag">&lt;/artifactId&gt;</span>
-    <span class="code-tag">&lt;version&gt;</span>2.8.1<span class="code-tag">&lt;/version&gt;</span>
-    <span class="code-tag">&lt;configuration&gt;</span>
-       <span class="code-tag">&lt;systemPropertyVariables&gt;</span>
-         <span class="code-tag">&lt;tapestry.execution-mode&gt;</span>DevelopmentMode<span class="code-tag">&lt;/tapestry.execution-mode&gt;</span>
-       <span class="code-tag">&lt;/systemPropertyVariables&gt;</span>
-    <span class="code-tag">&lt;/configuration&gt;</span>
-<span class="code-tag">&lt;/plugin&gt;</span>
-</pre>
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[
+&lt;plugin&gt;
+    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+    &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
+    &lt;version&gt;2.8.1&lt;/version&gt;
+    &lt;configuration&gt;
+       &lt;systemPropertyVariables&gt;
+         &lt;tapestry.execution-mode&gt;DevelopmentMode&lt;/tapestry.execution-mode&gt;
+       &lt;/systemPropertyVariables&gt;
+    &lt;/configuration&gt;
+&lt;/plugin&gt;
+]]></script>
 </div></div>
 
 <p>For each mode declared in your JVM System Property, TapestryFilter checks for a parameter in your web.xml, named tapestry.TheModeName-modules, with TheModeName being the name of the desired mode. Its value will be a comma-separated list of modules.</p>
@@ -540,45 +551,45 @@ configuration.add(ComponentParameterCons
 <p>The example below defines two differents execution modes in your web.xml file: production (the default value) and DevelopmentMode. For each mode, we list the modules we want to load. If we use JVM System property declared in the example above, the DevelopmentModeModule module will be loaded.</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>web.xml</b></div><div class="codeContent panelContent">
-<pre class="code-xml">
-<span class="code-tag">&lt;context-param&gt;</span>
-    <span class="code-tag">&lt;param-name&gt;</span>tapestry.production-modules<span class="code-tag">&lt;/param-name&gt;</span>
-    <span class="code-tag">&lt;param-value&gt;</span>org.apache.tapestry.appli.services.ProductionModeModule<span class="code-tag">&lt;/param-value&gt;</span>
-<span class="code-tag">&lt;/context-param&gt;</span>
-<span class="code-tag">&lt;context-param&gt;</span>
-    <span class="code-tag">&lt;param-name&gt;</span>tapestry.DevelopmentMode-modules<span class="code-tag">&lt;/param-name&gt;</span>
-    <span class="code-tag">&lt;param-value&gt;</span>org.apache.tapestry.appli.services.DevelopmentModeModule<span class="code-tag">&lt;/param-value&gt;</span>
-<span class="code-tag">&lt;/context-param&gt;</span>
-</pre>
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[
+&lt;context-param&gt;
+    &lt;param-name&gt;tapestry.production-modules&lt;/param-name&gt;
+    &lt;param-value&gt;org.apache.tapestry.appli.services.ProductionModeModule&lt;/param-value&gt;
+&lt;/context-param&gt;
+&lt;context-param&gt;
+    &lt;param-name&gt;tapestry.DevelopmentMode-modules&lt;/param-name&gt;
+    &lt;param-value&gt;org.apache.tapestry.appli.services.DevelopmentModeModule&lt;/param-value&gt;
+&lt;/context-param&gt;
+]]></script>
 </div></div>
 
 <p>Tapestry will load modules in the order that they are declared. For example, if we run the following command line:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
 -Dtapestry.execution-mode=DevelopmentMode,DevelopmentMode2 jetty:run
-</pre>
+]]></script>
 </div></div>
 
 <p>and then for each modes we have two modules:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>web.xml</b></div><div class="codeContent panelContent">
-<pre class="code-xml">
-<span class="code-tag">&lt;context-param&gt;</span>
-      <span class="code-tag">&lt;param-name&gt;</span>tapestry.DevelopmentMode-modules<span class="code-tag">&lt;/param-name&gt;</span>
-      <span class="code-tag">&lt;param-value&gt;</span>
+<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[
+&lt;context-param&gt;
+      &lt;param-name&gt;tapestry.DevelopmentMode-modules&lt;/param-name&gt;
+      &lt;param-value&gt;
           org.apache.tapestry.appli.services.DevelopmentMode1Module1,
           org.apache.tapestry.appli.services.DevelopmentMode1Module2
-      <span class="code-tag">&lt;/param-value&gt;</span>
-<span class="code-tag">&lt;/context-param&gt;</span>
-<span class="code-tag">&lt;context-param&gt;</span>
-      <span class="code-tag">&lt;param-name&gt;</span>tapestry.DevelopmentMode2-modules<span class="code-tag">&lt;/param-name&gt;</span>
-      <span class="code-tag">&lt;param-value&gt;</span>
+      &lt;/param-value&gt;
+&lt;/context-param&gt;
+&lt;context-param&gt;
+      &lt;param-name&gt;tapestry.DevelopmentMode2-modules&lt;/param-name&gt;
+      &lt;param-value&gt;
           org.apache.tapestry.appli.services.DevelopmentMode2Module1,
           org.apache.tapestry.appli.services.DevelopmentMode2Module2
-      <span class="code-tag">&lt;/param-value&gt;</span>
-<span class="code-tag">&lt;/context-param&gt;</span>
-</pre>
+      &lt;/param-value&gt;
+&lt;/context-param&gt;
+]]></script>
 </div></div>
 
 <p>then Tapestry will load modules in the order: DevelopmentMode1Module1, DevelopmentMode1Module2, DevelopmentMode2Module1 and DevelopmentMode2Module2</p>
@@ -602,28 +613,28 @@ configuration.add(ComponentParameterCons
 <p>So, if you wanted to run the Tapestry application inside folder <tt>t5app</tt>, you would modify your <tt>web.xml</tt> indicate the use of the folder:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
   &lt;filter-mapping&gt;
     &lt;filter-name&gt;app&lt;/filter-name&gt;
     &lt;url-pattern&gt;/t5app/*&lt;/url-pattern&gt;
   &lt;/filter-mapping&gt;
-</pre>
+]]></script>
 </div></div>
 
 <p>... and in your AppModule, you would inform Tapestry about the mapping change:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class AppModule
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class AppModule
 {
     @Contribute(SymbolProvider.class)
     @ApplicationDefaults
-    <span class="code-keyword">public</span> <span class="code-keyword">static</span> void applicationDefaults(MappedConfiguration&lt;<span class="code-object">String</span>, <span class="code-object">String</span>&gt; configuration)
+    public static void applicationDefaults(MappedConfiguration&lt;String, String&gt; configuration)
     {
-        configuration.add(SymbolConstants.APPLICATION_FOLDER, <span class="code-quote">"t5app"</span>)
+        configuration.add(SymbolConstants.APPLICATION_FOLDER, "t5app")
     }
 }
-</pre>
+]]></script>
 </div></div>
 
 <div class="panelMacro"><table class="infoMacro"><colgroup span="1"><col span="1" width="24"><col span="1"></colgroup><tr><td colspan="1" rowspan="1" valign="top"><img align="middle" src="/images/confluence/information.gif" width="16" height="16" alt="" border="0"></td><td colspan="1" rowspan="1">This extra mapping is unfortunately necessary, because the Servlet API does not provide a way for a servlet filter, such as the one used by Tapestry, to know about its mapping.</td></tr></table></div>
@@ -637,7 +648,7 @@ configuration.add(ComponentParameterCons
 
 <div class="clearer"></div>
 <div id="footer">
-<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather logo, and the Apache Tapestry project logo are trademarks of The Apache Software Foundation.</p>
+<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather logo, and the Apache Tapestry project logo are trademarks of The Apache Software Foundation.<br clear="none">
 <script type="text/javascript">
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-400821-1']);
@@ -648,7 +659,7 @@ configuration.add(ComponentParameterCons
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
   })();
-</script></div>
+</script></p></div>
 </div>
 		<div id="comments_thread"></div>
 		<script type="text/javascript" src="https://comments.apache.org/show_comments.lua?site=tapestry&amp;page=http://tapestry.apache.org/configuration.html" async="true">

Modified: websites/production/tapestry/content/session-storage.html
==============================================================================
--- websites/production/tapestry/content/session-storage.html (original)
+++ websites/production/tapestry/content/session-storage.html Sun Aug 11 19:20:52 2013
@@ -34,9 +34,9 @@
 </div>
 
 <div id="top">
-<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em">
+<div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><p>
 <span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
+</p><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html">
   <input type="text" name="q">
   <input type="submit" value="Search">
 </form>
@@ -58,7 +58,7 @@
 <div id="content">
 <div id="ConfluenceContent"><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px"><table class="tableview" width="100%"><tr><th colspan="1" rowspan="1" style="padding: 3px 3px 3px 0px">Related Articles</th></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
-                         <a shape="rect" href="session-storage.html">Session Storage</a>
+                         <a shape="rect" href="persistent-page-data.html">Persistent Page Data</a>
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
@@ -66,13 +66,16 @@
         
                                             </td></tr><tr><td colspan="1" rowspan="1">
                                  <span class="icon icon-page" title="Page">Page:</span>
-                         <a shape="rect" href="persistent-page-data.html">Persistent Page Data</a>
+                         <a shape="rect" href="session-storage.html">Session Storage</a>
         
                                             </td></tr></table>
 </div> 
 
 <h1><a shape="rect" name="SessionStorage-SessionStorage"></a>Session Storage</h1>
 
+<div>
+<ul><li><a shape="rect" href="#SessionStorage-SessionStateObjects">Session State Objects</a></li><ul><li><a shape="rect" href="#SessionStorage-Pitfalls">Pitfalls</a></li><li><a shape="rect" href="#SessionStorage-CheckforCreation">Check for Creation</a></li><li><a shape="rect" href="#SessionStorage-PersistenceStrategies">Persistence Strategies</a></li><li><a shape="rect" href="#SessionStorage-ConfiguringSSOs">Configuring SSOs</a></li></ul><li><a shape="rect" href="#SessionStorage-SessionAttributes">Session Attributes</a></li><ul><li><a shape="rect" href="#SessionStorage-Pitfalls">Pitfalls</a></li></ul><li><a shape="rect" href="#SessionStorage-ClusteringIssues">Clustering Issues</a></li><ul><li><a shape="rect" href="#SessionStorage-@ImmutableSessionPersistedObjectAnnotation">@ImmutableSessionPersistedObject Annotation</a></li><li><a shape="rect" href="#SessionStorage-OptimizedSessionPersistedObjectInterface">OptimizedSessionPersistedObject Interface</a></li><li><a shape="rect" href="#
 SessionStorage-SessionPersistedObjectAnalyzerService">SessionPersistedObjectAnalyzer Service</a></li></ul><li><a shape="rect" href="#SessionStorage-SessionLocking">Session Locking</a></li></ul></div>
+
 <p>Most web applications will need to have some data that is shared across multiple pages. Perhaps you are creating a multi-page wizard, or you have an object that tracks the user's identify once logged in, or maybe you need to manage a shopping cart.</p>
 
 <p>Ordinary <a shape="rect" href="persistent-page-data.html" title="Persistent Page Data">page-persistent fields</a> won't work for this, since persistent fields are available only to a specific page, not shared across multiple pages.</p>
@@ -88,15 +91,15 @@
 <p>Example:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class MyPage
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class MyPage
 {
   @SessionState
-  <span class="code-keyword">private</span> ShoppingCart shoppingCart;
+  private ShoppingCart shoppingCart;
   
   . . .
 }
-</pre>
+]]></script>
 </div></div>
 
 <p>Any other component or page that declares a field <b>of the same type</b>, regardless of name, and marks it with the SessionState annotation will share the same value. It's that simple.  However, using @SessionState <em>safely</em> requires care:</p>
@@ -109,25 +112,25 @@
 
 <p>Assigning a value to an SSO field will store that value. Assigning null to an SSO field will remove the SSO (reading the field subsequently will force a new SSO instance to be created).</p>
 
-<h2><a shape="rect" name="SessionStorage-Pitfalls"></a>Pitfalls</h2>
+<h3><a shape="rect" name="SessionStorage-Pitfalls"></a>Pitfalls</h3>
 
 <p>With @SessionState, you are creating a session-wide data storage area that is tied to the <em>type</em> (class) of the variable you annotate.  It is not specifically tied to the variable itself, or even to the class in which that variable was annotated. As with all session data, there is the serious possibility of collisions, not just within your application but with other modules/libraries:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Example of Data Collision &#8211; Don't Do This!</b></div><div class="codeContent panelContent">
-<pre class="code-java">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
   @SessionState
-  <span class="code-keyword">private</span> <span class="code-object">String</span> userName;     <span class="code-comment">// Unsafe -- <span class="code-object">String</span> is not a custom type
-</span>
-  ... then, later in <span class="code-keyword">this</span> class or any other:
+  private String userName;     // Unsafe -- String is not a custom type
+
+  ... then, later in this class or any other:
 
   @sessionState
-  <span class="code-keyword">private</span> <span class="code-object">String</span> userCity;     <span class="code-comment">// This overwrites value in userName, because it's also a <span class="code-object">String</span>!</span>
-</pre>
+  private String userCity;     // This overwrites value in userName, because it's also a String!
+]]></script>
 </div></div>
 
 <p>The simple rule is, NEVER use @SessionState for simple-type variables. It is ALWAYS worth taking the time to build a special class to hold your session state information. Doing so will force you to consolidate that information into a single, logical unit that can't be accidentally accessed by other classes. (Alternatively, see the Session Attribute section below.)</p>
 
-<h2><a shape="rect" name="SessionStorage-CheckforCreation"></a>Check for Creation</h2>
+<h3><a shape="rect" name="SessionStorage-CheckforCreation"></a>Check for Creation</h3>
 
 <p>Scalable web applications do not create the server-side session needlessly. If you can avoid creating the session, especially on first access to your web application, you will be able to handle an order of magnitude more users. So, if you can avoid creating the SSO, you should do so.</p>
 
@@ -136,9 +139,9 @@
 <p>Instead, create a second field with a matching name but with "Exists" appended:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-  <span class="code-keyword">private</span> <span class="code-object">boolean</span> shoppingCartExists;
-</pre>
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+  private boolean shoppingCartExists;
+]]></script>
 </div></div>
 
 <p>It is not annotated; it is located by naming convention ("Exists" appended). It must be type boolean and must be a private instance variable.  Tapestry will automatically set this variable to <tt>true</tt> when the SSO is created, so you can check it to see if the SSO already exists.</p>
@@ -146,49 +149,21 @@
 <p>Alternately, you may allow for the state being null:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-  @SessionState(create=<span class="code-keyword">false</span>)
-  <span class="code-keyword">private</span> ShoppingCart shoppingCart;
-</pre>
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+  @SessionState(create=false)
+  private ShoppingCart shoppingCart;
+]]></script>
 </div></div>
 
 <p>In this case, the shoppingCart field will be null if the ShoppingCart SSO does not exist, but will be non-null if it has been created (either by assigning a value to the field, or by a different SSO field where create is true).</p>
 
-<h2><a shape="rect" name="SessionStorage-PersistenceStrategies"></a>Persistence Strategies</h2>
+<h3><a shape="rect" name="SessionStorage-PersistenceStrategies"></a>Persistence Strategies</h3>
 
 <p>Main Article: <a shape="rect" href="persistent-page-data.html#PersistentPageData-PersistenceStrategies">Persistent Page Data</a></p>
 
 <p>Each SSO is managed according to a persistence strategy. The default persistence strategy, "session", stores the SSOs inside the session. The session is created as needed.</p>
 
-<h2><a shape="rect" name="SessionStorage-ClusteringIssues"></a>Clustering Issues</h2>
-
-<p>The Servlet API was designed with the intention that there would be only a modest amount of server-side state, and that the stored values would be individual numbers and strings, and thus, immutable.</p>
-
-<p>However, many web applications do not use the HttpSession this way, instead storing large, mutable objects in the session. This is not a problem for single servers, but in a cluster, anything stored in the session must be serialized to a bytestream and distributed to other servers within the cluster, and restored there.</p>
-
-<p>Most application servers perform that serialization and distribution whenever HttpSession.setAttribute() is called. This creates a data consistency problem for mutable objects, because if you read a mutable session object, change its state, but <em>don't</em> invoke setAttribute(), the changes will be isolated to just a single server in the cluster.</p>
-
-<p>Tapestry attempts to solve this: any session-persisted object that is read during a request will be re-stored back into the HttpSession at the end of the request. This ensures that changed internal state of those mutable objects is properly replicated around the cluster.</p>
-
-<p>But while this solution solves the data consistency problem, it does so at the expense of performance, since all of those calls to setAttribute() result in extra session data being replicated needlessly if the internal state of the mutable object hasn't changed.</p>
-
-<p>Tapestry has solutions to this, too:</p>
-
-<h3><a shape="rect" name="SessionStorage-@ImmutableSessionPersistedObjectAnnotation"></a>@ImmutableSessionPersistedObject Annotation</h3>
-
-<p>Tapestry knows that Java's String, Number and Boolean classes are immutable. Immutable objects do not require a re-store into the session.</p>
-
-<p>You can mark your own session objects as immutable (and thus not requiring session replication) using the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/ImmutableSessionPersistedObject.html">ImmutableSessionPersistedObject</a> annotation.</p>
-
-<h3><a shape="rect" name="SessionStorage-OptimizedSessionPersistedObjectInterface"></a>OptimizedSessionPersistedObject Interface</h3>
-
-<p>The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/OptimizedSessionPersistedObject">OptimizedSessionPersistedObject</a> interface allows an object to control this behavior. An object with this interface can track when its mutable state changes. Typically, you should extend from the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.html">BaseOptimizedSessionPersistedObject</a> base class.</p>
-
-<h3><a shape="rect" name="SessionStorage-SessionPersistedObjectAnalyzerService"></a>SessionPersistedObjectAnalyzer Service</h3>
-
-<p>The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/SessionPersistedObjectAnalyzer.html">SessionPersistedObjectAnalyzer</a> service is ultimately responsible for determining whether a session persisted object is dirty or not (dirty meaning in need of a restore into the session). This is an extensible service where new strategies, for new classes, can be introduced.</p>
-
-<h2><a shape="rect" name="SessionStorage-ConfiguringSSOs"></a>Configuring SSOs</h2>
+<h3><a shape="rect" name="SessionStorage-ConfiguringSSOs"></a>Configuring SSOs</h3>
 
 <p>Generally, you will need to configure your Session State Object if you want to change the persistence strategy to other than the default. (Right now there's only one built in strategy, but more will be coming in the future.)</p>
 
@@ -197,20 +172,20 @@
 <p>A Session State Object is configured using contributions to the ApplicationStateManager service. From your application's module:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-  <span class="code-keyword">public</span> void contributeApplicationStateManager(MappedConfiguration&lt;<span class="code-object">Class</span>, ApplicationStateContribution&gt; configuration)
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+  public void contributeApplicationStateManager(MappedConfiguration&lt;Class, ApplicationStateContribution&gt; configuration)
   {
-    ApplicationStateCreator&lt;MyState&gt; creator = <span class="code-keyword">new</span> ApplicationStateCreator&lt;ShoppingCart&gt;()
+    ApplicationStateCreator&lt;MyState&gt; creator = new ApplicationStateCreator&lt;ShoppingCart&gt;()
     {
-      <span class="code-keyword">public</span> ShoppingCart create()
+      public ShoppingCart create()
       {
-        <span class="code-keyword">return</span> <span class="code-keyword">new</span> ShoppingCart(<span class="code-keyword">new</span> Date());
+        return new ShoppingCart(new Date());
       }
     };
   
-    configuration.add(ShoppingCart.class, <span class="code-keyword">new</span> ApplicationStateContribution(<span class="code-quote">"session"</span>, creator));
+    configuration.add(ShoppingCart.class, new ApplicationStateContribution("session", creator));
   }
-</pre>
+]]></script>
 </div></div>
 
 <p>Here, we have an SSO type of ShoppingCart, and we're providing a creator for it. We've dolled the creator up with some generic types, but that isn't essential.</p>
@@ -231,38 +206,38 @@
 <p>As an alternative to SSOs, Tapestry provides a <b>Session Attribute</b> mechanism, which lets you store data in the session by name (rather than type).  It is particularly useful when integrating Tapestry with legacy applications that directly manipulate the HttpSession.</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>The Old Way</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class Page {
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class Page {
     @Inject
-    <span class="code-keyword">private</span> Request request;
+    private Request request;
     
-    <span class="code-keyword">public</span> User getUser() {
-        <span class="code-keyword">return</span> (User) request.getSession(<span class="code-keyword">true</span>).getAttribute(<span class="code-quote">"loggedInUserName"</span>);
+    public User getUser() {
+        return (User) request.getSession(true).getAttribute("loggedInUserName");
     }
 }
-</pre>
+]]></script>
 </div></div>
 
 <p>Starting with Tapestry 5.2, this can be accomplished just by annotating a page or component property with @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SessionAttribute.html">SessionAttribute</a>. This annotation is used to map a property of a page or component to value stored in session. Unlike Session State Objects, the name (not the type) of the annotated property is used as the name of the session attribute to look for.</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>The New Way</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class Page {
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class Page {
     @SessionAttribute
-    <span class="code-keyword">private</span> User loggedInUserName;
+    private User loggedInUserName;
 }
-</pre>
+]]></script>
 </div></div>
 
 <p>You can also provide a name using the annotation's <tt>value</tt> parameter:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> class Page {
-    @SessionAttribute(<span class="code-quote">"loggedInUserName"</span>)
-    <span class="code-keyword">private</span> User userName;
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public class Page {
+    @SessionAttribute("loggedInUserName")
+    private User userName;
 }
-</pre>
+]]></script>
 </div></div>
 
 
@@ -273,22 +248,68 @@
 <p>It's best to define the session attribute name as constant, and use that in the annotation's value parameter, rather then defaulting to the instance variable name.  This will help prevent subtle runtime errors due to misspellings.  For example:</p>
 
 <div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>The Safer Way</b></div><div class="codeContent panelContent">
-<pre class="code-java">
-<span class="code-keyword">public</span> <span class="code-keyword">static</span> <span class="code-keyword">final</span> <span class="code-object">String</span> USER_NAME_SESSION_ATTRIBUTE = <span class="code-quote">"com.example.shoppingapp.username"</span>;
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+public static final String USER_NAME_SESSION_ATTRIBUTE = "com.example.shoppingapp.username";
 
 ...
 
-<span class="code-keyword">public</span> class Page {
+public class Page {
     @SessionAttribute(USER_NAME_SESSION_ATTRIBUTE)
-    <span class="code-keyword">private</span> User userName;
+    private User userName;
 }
-</pre>
-</div></div></div>
+]]></script>
+</div></div>
+
+<h2><a shape="rect" name="SessionStorage-ClusteringIssues"></a>Clustering Issues</h2>
+
+<p>The Servlet API was designed with the intention that there would be only a modest amount of server-side state, and that the stored values would be individual numbers and strings, and thus, immutable.</p>
+
+<p>However, many web applications do not use the HttpSession this way, instead storing large, mutable objects in the session. This is not a problem for single servers, but in a cluster, anything stored in the session must be serialized to a bytestream and distributed to other servers within the cluster, and restored there.</p>
+
+<p>Most application servers perform that serialization and distribution whenever HttpSession.setAttribute() is called. This creates a data consistency problem for mutable objects, because if you read a mutable session object, change its state, but <em>don't</em> invoke setAttribute(), the changes will be isolated to just a single server in the cluster.</p>
+
+<p>Tapestry attempts to solve this: any session-persisted object that is read during a request will be re-stored back into the HttpSession at the end of the request. This ensures that changed internal state of those mutable objects is properly replicated around the cluster.</p>
+
+<p>But while this solution solves the data consistency problem, it does so at the expense of performance, since all of those calls to setAttribute() result in extra session data being replicated needlessly if the internal state of the mutable object hasn't changed.</p>
+
+<p>Tapestry has solutions to this, too:</p>
+
+<h3><a shape="rect" name="SessionStorage-@ImmutableSessionPersistedObjectAnnotation"></a>@ImmutableSessionPersistedObject Annotation</h3>
+
+<p>Tapestry knows that Java's String, Number and Boolean classes are immutable. Immutable objects do not require a re-store into the session.</p>
+
+<p>You can mark your own session objects as immutable (and thus not requiring session replication) using the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/ImmutableSessionPersistedObject.html">ImmutableSessionPersistedObject</a> annotation.</p>
+
+<h3><a shape="rect" name="SessionStorage-OptimizedSessionPersistedObjectInterface"></a>OptimizedSessionPersistedObject Interface</h3>
+
+<p>The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/OptimizedSessionPersistedObject">OptimizedSessionPersistedObject</a> interface allows an object to control this behavior. An object with this interface can track when its mutable state changes. Typically, you should extend from the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/BaseOptimizedSessionPersistedObject.html">BaseOptimizedSessionPersistedObject</a> base class.</p>
+
+<h3><a shape="rect" name="SessionStorage-SessionPersistedObjectAnalyzerService"></a>SessionPersistedObjectAnalyzer Service</h3>
+
+<p>The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/SessionPersistedObjectAnalyzer.html">SessionPersistedObjectAnalyzer</a> service is ultimately responsible for determining whether a session persisted object is dirty or not (dirty meaning in need of a restore into the session). This is an extensible service where new strategies, for new classes, can be introduced.</p>
+
+<h2><a shape="rect" name="SessionStorage-SessionLocking"></a>Session Locking</h2>
+
+<p>Starting with version 5.4, by default Tapestry will apply locking semantics around access to the HttpSession. Reading attribute names occurs with a shared read lock, and getting or setting an attribute upgrades the lock to an exclusive write lock. This can tend to serialize threads when a number of simultaneous (Ajax) requests from the client arrive. However, many implementations of HttpSession are not thread safe, and often mutable objects<br clear="none">
+are stored in the session and shared between threads.</p>
+
+<p>The <tt>tapestry.session-locking-enabled</tt> <a shape="rect" href="configuration.html" title="Configuration">symbol</a> can control this behavior. Setting this to true (the default) will yield a more robust application; setting it to false may speed up processing for more Ajax intensive applications (but care should then be given to ensuring that objects shared inside the session are themeselves immutable or thread-safe).</p>
+
+<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
+  public static void contributeApplicationDefaults(MappedConfiguration&lt;String,String&gt; configuration)
+  {
+    configuration.add(SymbolConstants.SESSION_LOCKING_ENABLED, true);
+    ...
+  }
+]]></script>
+</div></div>
+</div>
 </div>
 
 <div class="clearer"></div>
 <div id="footer">
-<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather logo, and the Apache Tapestry project logo are trademarks of The Apache Software Foundation.</p>
+<div id="footer"><p>Apache Tapestry, Tapestry, Apache, the Apache feather logo, and the Apache Tapestry project logo are trademarks of The Apache Software Foundation.<br clear="none">
 <script type="text/javascript">
   var _gaq = _gaq || [];
   _gaq.push(['_setAccount', 'UA-400821-1']);
@@ -299,7 +320,7 @@
     ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
     var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
   })();
-</script></div>
+</script></p></div>
 </div>
 		<div id="comments_thread"></div>
 		<script type="text/javascript" src="https://comments.apache.org/show_comments.lua?site=tapestry&amp;page=http://tapestry.apache.org/session-storage.html" async="true">