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 2014/03/02 23:20:38 UTC

svn commit: r899778 [1/2] - in /websites/production/tapestry/content: building-tapestry-from-source.html cache/main.pageCache injection-faq.html limitations.html page-and-component-classes-faq.html

Author: buildbot
Date: Sun Mar  2 22:20:37 2014
New Revision: 899778

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/building-tapestry-from-source.html
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/injection-faq.html
    websites/production/tapestry/content/limitations.html
    websites/production/tapestry/content/page-and-component-classes-faq.html

Modified: websites/production/tapestry/content/building-tapestry-from-source.html
==============================================================================
--- websites/production/tapestry/content/building-tapestry-from-source.html (original)
+++ websites/production/tapestry/content/building-tapestry-from-source.html Sun Mar  2 22:20:37 2014
@@ -69,7 +69,7 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p>This is a guide to building Tapestry itself from source code. This is primarily of interest to Tapestry <em>contributors</em>, rather than Tapestry <em>users</em>.</p><p>Although Tapestry <em>users</em> are free to use any build mechanism for their own projects (and first class Maven support is provided), to build Tapestry itself from source you will use Gradle.</p><p>Note: Both command line and Eclipse Gradle IDE/EGit instructions are given here. Generally you'll want to chose approach one or the other, rather than mixing them.</p><h2 id="BuildingTapestryfromSource-Prerequisites">Prerequisites</h2><ul><li>Install a Java JDK (Sun/Oracle, not OpenJDK), version 1.7 (just to prevent VU#225657, see: <a shape="rect" class="external-link" href="http://www.kb.cert.org/vuls/id/225657" >http://www.kb.cert.org/vuls/id/225657</a>).</li><li>Install an IDE (IDEA IntelliJ is recommended (and free to Tapestry committers), but Eclipse will also work. NetBeans is repor
 ted to work as well.</li><li>Install Firefox browser <span style="text-decoration: line-through;">version 3.6</span>, needed for the integration tests.</li><li>Set the Firefox browser's "preferred language" to English (en), because some tests will otherwise fail.</li><li>Install a Git client<ul><li>Command-line users: <a shape="rect" class="external-link" href="http://git-scm.com/downloads" >http://git-scm.com/downloads</a></li><li>Eclipse users: Install EGit from the Eclipse Marketplace, then in In Window &gt; Preferences &gt; Team &gt; Git, set your "Default repository folder" (e.g. <code>~/git</code> or <code>%HOME%\git</code>)</li></ul></li><li>Install Gradle 1.0-milestone-3 or newer (or a Gradle plugin to your IDE),<ul><li>Command-line users: <a shape="rect" class="external-link" href="http://www.gradle.org/downloads" >http://www.gradle.org/downloads</a></li><li>Eclipse users: Install Gradle IDE from the Eclipse Marketplace</li></ul></li></ul><h2 id="BuildingTapestryfromSource-
 GettingStarted">Getting Started</h2><p>Please read <a shape="rect" class="external-link" href="https://git-wip-us.apache.org/">https://git-wip-us.apache.org/</a> first.</p><p>Windows users (especialy EGit users) should probably set the core.autocrlf config setting to <code>false</code> so that local diffs won't highlight line ending differences.</p><h3 id="BuildingTapestryfromSource-ClonetheRepository">Clone the Repository</h3><p>Clone Tapestry from the Git repo:</p><ul><li><p>Command-line git users:</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Non Committers:</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>git clone</p><a shape="rect" class="external-link" href="http://git-wip-us.apache.org/repos/asf/tapestry-5.git">http://git-wip-us.apache.org/repos/asf/tapestry-5.git</a><p>&#160;</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Committers:</p></td><td colspan="1" rowspan="1
 " class="confluenceTd"><p>git clone</p><a shape="rect" class="external-link" href="https://git-wip-us.apache.org/repos/asf/tapestry-5.git">https://git-wip-us.apache.org/repos/asf/tapestry-5.git</a><p>&#160;</p></td></tr></tbody></table></div></li><li>Eclipse EGit users:<ul><li>Switch to Git perspective; then copy one of the URLs above into paste buffer</li><li>Right-click &gt; Paste repository path or URI. This will bring up the Clone Git Repository dialog.</li><li>Committers: make sure Protocol is https, and enter your Apache commiter LDAP user name &amp; password</li><li>click Next.</li><li>Select the branches you're interested in (e.g 5.3 and master), click Next</li><li>Select Directory to where you want the project source code (e.g. <code>~/git/tapestry-5</code> or <code>%HOME%\git\tapestry-5</code>)</li><li>Select whichever "Initial Branch" you're interested in (e.g. master)</li><li>Set "Remote name" to "origin" (the default)</li><li><strong>VERY IMPORTANT</strong>: uncheck the
  "Import all existing projects" checkbox (we'll do this using Gradle, below)</li><li>Click Finish. (Be patient; the clone operation might take a few minutes.)</li></ul></li></ul><h3 id="BuildingTapestryfromSource-GradlePreparation">Gradle Preparation</h3><ul><li>Command-line gradle users only:<ul><li>If you're using Eclipse but <strong>not</strong> Gradle IDE do <code>./gradlew eclipse</code></li><li>The command-line Gradle's eclipse plugin doesn't include the provided project dependencies; you need to add them manually (Java Build Path &gt; Projects &gt; Add tapestry-test). The plugin also generates a root eclipse project, so you'll need to delete the ".project" file in the root folder, and then you can import all Tapestry sub-projects at once.</li></ul></li><li>Eclipse Gradle IDE users:<ul><li>Switch to Java (or JEE) perspective and right-click &gt; Import... &gt; Gradle &gt; Gradle Project &gt; Next.</li><li>Set the "Root folder" to where you put your Tapestry source in the previ
 ous section (e.g. <code>~/git/tapestry-5</code> or <code>%Home%\git\tapestry-5</code>)</li><li>Click <code>Build Model. When it completes, s</code>elect the top-level (the top-level module and all sub-modules).</li><li>Be sure the "Enable dependency management" and "Create workingset 'tapestry-5' checkboxes are checked.</li><li>Click <code>Finish</code>. (Be patient; the import operation might take a few minutes.)</li></ul></li><li>Eclipse EGit users: Do a Git "Share" on the project:<ul><li>Still in the Java (or JEE) perspective, select all of the Tapestry projects (top-level and sub-modules) and right-click &gt; Team &gt; Share Project... &gt; Git &gt; Next &gt; Ensure all are selected, click <code>Finish</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-Antlr">Antlr</h3><p>The <code>tapestry-core</code> project will initially have errors because of missing Java classes that are produced by ANTLR the first time the project is built. To fix this:</p><ul><li>Eclipse Gradl
 e IDE users:<ul><li>Right click on the <code>build.gradle</code> file within tapestry-core and click Run As &gt; "Gradle build...", check <strong>only</strong> the generateGrammarSource task, and change the "Name" field to something like "tapestry-core antlr", then click Apply and Run.</li><li>When it's finished, the antlr-generated classes (e.g. PropertyExpressionLexer.java) will be in created in $buildDir/generated-sources/antlr/, but Eclipse doesn't yet know about that path. To fix that, right click on the <code>tapestry-core</code> project &gt; Properties &gt; Java Build Path &gt; Source &gt; Add Folder &gt; find <code>tapestry-core/build/generated-sources/antlr</code> and check the checkbox next to it, then click <code>OK</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-CoffeeScript">CoffeeScript</h3><p>If you want to run tests from within Eclipse, Tapestry will complain that it won't find certain JavaScript files that normally are generated during compile time fro
 m their Coffeescript sources. In order to generate the JavaScript files you need to have Coffeescript installed and in your path. Simply install <a shape="rect" class="external-link" href="http://nodejs.org/download/" >Node.js</a> and afterwards run <code>npm install -g coffee-script</code>. The installation should take care of everything.</p><ul><li>Eclipse Gradle IDE users:<ul><li>Right click on the <code>build.gradle</code> file within tapestry-core and click Run As &gt; "Gradle build...", check <strong>only</strong> the tapestry-core:compileCoffeeScript and tapestry-core:compileTestCoffeeScript tasks, and change the "Name" field to something like "tapestry-core coffeescript", then click Apply and Run.</li><li>When it's finished, the coffeescript-generated JavaScript files (e.g. t5-core-dom-jquery.js) will be in created in $buildDir/generated-sources/compiled-coffeescript/ and $buildDir/generated-sources/compiled-test-coffeescript/, but Eclipse doesn't yet know about that path. T
 o fix that, right click on the <code>tapestry-core</code> project &gt; Properties &gt; Java Build Path &gt; Source &gt; Add Folder &gt; find <code>tapestry-core/build/generated-sources/compiled-coffeescript</code> and <code>tapestry-core/build/generated-sources/compiled-test-coffeescript</code> and check the checkbox next to it, then click <code>OK</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-GenerateCoffeeScriptandAntlrfilesautomaticallywhenchanged">Generate CoffeeScript and Antlr files automatically when changed</h3><p>If you want to have Eclipse compile the JavaScript files and lexer classes from their Coffeescript sources and Antlr files automatically when they change, you can do that by configuring an additional builder for the <code>tapestry-core</code> project:</p><ul><li>Eclipse Gradle IDE users:<ul><li>Right click on the <code>tapestry-core</code> project and select properties.</li><li>Select the "Builders" entry from the list on the left and click "New.." 
 in the right panel.</li><li>Select "Program" and click "Ok".</li><li>Give the program a meaningful name, e.g. "compile coffeescript and antlr".</li><li>Switch to the "Main" tab.</li><li>For "Location:" click "Browse Workspace..." and select <code>gradlew.sh</code> or <code>gradlew.bat</code> in the Tapestry root project. If the root project is called "tapestry-5" the entry should look similar to "${workspace_loc:/tapestry-5/gradlew.bat}".</li><li>For "Working Directory:" click "Browse Workspace..." and select the Tapestry root project.</li><li>For "Arguments:" enter <code>tapestry-core:generateGrammarSource tapestry-core:compileCoffeeScript tapestry-core:compileTestCoffeeScript</code>.</li><li>Switch to the "Build Options" tab.</li><li>Make sure that only "Allocate Console", "After a "Clean"", "During manual builds", "During auto builds" and "Specify working set of relevant resources" are checked.</li><li>Click "Specify Resources...".</li><li>From the "tapestry-core" project select 
 "src/main/antlr", "src/main/coffeescript", and "src/test/coffeescript".</li><li>Click "Finish".</li><li>Click "OK".</li><li>Click "OK".</li></ul></li></ul><h3 id="BuildingTapestryfromSource-Building">Building</h3><p>You can build individual modules, or (from the root folder) build everything.</p><ul><li>Command-line users:<br clear="none"> *( "gradlew" is the gradle wrapper shell script (gradlew) or batch file (gradlew.bat) found in the root folder of the Tapestry source.<ul><li><code>./gradlew build</code></li></ul></li><li>Eclipse Gradle IDE users:<ul><li>Right click on the top-level project (or any sub-project) and select Run As &gt; Gradle Build...</li></ul></li></ul><h3 id="BuildingTapestryfromSource-RunningTests">Running Tests</h3><p>Eclipse users:</p><ul><li>Install the <a shape="rect" class="external-link" href="http://testng.org/doc/eclipse.html" >TestNG plugin</a> to allow running of individual TestNG unit tests from within in Eclipse.</li></ul><p>The Tapestry integration 
 tests will repeatedly start up a Firefox browser.</p><ul><li>Ensure that your environment will allow a connection to <a shape="rect" class="external-link" href="https://localhost:443" >https://localhost:443</a></li></ul><h3 id="BuildingTapestryfromSource-SkippingTests">Skipping Tests</h3><p>Running the Tapestry integration tests can take 10 minutes or more (mostly because of Selenium tests, which repeatedly start and stop the Firefox browser), so you won't want to run them every time you try a change.</p><ul><li>Command-line users:<ul><li><code>./gradlew build -x test</code></li><li>You can skip tests on a specific module by adding a colon and the module name. For example: <code>-x test:tapestry-ioc</code></li></ul></li><li>Eclipse Gradle IDE users:</li></ul><h3 id="BuildingTapestryfromSource-RunningtheIntegrationTestAppsManually">Running the Integration Test Apps Manually</h3><p>The Tapestry source includes several web apps that are used by the automated Selenium integration tests.
  You can also run these apps manually to try out nearly every browser-visible aspect of Tapestry.&#160;(See a <a shape="rect" class="external-link" href="http://tapestry-test.appspot.com/" >live example</a> running on Google App Engine.)</p><ul><li>If using Eclipse:<ul><li>Use the run-jetty-run plugin in Eclipse, with the context directory selected from among the <code>test</code> context directories. For example, in the tapestry-core module, right click on the /src/test/app1 (or app2, etc) folder, and select Run As &gt; Run Jetty, then open your browser to <a shape="rect" class="external-link" href="http://localhost:8080/tapestry-core" >http://localhost:8080/tapestry-core</a></li></ul></li></ul><h3 id="BuildingTapestryfromSource-MakingCodeChanges">Making Code Changes</h3><p>Once you have cloned or pulled the latest changes to your local Git repository, you can start working on it. Whenever you make some changes to the codebase, it's good to have a related issue filed in JIRA and to
  use a similarly named branch in your local Git repository. For example, to create a branch for an issue with the key TAP5-123:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<div id="ConfluenceContent"><p>This is a guide to building Tapestry itself from source code. This is primarily of interest to Tapestry <em>contributors</em>, rather than Tapestry <em>users</em>.</p><p>Although Tapestry <em>users</em> are free to use any build mechanism for their own projects (and first class Maven support is provided), to build Tapestry itself from source you will use Gradle.</p><p>Note: Both command line and Eclipse Gradle IDE/EGit instructions are given here. Generally you'll want to chose approach one or the other, rather than mixing them.</p><h2 id="BuildingTapestryfromSource-Prerequisites">Prerequisites</h2><ul><li>Install a Java JDK (Sun/Oracle, not OpenJDK), version 1.7 (just to prevent VU#225657, see: <a shape="rect" class="external-link" href="http://www.kb.cert.org/vuls/id/225657" >http://www.kb.cert.org/vuls/id/225657</a>).</li><li>Install an IDE (IDEA IntelliJ is recommended (and free to Tapestry committers), but Eclipse will also work. NetBeans is repor
 ted to work as well.</li><li>Install Firefox browser <span style="text-decoration: line-through;">version 3.6</span>, needed for the integration tests.</li><li>Set the Firefox browser's "preferred language" to English (en), because some tests will otherwise fail.</li><li>Install a Git client<ul><li>Command-line users: <a shape="rect" class="external-link" href="http://git-scm.com/downloads" >http://git-scm.com/downloads</a></li><li>Eclipse users: Install EGit from the Eclipse Marketplace, then in In Window &gt; Preferences &gt; Team &gt; Git, set your "Default repository folder" (e.g. <code>~/git</code> or <code>%HOME%\git</code>)</li></ul></li><li>Install Gradle 1.0-milestone-3 or newer (or a Gradle plugin to your IDE),<ul><li>Command-line users: <a shape="rect" class="external-link" href="http://www.gradle.org/downloads" >http://www.gradle.org/downloads</a></li><li>Eclipse users: Install Gradle IDE from the Eclipse Marketplace</li></ul></li></ul><h2 id="BuildingTapestryfromSource-
 GettingStarted">Getting Started</h2><p>Please read <a shape="rect" class="external-link" href="https://git-wip-us.apache.org/">https://git-wip-us.apache.org/</a> first.</p><p>Windows users (especialy EGit users) should probably set the core.autocrlf config setting to <code>false</code> so that local diffs won't highlight line ending differences.</p><h3 id="BuildingTapestryfromSource-ClonetheRepository">Clone the Repository</h3><p>Clone Tapestry from the Git repo:</p><ul><li><p>Command-line git users:</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Non Committers:</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>git clone</p><a shape="rect" class="external-link" href="http://git-wip-us.apache.org/repos/asf/tapestry-5.git">http://git-wip-us.apache.org/repos/asf/tapestry-5.git</a><p>&#160;</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Committers:</p></td><td colspan="1" rowspan="1
 " class="confluenceTd"><p>git clone</p><a shape="rect" class="external-link" href="https://git-wip-us.apache.org/repos/asf/tapestry-5.git">https://git-wip-us.apache.org/repos/asf/tapestry-5.git</a><p>&#160;</p></td></tr></tbody></table></div></li><li>Eclipse EGit users:<ul><li>Switch to Git perspective; then copy one of the URLs above into paste buffer</li><li>Right-click &gt; Paste repository path or URI. This will bring up the Clone Git Repository dialog.</li><li>Committers: make sure Protocol is https, and enter your Apache commiter LDAP user name &amp; password</li><li>click Next.</li><li>Select the branches you're interested in (e.g 5.3 and master), click Next</li><li>Select Directory to where you want the project source code (e.g. <code>~/git/tapestry-5</code> or <code>%HOME%\git\tapestry-5</code>)</li><li>Select whichever "Initial Branch" you're interested in (e.g. master)</li><li>Set "Remote name" to "origin" (the default)</li><li><strong>VERY IMPORTANT</strong>: uncheck the
  "Import all existing projects" checkbox (we'll do this using Gradle, below)</li><li>Click Finish. (Be patient; the clone operation might take a few minutes.)</li></ul></li></ul><h3 id="BuildingTapestryfromSource-GradlePreparation">Gradle Preparation</h3><ul><li>Command-line gradle users only:<ul><li>If you're using Eclipse but <strong>not</strong> Gradle IDE do <code>./gradlew eclipse</code></li><li>The command-line Gradle's eclipse plugin doesn't include the provided project dependencies; you need to add them manually (Java Build Path &gt; Projects &gt; Add tapestry-test). The plugin also generates a root eclipse project, so you'll need to delete the ".project" file in the root folder, and then you can import all Tapestry sub-projects at once.</li></ul></li><li>Eclipse Gradle IDE users:<ul><li>Switch to Java (or JEE) perspective and right-click &gt; Import... &gt; Gradle &gt; Gradle Project &gt; Next.</li><li>Set the "Root folder" to where you put your Tapestry source in the previ
 ous section (e.g. <code>~/git/tapestry-5</code> or <code>%Home%\git\tapestry-5</code>)</li><li>Click <code>Build Model. When it completes, s</code>elect the top-level (the top-level module and all sub-modules).</li><li>Be sure the "Enable dependency management" and "Create workingset 'tapestry-5' checkboxes are checked.</li><li>Click <code>Finish</code>. (Be patient; the import operation might take a few minutes.)</li></ul></li><li>Eclipse EGit users: Do a Git "Share" on the project:<ul><li>Still in the Java (or JEE) perspective, select all of the Tapestry projects (top-level and sub-modules) and right-click &gt; Team &gt; Share Project... &gt; Git &gt; Next &gt; Ensure all are selected, click <code>Finish</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-Antlr">Antlr</h3><p>The <code>tapestry-core</code> project will initially have errors because of missing Java classes that are produced by ANTLR the first time the project is built. To fix this:</p><ul><li>Eclipse Gradl
 e IDE users:<ul><li>Right click on the <code>build.gradle</code> file within tapestry-core and click Run As &gt; "Gradle build...", check <strong>only</strong> the generateGrammarSource task, and change the "Name" field to something like "tapestry-core antlr", then click Apply and Run.</li><li>When it's finished, the antlr-generated classes (e.g. PropertyExpressionLexer.java) will be in created in $buildDir/generated-sources/antlr/, but Eclipse doesn't yet know about that path. To fix that, right click on the <code>tapestry-core</code> project &gt; Properties &gt; Java Build Path &gt; Source &gt; Add Folder &gt; find <code>tapestry-core/build/generated-sources/antlr</code> and check the checkbox next to it, then click <code>OK</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-CoffeeScript">CoffeeScript</h3><p>If you want to run tests from within Eclipse, Tapestry will complain that it won't find certain JavaScript files that normally are generated during compile time fro
 m their Coffeescript sources. In order to generate the JavaScript files you need to have Coffeescript installed and in your path. Simply install <a shape="rect" class="external-link" href="http://nodejs.org/download/" >Node.js</a> and afterwards run <code>npm install -g coffee-script</code>. The installation should take care of everything.</p><ul><li>Eclipse Gradle IDE users:<ul><li>Right click on the <code>build.gradle</code> file within tapestry-core and click Run As &gt; "Gradle build...", check <strong>only</strong> the tapestry-core:compileCoffeeScript and tapestry-core:compileTestCoffeeScript tasks, and change the "Name" field to something like "tapestry-core coffeescript", then click Apply and Run.</li><li>When it's finished, the coffeescript-generated JavaScript files (e.g. t5-core-dom-jquery.js) will be in created in $buildDir/generated-sources/compiled-coffeescript/ and $buildDir/generated-sources/compiled-test-coffeescript/, but Eclipse doesn't yet know about that path. T
 o fix that, right click on the <code>tapestry-core</code> project &gt; Properties &gt; Java Build Path &gt; Source &gt; Add Folder &gt; find <code>tapestry-core/build/generated-sources/compiled-coffeescript</code> and <code>tapestry-core/build/generated-sources/compiled-test-coffeescript</code> and check the checkbox next to it, then click <code>OK</code>.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-GenerateCoffeeScriptandAntlrfilesautomaticallywhenchanged">Generate CoffeeScript and Antlr files automatically when changed</h3><p>If you want to have Eclipse compile the JavaScript files and lexer classes from their Coffeescript sources and Antlr files automatically when they change, you can do that by configuring an additional builder for the <code>tapestry-core</code> project:</p><ul><li>Eclipse Gradle IDE users:<ul><li>Right click on the <code>tapestry-core</code> project and select properties.</li><li>Select the "Builders" entry from the list on the left and click "New.." 
 in the right panel.</li><li>Select "Program" and click "Ok".</li><li>Give the program a meaningful name, e.g. "compile coffeescript and antlr".</li><li>Switch to the "Main" tab.</li><li>For "Location:" click "Browse Workspace..." and select <code>gradlew.sh</code> or <code>gradlew.bat</code> in the Tapestry root project. If the root project is called "tapestry-5" the entry should look similar to "${workspace_loc:/tapestry-5/gradlew.bat}".</li><li>For "Working Directory:" click "Browse Workspace..." and select the Tapestry root project.</li><li>For "Arguments:" enter <code>tapestry-core:generateGrammarSource tapestry-core:compileCoffeeScript tapestry-core:compileTestCoffeeScript</code>.</li><li>Switch to the "Build Options" tab.</li><li>Make sure that only "Allocate Console", "After a "Clean"", "During manual builds", "During auto builds" and "Specify working set of relevant resources" are checked.</li><li>Click "Specify Resources...".</li><li>From the "tapestry-core" project select 
 "src/main/antlr", "src/main/coffeescript", and "src/test/coffeescript".</li><li>Click "Finish".</li><li>Click "OK".</li><li>Click "OK".</li></ul></li></ul><h3 id="BuildingTapestryfromSource-Building">Building</h3><p>You can build individual modules, or (from the root folder) build everything.</p><ul><li>Command-line users:<br clear="none"> *( "gradlew" is the gradle wrapper shell script (gradlew) or batch file (gradlew.bat) found in the root folder of the Tapestry source.<ul><li><code>./gradlew build</code></li></ul></li><li>Eclipse Gradle IDE users:<ul><li>Right click on the top-level project (or any sub-project) and select Run As &gt; Gradle Build..., which starts an External Tools Configuration dialog box. Enter a reasonable name, select the tasks you want to run (for example, tapestry-core/install), and click Run.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-RunningIndividualTests">Running Individual Tests</h3><p>Eclipse users:</p><ul><li>Install the <a shape="rect" cla
 ss="external-link" href="http://testng.org/doc/eclipse.html" >TestNG plugin</a> to allow running of individual TestNG unit tests from within in Eclipse.</li></ul><p>The Tapestry integration tests will repeatedly start up a Firefox browser.</p><ul><li>Ensure that your environment will allow a connection to <a shape="rect" class="external-link" href="https://localhost:443" >https://localhost:443</a></li></ul><h3 id="BuildingTapestryfromSource-SkippingTests">Skipping Tests</h3><p>Running the Tapestry integration tests can take 10 minutes or more (mostly because of Selenium tests, which repeatedly start and stop the Firefox browser), so you won't want to run them every time you try a change.</p><ul><li>Command-line users:<ul><li><code>To build while skipping all tests: ./gradlew build -x test</code></li><li>You can skip tests on a specific module by adding a colon and the module name. For example: <code>-x test:tapestry-ioc</code></li></ul></li><li>Eclipse Gradle IDE users:<ul><li>In yo
 ur External Tools Configuration, add the same -x test option as above at Arguments &gt; Program Arguments.</li></ul></li></ul><h3 id="BuildingTapestryfromSource-RunningtheIntegrationTestAppsManually">Running the Integration Test Apps Manually</h3><p>The Tapestry source includes several web apps that are used by the automated Selenium integration tests. You can also run these apps manually to try out nearly every browser-visible aspect of Tapestry.&#160;(See a <a shape="rect" class="external-link" href="http://tapestry-test.appspot.com/" >live example</a> running on Google App Engine.)</p><ul><li>If using Eclipse:<ul><li>Use the run-jetty-run plugin in Eclipse, with the context directory selected from among the <code>test</code> context directories. For example, in the tapestry-core module, right click on the /src/test/app1 (or app2, etc) folder, and select Run As &gt; Run Jetty, then open your browser to <a shape="rect" class="external-link" href="http://localhost:8080/tapestry-core
 " >http://localhost:8080/tapestry-core</a></li></ul></li></ul><h3 id="BuildingTapestryfromSource-MakingCodeChanges">Making Code Changes</h3><p>Once you have cloned or pulled the latest changes to your local Git repository, you can start working on it. Whenever you make some changes to the codebase, it's good to have a related issue filed in JIRA and to use a similarly named branch in your local Git repository. For example, to create a branch for an issue with the key TAP5-123:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[git branch TAP5-123 origin/master]]></script>
 </div></div><p>With per-issue branches you can easily switch back and forth between different issues without worrying about unwanted side-effects from unfinished changes to other issues. Whenever you want to work on the TAP5-123 example issue, simply checkout that branch and start making your changes:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[git checkout TAP5-123]]></script>

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

Modified: websites/production/tapestry/content/injection-faq.html
==============================================================================
--- websites/production/tapestry/content/injection-faq.html (original)
+++ websites/production/tapestry/content/injection-faq.html Sun Mar  2 22:20:37 2014
@@ -77,55 +77,22 @@ table.ScrollbarTable td.ScrollbarParent 
 table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
 table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
 
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="ajax-components-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="ajax-components-faq.html">Ajax Components FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control FAQ</a></td><td colspan="1" rowspan="1" 
 class="ScrollbarNextIcon"><a shape="rect" href="tapestry-inversion-of-control-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div>
-
-<h2 id="InjectionFAQ-Injection">Injection</h2>
-
-<p>Main article: <a shape="rect" href="injection.html">Injection</a></p>
-
-<h3 id="InjectionFAQ-What'sthedifferencebetweenthe@Componentand@InjectComponentannotations?">What's the difference between the <code>@Component</code> and <code>@InjectComponent</code> annotations?</h3>
-
-<p>The <code>@Component</code> annotation is used to define the <em>type</em> of component, and its parameter bindings. When using <code>@Component</code>, the template must not define the type, and any parameter bindings are merged in:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-  &lt;a t:id=&quot;home&quot; class=&quot;nav&quot;&gt;Back to home&lt;/a&gt;
+/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="ajax-components-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="ajax-components-faq.html">Ajax Components FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control FAQ</a></td><td colspan="1" rowspan="1" 
 class="ScrollbarNextIcon"><a shape="rect" href="tapestry-inversion-of-control-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div><h2 id="InjectionFAQ-Injection">Injection</h2><p>Main article: <a shape="rect" href="injection.html">Injection</a></p><h3 id="InjectionFAQ-What'sthedifferencebetweenthe@Componentand@InjectComponentannotations?">What's the difference between the <code>@Component</code> and <code>@InjectComponent</code> annotations?</h3><p>The <code>@Component</code> annotation is used to define the <em>type</em> of component, and its parameter bindings. When using <code>@Component</code>, the template must not define the type, and any parameter bindings are merged in:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[  &lt;a t:id=&quot;home&quot; class=&quot;nav&quot;&gt;Back to home&lt;/a&gt;
 ]]></script>
-</div></div>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-  @Component(parameters={ &quot;page=index&quot; })
+</div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[  @Component(parameters={ &quot;page=index&quot; })
   private PageLink home;
 ]]></script>
-</div></div>
-
-<p>Here the type of component is defined by the field type. The field name is matched against the <code>t:id</code> in the template. The <code>page</code> parameter is set in the Java class, and the informal <code>class</code> parameter is set in the template.  If the tag in the template was <code>&lt;t:pagelink&gt;</code>, or if the template tag included the attribute <code>t:type="pagelink"</code>, then you would see an exception.</p>
-
-<p>By contrast, <code>@InjectComponent</code> expects the component to be already defined, and doesn't allow any configuration of it:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-  &lt;t:form t:id=&quot;login&quot;&gt; .... &lt;/t:form&gt;
+</div></div><p>Here the type of component is defined by the field type. The field name is matched against the <code>t:id</code> in the template. The <code>page</code> parameter is set in the Java class, and the informal <code>class</code> parameter is set in the template. If the tag in the template was <code>&lt;t:pagelink&gt;</code>, or if the template tag included the attribute <code>t:type="pagelink"</code>, then you would see an exception.</p><p>By contrast, <code>@InjectComponent</code> expects the component to be already defined, and doesn't allow any configuration of it:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[  &lt;t:form t:id=&quot;login&quot;&gt; .... &lt;/t:form&gt;
 ]]></script>
-</div></div>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-  @InjectComponent
+</div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[  @InjectComponent
   private Form login;
 ]]></script>
-</div></div>
-
-<p>Again, we're matching the field name to the component id, and you would get an error if the component is not defined in the template.</p>
-
-<h3 id="InjectionFAQ-What'sthedifferencebetweenthe@InjectPageand@InjectContainerannotations?">What's the difference between the <code>@InjectPage</code> and <code>@InjectContainer</code> annotations?</h3>
-
-<p>The <code>@InjectPage</code> annotation is used to inject some page in the application into a field of some other page.  You often see it used from event handler methods:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-  @InjectPage
+</div></div><p>Again, we're matching the field name to the component id, and you would get an error if the component is not defined in the template.</p><h3 id="InjectionFAQ-What'sthedifferencebetweenthe@InjectPageand@InjectContainerannotations?">What's the difference between the <code>@InjectPage</code> and <code>@InjectContainer</code> annotations?</h3><p>The <code>@InjectPage</code> annotation is used to inject some page in the application into a field of some other page. You often see it used from event handler methods:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[  @InjectPage
   private ConfirmRegistration confirmRegistration;
 
   Object onSuccessFromRegistrationForm()
@@ -136,43 +103,16 @@ table.ScrollbarTable td.ScrollbarNextIco
     return confirmRegistration;
   }
 ]]></script>
-</div></div>
-
-<p>This code pattern is used to configure peristent properties of a page before returning it; Tapestry will send a client redirect to the page to present the data.</p>
-
-<p><code>@InjectContainer</code> can be used inside a component or a mixin.  In a component, it injects the immediate container of the component; this is often the top-level page object.</p>
-
-<p>In a mixin, it injects the component to which the mixin is attached.</p>
-
-<h3 id="InjectionFAQ-IgetanexceptionbecauseIhavetwoserviceswiththesameinterface,howdoIhandlethis?">I get an exception because I have two services with the same interface, how do I handle this?</h3>
-
-<p>It's not uncommon to have two or more services that implement the exact same interface. When you inject, you might start by just identifying the type of service to inject:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-	@Inject
+</div></div><p>This code pattern is used to configure peristent properties of a page before returning it; Tapestry will send a client redirect to the page to present the data.</p><p><code>@InjectContainer</code> can be used inside a component or a mixin. In a component, it injects the immediate container of the component; this is often the top-level page object.</p><p>In a mixin, it injects the component to which the mixin is attached.</p><h3 id="InjectionFAQ-IgetanexceptionbecauseIhavetwoserviceswiththesameinterface,howdoIhandlethis?">I get an exception because I have two services with the same interface, how do I handle this?</h3><p>It's not uncommon to have two or more services that implement the exact same interface. When you inject, you might start by just identifying the type of service to inject:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[	@Inject
 	private ComponentEventResultProcessor processor;
 ]]></script>
-</div></div>
-
-<p>Which results in the error: <strong>Service interface org.apache.tapestry5.services.ComponentEventResultProcessor is matched by 3 services: AjaxComponentEventResultProcessor, ComponentEventResultProcessor, ComponentInstanceResultProcessor. Automatic dependency resolution requires that exactly one service implement the interface.</strong></p>
-
-<p>We need more information than just the service interface type in order to identify which of the three services to inject. One possibility is to inject with the correct service id:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-	@InjectService(&quot;ComponentEventResultProcessor&quot;)
+</div></div><p>Which results in the error: <strong>Service interface org.apache.tapestry5.services.ComponentEventResultProcessor is matched by 3 services: AjaxComponentEventResultProcessor, ComponentEventResultProcessor, ComponentInstanceResultProcessor. Automatic dependency resolution requires that exactly one service implement the interface.</strong></p><p>We need more information than just the service interface type in order to identify which of the three services to inject. One possibility is to inject with the correct service id:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[	@InjectService(&quot;ComponentEventResultProcessor&quot;)
 	private ComponentEventResultProcessor processor;
 ]]></script>
-</div></div>
-
-<p>This works ... but it is clumsy. If the service id, "ComponentEventResultProcessor", ever changes, this code will break. It's not <em>refactoring safe</em>.</p>
-
-<p>Instead, we should use marker annotations.  If we look at <code>TapestryModule</code>, where the ComponentEventResultProcessor service is defined, we'll see it identifies the necessary markers:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-    @Marker(
+</div></div><p>This works ... but it is clumsy. If the service id, "ComponentEventResultProcessor", ever changes, this code will break. It's not <em>refactoring safe</em>.</p><p>Instead, we should use marker annotations. If we look at <code>TapestryModule</code>, where the ComponentEventResultProcessor service is defined, we'll see it identifies the necessary markers:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[    @Marker(
     { Primary.class, Traditional.class })
     public ComponentEventResultProcessor buildComponentEventResultProcessor(
             Map&lt;Class, ComponentEventResultProcessor&gt; configuration)
@@ -180,110 +120,13 @@ table.ScrollbarTable td.ScrollbarNextIco
         return constructComponentEventResultProcessor(configuration);
     }
 ]]></script>
-</div></div>
-
-<p>When a service has marker annotations, the annotations present at the <em>point of injection</em> (the field, method parameter, or constructor parameter) are used to select a matching service.  The list of services that match by type is then filtered to only include services that have all of the marker annotations present at the point of injection.</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[
-    @Inject
+</div></div><p>When a service has marker annotations, the annotations present at the <em>point of injection</em> (the field, method parameter, or constructor parameter) are used to select a matching service. The list of services that match by type is then filtered to only include services that have all of the marker annotations present at the point of injection.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[    @Inject
 	@Traditional @Primary
 	private ComponentEventResultProcessor processor;
 ]]></script>
-</div></div>
-
-<p>The two marker annotations, <code>@Traditional</code> and <code>@Primary</code>, ensure that only a single service matches.</p>
-
-<h3 id="InjectionFAQ-What'sthedifferencebetween@Injectand@Environmental?">What's the difference between <code>@Inject</code> and <code>@Environmental</code>?</h3>
-
-<p><code>@Inject</code> is relatively general; it can be used to inject resources specific to a page or component (such as ComponentResources, Logger, or Messages), or it can inject services or other objects obtained from the Tapestry IoC container.  Once the page is loaded, the values for these injections never change.</p>
-
-<p><code>@Environmental</code> is different; it exposes a request-scoped, dynamically bound value</p><p></p><p>&lt;style type='text/css'&gt;
-.FootnoteMarker, .FootnoteNum a {
-  background: transparent url(/confluence/download/resources/com.adaptavist.confluence.footnoteMacros:footnote/gfx/footnote.png) no-repeat top right;
-  padding: 1px 2px 0px 1px;
-  border-left: 1px solid #8898B8;
-  border-bottom: 1px solid #6B7C9B;
-  margin: 1px;
-  text-decoration: none;
-}
-.FootnoteNum a {
-  margin-top: 2px;
-  margin-right: 0px;
-}
-.FootnoteNum {
-  font-size: x-small;
-  text-align: right;
-  padding-bottom: 4px;
-}
-.footnote-th1 {
-  text-align: right;
-}
-.Footnote {
-  padding-left: 7px;
-  margin-bottom: 4px;
-  border: 1px none #DDDDDD;
-  writingMode: tb-rl;
-}
-.accessibility {
-     display: none;
-     visibility: hidden;
-}
-@media aural,braille,embossed {
-        .FootnoteMarker, .FootnoteNum a {
-         border: 1px solid #000000;
-         background: #ffffff none;
-    }
-    .accessibility {
-         display: run-in;
-         visibility: visible;
-    }
-}
-&lt;/style&gt;
-&lt;script type='text/javascript' language='JavaScript'&gt;
-//&lt;!--\n
-var effectInProgress = {};
-var despamEffect = function (id,effectType,duration) {
-  if ((effectInProgress[id]) || (typeof(Effect)=="undefined") || (typeof(Effect[effectType])=="undefined")) return;
-  new Effect[effectType](id);
-  effectInProgress[id]=true;
-  setTimeout('effectInProgress[\"'+id+'\"]=false;',duration*1000);
-};
-var oldFootnoteId = '';
-var footnoteHighlight = function(id,pulsateNum) {
-  if (oldFootnoteId!='') document.getElementById('Footnote'+oldFootnoteId).style['borderStyle'] = 'none';
-  oldFootnoteId = id;
-  document.getElementById('Footnote'+id).style['borderStyle'] = 'solid';
-  despamEffect('Footnote'+id,'Highlight',1)
-  if (pulsateNum) despamEffect('FootnoteNum'+id,'Pulsate',3)
-}
-var footnoteMarkerHighlight = function(id) {
-  if (oldFootnoteId!='') document.getElementById('Footnote'+oldFootnoteId).style['borderStyle'] = 'none';
-  oldFootnoteId = '';
-  despamEffect('FootnoteMarker'+id,'Pulsate',3)
-}
-//--&gt;
-&lt;/script&gt;
-
-<sup id="FootnoteMarker1">
-    <a shape="rect" class="FootnoteMarker" name="FootnoteMarker1" href="#Footnote1" onclick="footnoteHighlight(&quot;1&quot;,true);" alt="Footnote: Click here to display the footnote" title="Footnote: Click here to display the footnote">
-            1
-    </a>
-</sup>
-</p><p></p>.  <p></p>
-
-<ul><li>Request scoped: different threads (processing different requests) will see different values when reading the field.</li><li>Dynamically bound: the value is explicitly placed into the Environment, and can be overridden at any time.</li></ul>
-
-
-<p>Environmentals are a form of loosely connected communication between an outer component (or even a service) and an inner component.  Example: the Form component places a <code>FormSupport</code> object into the environment.  Other components, such as TextField, use the <code>FormSupport</code> when rendering to perform functions such as allocate unique control names or register client-side validations.  The TextField doesn't require that the Form component be the immediate container component, or even an ancestor: a Form on one page may, indirectly, communicate with a TextField on some entirely different page. Neither component directly links to the other, the <code>FormSupport</code> is the conduit that connects them.</p>
-
-<h3 id="InjectionFAQ-Butwait...IseeIusedthe@Injectannotationanditstillworked.Whatgives?">But wait ... I see I used the <code>@Inject</code> annotation and it still worked. What gives?</h3>
-
-<p>In certain cases, Tapestry exposes a service (which can be injected) that is a proxy to the environmental; this is primarily for common environmentals, such as <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>, that may be needed outside of component classes.  You can see this in TapestryModule:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
-    /**
+</div></div><p>The two marker annotations, <code>@Traditional</code> and <code>@Primary</code>, ensure that only a single service matches.</p><h3 id="InjectionFAQ-What'sthedifferencebetween@Injectand@Environmental?">What's the difference between <code>@Inject</code> and <code>@Environmental</code>?</h3><p><code>@Inject</code> is relatively general; it can be used to inject resources specific to a page or component (such as ComponentResources, Logger, or Messages), or it can inject services or other objects obtained from the Tapestry IoC container. Once the page is loaded, the values for these injections never change.</p><p><code>@Environmental</code> is different; it exposes a request-scoped, dynamically bound value:</p><ul><li>"Request scoped": different threads (processing different requests) will see different values when reading the field.</li><li>"Dynamically bound": the value is explicitly placed into the Environment, and can be overridden at any time.</li></ul><p>Environmenta
 ls are a form of loosely connected communication between an outer component (or even a service) and an inner component. Example: the Form component places a <code>FormSupport</code> object into the environment. Other components, such as TextField, use the <code>FormSupport</code> when rendering to perform functions such as allocate unique control names or register client-side validations. The TextField doesn't require that the Form component be the immediate container component, or even an ancestor: a Form on one page may, indirectly, communicate with a TextField on some entirely different page. Neither component directly links to the other, the <code>FormSupport</code> is the conduit that connects them.</p><p>The term "Environmental" was chosen as the value "comes from the environment".</p><h3 id="InjectionFAQ-Butwait...IseeIusedthe@Injectannotationanditstillworked.Whatgives?">But wait ... I see I used the <code>@Inject</code> annotation and it still worked. What gives?</h3><p>In c
 ertain cases, Tapestry exposes a service (which can be injected) that is a proxy to the environmental; this is primarily for common environmentals, such as <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>, that may be needed outside of component classes. You can see this in TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[    /**
      * Builds a proxy to the current {@link JavaScriptSupport} inside this thread&#39;s {@link Environment}.
      * 
      * @since 5.2.0
@@ -293,32 +136,13 @@ var footnoteMarkerHighlight = function(i
         return environmentalBuilder.build(JavaScriptSupport.class);
     }
 ]]></script>
-</div></div>
-
-<p>This kind of logic is based on the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/EnvironmentalShadowBuilder.html">EnvironmentalShadowBuilder</a> service.</p>
-
-<h3 id="InjectionFAQ-Ok,butRequestisasingletonservice,notanenvironmental,andIcaninjectthat.IsTapestryreallythreadsafe?">Ok, but Request is a singleton service, not an environmental, and I can inject that. Is Tapestry really thread safe?</h3>
-
-<p>Yes, of course Tapestry is thread safe.  The Request service is another special case, as seen in TapestryModule:</p>
-
-<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[
-    public Request buildRequest()
+</div></div><p>This kind of logic is based on the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/EnvironmentalShadowBuilder.html">EnvironmentalShadowBuilder</a> service.</p><h3 id="InjectionFAQ-Ok,butRequestisasingletonservice,notanenvironmental,andIcaninjectthat.IsTapestryreallythreadsafe?">Ok, but Request is a singleton service, not an environmental, and I can inject that. Is Tapestry really thread safe?</h3><p>Yes, of course Tapestry is thread safe. The Request service is another special case, as seen in TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent panelContent pdl">
+<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[    public Request buildRequest()
     {
         return shadowBuilder.build(requestGlobals, &quot;request&quot;, Request.class);
     }
 ]]></script>
-</div></div>
-
-<p><a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html">RequestGlobals</a> is a per-thread service.  The Request service is a global singleton created by the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PropertyShadowBuilder.html">PropertyShadowBuilder</a> service, but is just a proxy. It has no internal state; invoking a method on the Request service just turns around and extracts the Request object from the per-thread RequestGlobals and invokes the same method there.</p>
-
-<h3 id="InjectionFAQ-Iuse@Injectonafieldtoinjectaservice,butthefieldisstillnull,whathappened?">I use <code>@Inject</code> on a field to inject a service, but the field is still null, what happened?</h3>
-
-<p>This can happen when you use the wrong <code>@Inject</code> annotation; for example, com.google.inject.Inject instead of org.apache.tapestry5.ioc.annotations.Inject.  This can occur when you have TestNG on the classpath, for example, and your IDE is too helpful.  Double check your imports when things seem weird.</p>
-
-<p>Also remember that <code>@Inject</code> on fields works for components and for service implementations or other objects that Tapestry instantiates, but not on arbitrary objects (that are created via Java's new keyword).</p>
-
-<style type="text/css">/*<![CDATA[*/
+</div></div><p><a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html">RequestGlobals</a> is a per-thread service. The Request service is a global singleton created by the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PropertyShadowBuilder.html">PropertyShadowBuilder</a> service, but is just a proxy. It has no internal state; invoking a method on the Request service just turns around and extracts the Request object from the per-thread RequestGlobals and invokes the same method there.</p><h3 id="InjectionFAQ-Iuse@Injectonafieldtoinjectaservice,butthefieldisstillnull,whathappened?">I use <code>@Inject</code> on a field to inject a service, but the field is still null, what happened?</h3><p>This can happen when you use the wrong <code>@Inject</code> annotation; for example, com.google.inject.Inject instead of org.apache.tapestry5.i
 oc.annotations.Inject. This can occur when you have TestNG on the classpath, for example, and your IDE is too helpful. Double check your imports when things seem weird.</p><p>Also remember that <code>@Inject</code> on fields works for components and for service implementations or other objects that Tapestry instantiates, but not on arbitrary objects (that are created via Java's new keyword).</p><style type="text/css">/*<![CDATA[*/
 table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
 table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
 table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}
@@ -326,16 +150,7 @@ table.ScrollbarTable td.ScrollbarParent 
 table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
 table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
 
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="ajax-components-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="ajax-components-faq.html">Ajax Components FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control FAQ</a></td><td colspan="1" rowspan="1" 
 class="ScrollbarNextIcon"><a shape="rect" href="tapestry-inversion-of-control-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div>
-
-<hr>
-<p></p><p></p><p><table class="Footnotes" style="width: 100%; border:none;" cellspacing="0" cellpadding="0" summary="This table contains one or more notes for references made elsewhere on the page."><caption class="accessibility">Footnotes</caption><thead class="accessibility"><tr class="accessibility"><th colspan="1" rowspan="1" class="accessibility" id="footnote-th1">Reference</th><th colspan="1" rowspan="1" class="accessibility" id="footnote-th2">Notes</th></tr></thead><tbody><tr name="Footnote1"><td colspan="1" rowspan="1" valign="top" class="FootnoteNum" headings="footnote-th1">
-        <a shape="rect" id="FootnoteNum1" href="#FootnoteMarker1" onclick="footnoteMarkerHighlight(&quot;1&quot;);" onmouseover="footnoteHighlight(&quot;1&quot;,false);" alt="Footnote: Click to return to reference in text" title="Footnote: Click to return to reference in text">
-            1
-        </a>
-      </td><td colspan="1" rowspan="1" valign="top" class="Footnote" id="Footnote1" width="100%" headings="footnote-th2">
-          . The term "Environmental" was chosen as the value "comes from the environment", whatever that means. A name more evocative of its function still has not occurred to the Tapestry team!
-      </td></tr></tbody></table></p><p></p> <p></p></div>
+/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="ajax-components-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="ajax-components-faq.html">Ajax Components FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control FAQ</a></td><td colspan="1" rowspan="1" 
 class="ScrollbarNextIcon"><a shape="rect" href="tapestry-inversion-of-control-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/limitations.html
==============================================================================
--- websites/production/tapestry/content/limitations.html (original)
+++ websites/production/tapestry/content/limitations.html Sun Mar  2 22:20:37 2014
@@ -77,7 +77,7 @@ table.ScrollbarTable td.ScrollbarParent 
 table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
 table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
 
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="request-processing-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="request-processing-faq.html">Request Processing FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="specific-errors-faq.html">Specific Errors FAQ</a></td><td colspan="1" rowspan="1" class="ScrollbarNex
 tIcon"><a shape="rect" href="specific-errors-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div><h2 id="Limitations-Limitations">Limitations</h2><h3 id="Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I add new components to an existing page dynamically?</h3><p>The short answer here is: <strong>you don't</strong>. The long answer here is <strong>you don't have to, to get the behavior you desire</strong>.</p><p>One of Tapestry basic values is high scalability: this is expressed in a number of ways, reflecting scalability concerns within a single server, and within a cluster of servers.</p><p>Although you code Tapestry pages and components as if they were ordinary POJOs (<span style="line-height: 1.4285715;">Plain Old Java Objects -- Tapestry does not require you to extend any base classes or implement any special interfaces)</span><span style="line-heigh
 t: 1.4285715;">, as deployed by Tapestry they are closer to a traditional servlet: a single instance of each page services requests from multiple threads. Behind the scenes, Tapestry transforms you code, rewriting it on the fly.</span></p><p>&#160;</p><p>What this means is that <em>any</em> incoming request must be handled by a <em>single page instance</em>. Therefore, Tapestry enforces the concept of <strong>static structure, dynamic behavior</strong>.</p><p>Tapestry provides quite a number of ways to vary what content is rendered, well beyond simple conditionals and loops. It is possible to "drag in" components from other pages when rendering a page (other FAQs will expand on this concept). The point is, that although a Tapestry page's structure is very rigid, the order in which the components of the page render does not have to be top to bottom.</p><h3 id="Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why doesn't my service implementation reload when I change
  it?</h3><p>Main article: <a shape="rect" href="service-implementation-reloading.html">Service Implementation Reloading</a></p><p>Live service reloading has some limitations:</p><ul><li>The service must define a service interface.</li><li>The service implementation must be on the file system (not inside a JAR).</li><li>The implementation must be instantiated by Tapestry, not inside code (even code inside a module class).</li><li>The service must use the default <a shape="rect" href="defining-tapestry-ioc-services.html#DefiningTapestryIOCServices-ServiceScope">scope</a> (reloading of perthread scopes is not supported).</li></ul><p>Consider the following example module:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="request-processing-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="request-processing-faq.html">Request Processing FAQ</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="frequently-asked-questions.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="frequently-asked-questions.html">Frequently Asked Questions</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="specific-errors-faq.html">Specific Errors FAQ</a></td><td colspan="1" rowspan="1" class="ScrollbarNex
 tIcon"><a shape="rect" href="specific-errors-faq.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div><h2 id="Limitations-Limitations">Limitations</h2><h3 id="Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I add new components to an existing page dynamically?</h3><p>The short answer here is: <strong>you don't</strong>. The long answer here is <strong>you don't have to, to get the behavior you desire</strong>.</p><p>One of Tapestry basic values is high scalability: this is expressed in a number of ways, reflecting scalability concerns within a single server, and within a cluster of servers.</p><p>Although you code Tapestry pages and components as if they were ordinary POJOs (<span style="line-height: 1.4285715;">Plain Old Java Objects -- Tapestry does not require you to extend any base classes or implement any special interfaces)</span><span style="line-heigh
 t: 1.4285715;">, as deployed by Tapestry they are closer to a traditional servlet: a single instance of each page services requests from multiple threads. Behind the scenes, Tapestry transforms you code, rewriting it on the fly.</span></p><p>What this means is that <em>any</em> incoming request must be handled by a <em>single page instance</em>. Therefore, Tapestry enforces the concept of <strong>static structure, dynamic behavior</strong>.</p><p>Tapestry provides quite a number of ways to vary what content is rendered, well beyond simple conditionals and loops. It is possible to "drag in" components from other pages when rendering a page (other FAQs will expand on this concept). The point is, that although a Tapestry page's structure is very rigid, the order in which the components of the page render does not have to be top to bottom.</p><h3 id="Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why doesn't my service implementation reload when I change it?</h3><p>M
 ain article: <a shape="rect" href="service-implementation-reloading.html">Service Implementation Reloading</a></p><p>Live service reloading has some limitations:</p><ul><li>The service must define a service interface.</li><li>The service implementation must be on the file system (not inside a JAR).</li><li>The implementation must be instantiated by Tapestry, not inside code (even code inside a module class).</li><li>The service must use the default <a shape="rect" href="defining-tapestry-ioc-services.html#DefiningTapestryIOCServices-ServiceScope">scope</a> (reloading of perthread scopes is not supported).</li></ul><p>Consider the following example module:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <script class="theme: Default; brush: java; gutter: true" type="syntaxhighlighter"><![CDATA[public static void bind(ServiceBinder binder)
 {
   binder.bind(ArchiveService.class, ArchiveServiceImpl.class);
@@ -92,7 +92,7 @@ public static JobQueue buildJobQueue(Mes
   return service;
 }
 ]]></script>
-</div></div><p>ArchiveService is reloadable, because Tapestry instantiates <code>ArchiveServiceImpl</code> itself. On the other hand, Tapestry invokes <code>buildJobQueue()</code> and it is your code inside the method that instantiates <code>JobQueueImpl</code>, so the JobQueue service will not be reloadable.</p><p>Finally, only classes whose class files are stored directly on the file system, and not packaged inside JARs, are ever reloadable ... generally, only the services of the application being built (and not services from libraries) will be stored on the file system. This reflects the intent of reloading: as an agile development tool, but not something to be used in deployment.</p><h3 id="Limitations-HowdoIrunmultipleTapestryapplicationsinthesamewebapplication?">How do I run multiple Tapestry applications in the same web application?</h3><p>This is not supported; there's only one place to identify the application root package, so even configuring multiple filters into multiple
  folders will not work.</p><p>Support for multiple Tapestry applications in the same web application was a specific non-goal in Tapestry 5 (it needlessly complicated Tapestry 4). Given how loosely connected Tapestry 5 pages are from each other, there doesn't seem to be an advantage to doing so ... and certainly, in terms of memory utilization, there is a significant down side, were it even possible.</p><style type="text/css">/*<![CDATA[*/
+</div></div><p>ArchiveService is reloadable, because Tapestry instantiates <code>ArchiveServiceImpl</code> itself. On the other hand, Tapestry invokes <code>buildJobQueue()</code> and it is your code inside the method that instantiates <code>JobQueueImpl</code>, so the JobQueue service will not be reloadable.</p><p>Finally, only classes whose class files are stored directly on the file system, and not packaged inside JARs, are ever reloadable ... generally, only the services of the application being built (and not services from libraries) will be stored on the file system. This reflects the intent of reloading: as an agile development tool, but not something to be used in deployment.</p><h3 id="Limitations-HowdoIrunmultipleTapestryapplicationsinthesamewebapplication?">How do I run multiple Tapestry applications in the same web application?</h3><p>Running multiple Tapestry 5 applications is not supported; there's only one place to identify the application root package, so even config
 uring multiple filters into multiple folders will not work.</p><p>Support for multiple Tapestry applications in the same web application was a specific non-goal in Tapestry 5 (it needlessly complicated Tapestry 4). Given how loosely connected Tapestry 5 pages are from each other, there doesn't seem to be an advantage to doing so ... and certainly, in terms of memory utilization, there is a significant down side, were it even possible.</p><p>You&#160;<em>can</em>&#160;<span style="color: rgb(0,0,0);">run a Tapestry 4 app and a Tapestry 5 app side-by-side (the package names are different, for just this reason), but they know nothing of each other, and can't interact directly. This is just like the way you could have a single WAR with multiple servlets; the different applications can only communicate via URLs, or shared state in the HttpSession.</span></p><style type="text/css">/*<![CDATA[*/
 table.ScrollbarTable  {border: none;padding: 3px;width: 100%;padding: 3px;margin: 0px;background-color: #f0f0f0}
 table.ScrollbarTable td.ScrollbarPrevIcon {text-align: center;width: 16px;border: none;}
 table.ScrollbarTable td.ScrollbarPrevName {text-align: left;border: none;}