Author: buildbot
Date: Fri Feb 16 03:21:19 2018
New Revision: 1025456

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/assets.html
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/class-reloading.html
    websites/production/tapestry/content/component-classes.html
    websites/production/tapestry/content/component-reference.html
    websites/production/tapestry/content/component-templates.html
    websites/production/tapestry/content/project-layout.html

Modified: websites/production/tapestry/content/assets.html
==============================================================================
--- websites/production/tapestry/content/assets.html (original)
+++ websites/production/tapestry/content/assets.html Fri Feb 16 03:21:19 2018
@@ -145,10 +145,10 @@
 </div>
 
 
-<p>Assets can be in one of three places within a Tapestry app:</p><ol><li>In 
the <strong>web application's context folder</strong>, stored inside the web 
application WAR file in the usual JEE fashion. In a project following Maven's 
directory layout conventions, this would be src/main/webapp or a subdirectory 
of it (but&#160;<em>not</em> under src/main/webapp/WEB-INF).</li><li>For 
Tapestry 5.4 and later: under <strong><code>META-INF</code></strong><code>, 
with JavaScript modules under <strong>META-INF/modules</strong> and other 
assets under <strong>META-INF/assets</strong>. This would be 
src/main/resources/META-INF/modules 
and&#160;<code>src/main/resources/META-INF/assets</code> if following Maven 
directory conventions.</code></li><li>On the <strong>classpath</strong>, with 
your Java class files. <em>This is deprecated in Tapestry 5.4 and later (with a 
warning).</em> If following Maven directory conventions, this would correspond 
to a package-named subdirectory under src/main/resourc
 es/, such as src/main/resources/com/example/myapp/pages).</li></ol><h3 
id="Assets-ReferencingAssetsfromTemplates">Referencing Assets from 
Templates</h3><p>For referencing assets from templates, two <a  
href="assets.html">binding prefixes</a> exist: "context:" and "asset:". The 
"context:" prefix matches assets in the web application's context folder, and 
the "asset:" prefix is for assets from the classpath.</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 
1px;"><b>src/main/webapp/com/example/myapp/images/tapestry_banner.gif</b></div><div
 class="codeContent panelContent pdl">
+<p>Assets can be in one of three places within a Tapestry app:</p><ol><li>In 
the <strong>web application's context folder</strong>, stored inside the web 
application WAR file in the usual JEE fashion. In a project following Maven's 
directory layout conventions, this would be src/main/webapp or a subdirectory 
of it (but&#160;<em>not</em> under src/main/webapp/WEB-INF).</li><li>For 
Tapestry 5.4 and later: under <strong><code>META-INF</code></strong><code>, 
with JavaScript modules under <strong>META-INF/modules</strong> and other 
assets under <strong>META-INF/assets</strong>. This would be 
src/main/resources/META-INF/modules 
and&#160;<code>src/main/resources/META-INF/assets</code> if following Maven 
directory conventions.</code></li><li>On the <strong>classpath</strong>, with 
your Java class files. <em>This is deprecated in Tapestry 5.4 and later (with a 
warning).</em> If following Maven directory conventions, this would correspond 
to a package-named subdirectory under src/main/resourc
 es/, such as src/main/resources/com/example/myapp/pages).</li></ol><h3 
id="Assets-ReferencingAssetsfromTemplates">Referencing Assets from 
Templates</h3><p>For referencing assets from templates, two <a  
href="component-parameters.html">binding prefixes</a> exist: "context:" and 
"asset:". The "context:" prefix matches assets in the web application's context 
folder, and the "asset:" prefix is for assets from the classpath.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/webapp/com/example/myapp/images/tapestry_banner.gif</b></div><div
 class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;img src="${context:images/tapestry_banner.gif}"/&gt;
 </pre>
-</div></div><div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This is an example of using a 
<em>template expansion</em> inside an ordinary element (rather than a 
component).</p></div></div><p>If you don't provide either prefix, "asset:" is 
assumed.</p><p>Also note that in older code you may occasionally see 
${asset:context:...}. That means the same thing as ${context:...}.</p><h3 
id="Assets-AssetsinComponentClasses">Assets in Component Classes</h3><p>Assets 
are available to your code as instances of the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Asset.html";>Asset</a>
 interface.</p><p>Components access assets via <a  
href="assets.html">injection</a>, using the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5
 /ioc/annotations/Inject.html">Inject</a> annotation, which allows Assets to be 
injected into components as read-only properties. The path to the resource is 
specified using the Path annotation:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This is an example of using a 
<em>template expansion</em> inside an ordinary element (rather than a 
component).</p></div></div><p>If you don't provide either prefix, "asset:" is 
assumed.</p><p>Also note that in older code you may occasionally see 
${asset:context:...}. That means the same thing as ${context:...}.</p><h3 
id="Assets-AssetsinComponentClasses">Assets in Component Classes</h3><p>Assets 
are available to your code as instances of the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Asset.html";>Asset</a>
 interface.</p><p>Components access assets via <a  
href="injection.html">injection</a>, using the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapest
 ry5/ioc/annotations/Inject.html">Inject</a> annotation, which allows Assets to 
be injected into components as read-only properties. The path to the resource 
is specified using the Path annotation:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Inject
 @Path("context:images/tapestry_banner.gif")
 private Asset banner;
@@ -163,7 +163,7 @@ private Asset icon;
 @Path("${skin.root}/style.css")
 private Asset style;
 </pre>
-</div></div><div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>The use of the <code>${...</code>} 
syntax here is a <em>symbol expansion</em> (because it occurs in an annotation 
in Java code), rather than a <em>template expansion</em> (which occurs only in 
Tapestry template files).</p></div></div><p>An override of the skin.root symbol 
would affect all references to the named asset.</p><h3 
id="Assets-LocalizationofAssets">Localization of Assets</h3><p>Main Article: <a 
 href="assets.html">Assets</a></p><p>Assets are localized; Tapestry will search 
for a variation of the file appropriate to the effective locale for the 
request. In the previous example, a German user of the application may see a 
file named <code>edit_de.png</code> (if such a file exists).</p><h3 
id="Assets-NewAssetDomains">New Asset Domains</h3><p>I
 f you wish to create new domains for assets, for example to allow assets to be 
stored on the file system or in a database, you may define a new <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/AssetFactory.html";>AssetFactory</a>
 and contribute it to the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/AssetSource.html";>AssetSource</a>
 service configuration.</p><h3 
id="Assets-AssetFingerprinting(Tapestry5.3andearlier)">Asset Fingerprinting 
(Tapestry 5.3 and earlier)</h3><p>Tapestry creates a new URL for assets 
(whether context or classpath). The URL is of the form 
/assets/<strong>version</strong>/<strong>folder</strong>/<strong>path</strong>.</p><ul><li><strong>version</strong>:
 Application version number, defined by the 
<code>tapestry.application-version</code> symbol in your application module 
(normally AppModule.java). The default is a random hex number.</li><li><strong>
 folder</strong>: Identifies the library containing the asset, or "ctx" for a 
context asset, or "stack" (used when combining multiple JavaScript files into a 
single virtual asset).</li><li><strong>path</strong>: The path below the root 
package of the library to the specific asset file.</li></ul><h3 
id="Assets-AssetFingerprinting(Tapestry5.4andlater)">Asset 
Fingerprinting<span>&#160;(Tapestry 5.4 and later)</span></h3><p>Tapestry 5.4 
changes how Asset URLs are constructed. The version number is now 
a&#160;<em>content fingerprint</em>, a hash of the actual content of the 
asset.</p><p>Assets get a far-future expires header. It is no longer necessary 
or desirable to change the application version number.</p><p>During development 
or production, if an asset is changed in any way, it will have a new content 
fingerprint and will appear, to the browser, to be an entirely new immutable 
resource.</p><h3 id="Assets-CSSLinkRewriting">CSS Link Rewriting</h3><p>It is 
frequently the case that CSS fi
 les will include links to other files, such as background images, using 
the&#160;<code>url</code>() value syntax. Under 5.4, the URL for the CSS file 
and the targeted file would be broken, due to the inclusions of the CSS file's 
content hash fingerprint. To fix this, Tapestry parses CSS files, locates 
the&#160;<code>url()</code> directives, and rewrites the URLs to be absolute 
(including the targeted file's content hash fingerprint).</p><h3 
id="Assets-PerformanceNotes">Performance Notes</h3><p>Assets are expected to be 
entirely static (not changing while the application is deployed). This allows 
Tapestry to perform some important performance optimizations.</p><p>Tapestry 
GZIP compresses the content of all assets &#8211; if the asset is compressible, 
the client supports it, and you don't <a  href="assets.html">explicitly disable 
it</a>.</p><p><span>Further, the asset will get a </span><em>far future expires 
header</em><span>, which will encourage the client browser to cache the asset
 .</span></p><p>For Talestry 5.3 and earlier, you should have an explicit 
application version number for any production application. Client browsers will 
aggressively cache downloaded assets; they will usually not even send a request 
to see if the asset has changed once the asset is downloaded the first time. 
Because of this it is <em>very important</em> that each new deployment of your 
application has a new <a  href="assets.html">version number</a>, to force 
existing clients to re-download all assets.</p><h3 
id="Assets-AssetSecurity">Asset Security</h3><div 
class="confluence-information-macro confluence-information-macro-warning"><span 
class="aui-icon aui-icon-small aui-iconfont-error 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This applies to how Tapestry 5.3 
and earlier manage classpath assets; Tapestry 5.4 introduces another system 
which doesn't have this issue.</p></div></div><p>Because Tapestry directly 
exposes files on the classp
 ath to the clients, some thought has gone into ensuring that malicious clients 
are not able to download assets that should not be visible to them.</p><p>First 
off all, there's a package limitation: classpath assets are only visible if 
there's a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/LibraryMapping.html";>LibraryMapping</a>
 for them, and the library mapping substitutes for the initial folders on the 
classpath. Since the most secure assets, things like 
<code>hibernate.cfg.xml</code> are located in the unnamed package, they are 
always off limits.</p><p>But what about other files on the classpath? Imagine 
this scenario:</p><ul><li>Your Login page exposes a classpath asset, 
<code>icon.png</code>.</li><li><p>A malicious client copies the URL, 
<code>/assets/1.0.0/app/pages/icon.png (</code><span>which would indicate that 
the Login page is actually inside a library, which is unlikely. More likely, 
icon.png is a context asset a
 nd the malicious user guessed the path for Login.class by looking at the 
Tapestry source code.)&#160;</span><span>and changes the file name to 
</span><code>Login.class</code><span>.</span></p></li><li><p>The client 
decompiles the class file and spots your secret emergency password: goodbye 
security! (<span>Never create such back doors, of 
course!)</span></p></li></ul><p>Fortunately, this can't happen. Files with 
extension ".class" are secured; they must be accompanied in the URL with a 
query parameter that is the MD5 hash of the file's contents. If the query 
parameter is absent, or doesn't match the actual file's content, the request is 
rejected.</p><p>When your code exposes an Asset that is secured, Tapestry 
generates a URL that automatically includes MD5 hash query parameter. The 
malicious user is locked out of access to the files. (The only way they could 
generate the MD5 hash is if<span> they somehow already have the files, in which 
case they don't need to download them again an
 yway.)</span></p><p>By default, Tapestry secures file extensions ".class', 
".tml" and ".properties". The list can be extended by contributing to the <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ResourceDigestGenerator.html";>ResourceDigestGenerator</a>
 service:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent 
pdl">
+</div></div><div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>The use of the <code>${...</code>} 
syntax here is a <em>symbol expansion</em> (because it occurs in an annotation 
in Java code), rather than a <em>template expansion</em> (which occurs only in 
Tapestry template files).</p></div></div><p>An override of the skin.root symbol 
would affect all references to the named asset.</p><h3 
id="Assets-LocalizationofAssets">Localization of Assets</h3><p>Main Article: <a 
 href="localization.html">Localization</a></p><p>Assets are localized; Tapestry 
will search for a variation of the file appropriate to the effective locale for 
the request. In the previous example, a German user of the application may see 
a file named <code>edit_de.png</code> (if such a file exists).</p><h3 
id="Assets-NewAssetDomains">New Asset Doma
 ins</h3><p>If you wish to create new domains for assets, for example to allow 
assets to be stored on the file system or in a database, you may define a new 
<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/AssetFactory.html";>AssetFactory</a>
 and contribute it to the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/AssetSource.html";>AssetSource</a>
 service configuration.</p><h3 
id="Assets-AssetFingerprinting(Tapestry5.3andearlier)">Asset Fingerprinting 
(Tapestry 5.3 and earlier)</h3><p>Tapestry creates a new URL for assets 
(whether context or classpath). The URL is of the form 
/assets/<strong>version</strong>/<strong>folder</strong>/<strong>path</strong>.</p><ul><li><strong>version</strong>:
 Application version number, defined by the 
<code>tapestry.application-version</code> symbol in your application module 
(normally AppModule.java). The default is a random hex number.</li>
 <li><strong>folder</strong>: Identifies the library containing the asset, or 
"ctx" for a context asset, or "stack" (used when combining multiple JavaScript 
files into a single virtual asset).</li><li><strong>path</strong>: The path 
below the root package of the library to the specific asset file.</li></ul><h3 
id="Assets-AssetFingerprinting(Tapestry5.4andlater)">Asset 
Fingerprinting<span>&#160;(Tapestry 5.4 and later)</span></h3><p>Tapestry 5.4 
changes how Asset URLs are constructed. The version number is now 
a&#160;<em>content fingerprint</em>, a hash of the actual content of the 
asset.</p><p>Assets get a far-future expires header. It is no longer necessary 
or desirable to change the application version number.</p><p>During development 
or production, if an asset is changed in any way, it will have a new content 
fingerprint and will appear, to the browser, to be an entirely new immutable 
resource.</p><h3 id="Assets-CSSLinkRewriting">CSS Link Rewriting</h3><p>It is 
frequently the case
  that CSS files will include links to other files, such as background images, 
using the&#160;<code>url</code>() value syntax. Under 5.4, the URL for the CSS 
file and the targeted file would be broken, due to the inclusions of the CSS 
file's content hash fingerprint. To fix this, Tapestry parses CSS files, 
locates the&#160;<code>url()</code> directives, and rewrites the URLs to be 
absolute (including the targeted file's content hash fingerprint).</p><h3 
id="Assets-PerformanceNotes">Performance Notes</h3><p>Assets are expected to be 
entirely static (not changing while the application is deployed). This allows 
Tapestry to perform some important performance optimizations.</p><p>Tapestry 
GZIP compresses the content of all assets &#8211; if the asset is compressible, 
the client supports it, and you don't <a  href="configuration.html">explicitly 
disable it</a>.</p><p><span>Further, the asset will get a </span><em>far future 
expires header</em><span>, which will encourage the client browser
  to cache the asset.</span></p><p>For Talestry 5.3 and earlier, you should 
have an explicit application version number for any production application. 
Client browsers will aggressively cache downloaded assets; they will usually 
not even send a request to see if the asset has changed once the asset is 
downloaded the first time. Because of this it is <em>very important</em> that 
each new deployment of your application has a new <a  
href="configuration.html">version number</a>, to force existing clients to 
re-download all assets.</p><h3 id="Assets-AssetSecurity">Asset 
Security</h3><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>This applies to how Tapestry 5.3 
and earlier manage classpath assets; Tapestry 5.4 introduces another system 
which doesn't have this issue.</p></div></div><p>Because Tapestry directly e
 xposes files on the classpath to the clients, some thought has gone into 
ensuring that malicious clients are not able to download assets that should not 
be visible to them.</p><p>First off all, there's a package limitation: 
classpath assets are only visible if there's a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/LibraryMapping.html";>LibraryMapping</a>
 for them, and the library mapping substitutes for the initial folders on the 
classpath. Since the most secure assets, things like 
<code>hibernate.cfg.xml</code> are located in the unnamed package, they are 
always off limits.</p><p>But what about other files on the classpath? Imagine 
this scenario:</p><ul><li>Your Login page exposes a classpath asset, 
<code>icon.png</code>.</li><li><p>A malicious client copies the URL, 
<code>/assets/1.0.0/app/pages/icon.png (</code><span>which would indicate that 
the Login page is actually inside a library, which is unlikely. More likely, ico
 n.png is a context asset and the malicious user guessed the path for 
Login.class by looking at the Tapestry source code.)&#160;</span><span>and 
changes the file name to 
</span><code>Login.class</code><span>.</span></p></li><li><p>The client 
decompiles the class file and spots your secret emergency password: goodbye 
security! (<span>Never create such back doors, of 
course!)</span></p></li></ul><p>Fortunately, this can't happen. Files with 
extension ".class" are secured; they must be accompanied in the URL with a 
query parameter that is the MD5 hash of the file's contents. If the query 
parameter is absent, or doesn't match the actual file's content, the request is 
rejected.</p><p>When your code exposes an Asset that is secured, Tapestry 
generates a URL that automatically includes MD5 hash query parameter. The 
malicious user is locked out of access to the files. (The only way they could 
generate the MD5 hash is if<span> they somehow already have the files, in which 
case they don't need
  to download them again anyway.)</span></p><p>By default, Tapestry secures 
file extensions ".class', ".tml" and ".properties". The list can be extended by 
contributing to the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ResourceDigestGenerator.html";>ResourceDigestGenerator</a>
 service:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent 
pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public static void 
contributeResourceDigestGenerator(Configuration&lt;String&gt; configuration)
 {
     configuration.add("xyz");
@@ -184,7 +184,7 @@ private Asset style;
     &lt;version&gt;5.4&lt;/version&gt;
 &lt;/dependency&gt;
 </pre>
-</div></div></div></div></div></div><p>&#160;</p><p>By adding this dependency, 
all your JavaScript and CSS files will be minimized when <a  
href="assets.html">PRODUCTION_MODE=true</a>. You can force the minimization of 
these files, by changing the value of the constant 
SymbolConstants.MINIFICATION_ENABLED in your module class (usually 
AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent 
pdl">
+</div></div></div></div></div></div><p>&#160;</p><p>By adding this dependency, 
all your JavaScript and CSS files will be minimized when <a  
href="configuration.html">PRODUCTION_MODE=true</a>. You can force the 
minimization of these files, by changing the value of the constant 
SymbolConstants.MINIFICATION_ENABLED in your module class (usually 
AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent 
pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Contribute(SymbolProvider.class)
 @ApplicationDefaults
 public static void 
contributeApplicationDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)

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

Modified: websites/production/tapestry/content/class-reloading.html
==============================================================================
--- websites/production/tapestry/content/class-reloading.html (original)
+++ websites/production/tapestry/content/class-reloading.html Fri Feb 16 
03:21:19 2018
@@ -110,7 +110,7 @@
 </div>
 
 
-<p>One of the best features of Tapestry is automatic reloading of changed 
classes and templates. <em>Page and component</em> classes will automatically 
reload when changed. Likewise, changes to component templates and other related 
resources will also be picked up immediately. In addition, starting in version 
5.2, your service classes will also be reloaded automatically after changes (if 
you're using <a  href="class-reloading.html">Tapestry IoC</a>).</p><h2 
id="ClassReloading-TemplateReloading">Template Reloading</h2><p>When a template 
changes, all page instances (as well as the hierarchy of components below them) 
are discarded and reconstructed with the new template. However, classes are not 
reloaded in this case.</p><h2 id="ClassReloading-ClassReloading">Class 
Reloading</h2><p>On a change to <em>any</em> loaded class from inside a 
controlled package (or any sub-package of a controlled package), Tapestry will 
discard all page instances, and discard the class loader.</p><p><a  href=
 "class-reloading.html">Persistent field data</a> on the pages will usually not 
be affected (as it is stored separately, usually in the session). This allows 
you to make fairly significant changes to a component class even while the 
application continues to run.</p><h2 
id="ClassReloading-PackagesScanned">Packages Scanned</h2><p>Only certain 
classes are subject to reload. Reloading is based on package name; the packages 
that are reloaded are derived from the <a  
href="class-reloading.html">application configuration</a>.</p><p>If your root 
package is <code>org.example.myapp</code>, then only classes in the following 
packages (and their sub-packages) will be scanned for automatic 
reloads:</p><ul><li>org.example.myapp.pages</li><li>org.example.myapp.components</li><li>org.example.myapp.mixins</li><li>org.example.myapp.base</li><li>org.example.myapp.services
 (Tapestry 5.2 and later, with restrictions)</li></ul><p>Starting in Tapestry 
5.2, live class reloading includes service implementati
 on classes. There are some limitations to this. See&#160;<a  
href="service-implementation-reloading.html">Service Implementation 
Reloading</a> for more details.</p><h2 id="ClassReloading-FileSystemOnly">File 
System Only</h2><p>Reloading of classes and other files applies only to files 
that are actually on the file system, and not files obtained from JAR files. 
This is perfect during development, where the files in question are in your 
local workspace. In a deployed application, you are somewhat subject to the 
implementation of your servlet container or application server.</p><h2 
id="ClassReloading-ClassLoaderIssues">Class Loader Issues</h2><p>Tapestry uses 
an extra class loader to load page and component classes.</p><p>When a change 
to an underlying Java class file is detected, Tapestry discards the class 
loader and any pooled page instances.</p><p>You should be careful to not hold 
any references to Tapestry pages or components in other code, such as Tapestry 
IoC services. Holding s
 uch references can cause significant memory leaks, as they can prevent the 
class loader from being reclaimed by the garbage collector.</p><h2 
id="ClassReloading-ClassCastExceptions">ClassCastExceptions</h2><p>Tapestry's 
class loader architecture can cause minor headaches when you make use of a 
services layer, or any time that you pass component instances to objects that 
are not themselves components.</p><p>In such cases you may see 
ClassCastException errors. This is because the same class name, say 
org.example.myapp.pages.Start, exists as two different class instances. One 
class instance is loaded by the web application's default class loader. A 
second class instance has been loaded <em>and transformed</em> by Tapestry's 
reloading class loader.</p><p>Ordinary classes, such as Tapestry IoC Services, 
will be loaded by the default class loader and expect instances to be loaded by 
the same class loader (or a parent).</p><p>The solution to this problem is to 
introduce an interface; the c
 omponent class should implement the interface, and the service should expect 
an instance of the interface, rather than a specific type.</p><p>It is 
important that the interface be loaded by the default class loader. It should 
not be in the pages or components package, but instead be in another package, 
such as services.</p><h2 id="ClassReloading-HandlingReloadsinyourCode">Handling 
Reloads in your Code</h2><p>On occasion, you may need to know when 
invalidations occur, to clear your own cache. For example, if you have a 
binding that creates new classes, the way <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PropertyConduitSource.html";>PropertyConduitSource</a>
 does, you need to discard any cached classes or instances when a change is 
detected in component classes.</p><p>You do this by registering a listener with 
the correct <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tpaestry5/services/
 InvalidationEventHub.html">InvalidationEventHub</a> service.</p><p>For 
example, your service may be in the business of creating new classes based on 
component classes, and keep a cache of those classes:</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<p>One of the best features of Tapestry is automatic reloading of changed 
classes and templates. <em>Page and component</em> classes will automatically 
reload when changed. Likewise, changes to component templates and other related 
resources will also be picked up immediately. In addition, starting in version 
5.2, your service classes will also be reloaded automatically after changes (if 
you're using <a  href="ioc.html">Tapestry IoC</a>).</p><h2 
id="ClassReloading-TemplateReloading">Template Reloading</h2><p>When a template 
changes, all page instances (as well as the hierarchy of components below them) 
are discarded and reconstructed with the new template. However, classes are not 
reloaded in this case.</p><h2 id="ClassReloading-ClassReloading">Class 
Reloading</h2><p>On a change to <em>any</em> loaded class from inside a 
controlled package (or any sub-package of a controlled package), Tapestry will 
discard all page instances, and discard the class loader.</p><p><a  
href="class-reloa
 ding.html">Persistent field data</a> on the pages will usually not be affected 
(as it is stored separately, usually in the session). This allows you to make 
fairly significant changes to a component class even while the application 
continues to run.</p><h2 id="ClassReloading-PackagesScanned">Packages 
Scanned</h2><p>Only certain classes are subject to reload. Reloading is based 
on package name; the packages that are reloaded are derived from the <a  
href="configuration.html">application configuration</a>.</p><p>If your root 
package is <code>org.example.myapp</code>, then only classes in the following 
packages (and their sub-packages) will be scanned for automatic 
reloads:</p><ul><li>org.example.myapp.pages</li><li>org.example.myapp.components</li><li>org.example.myapp.mixins</li><li>org.example.myapp.base</li><li>org.example.myapp.services
 (Tapestry 5.2 and later, with restrictions)</li></ul><p>Starting in Tapestry 
5.2, live class reloading includes service implementation classes. Th
 ere are some limitations to this. See&#160;<a  
href="service-implementation-reloading.html">Service Implementation 
Reloading</a> for more details.</p><h2 id="ClassReloading-FileSystemOnly">File 
System Only</h2><p>Reloading of classes and other files applies only to files 
that are actually on the file system, and not files obtained from JAR files. 
This is perfect during development, where the files in question are in your 
local workspace. In a deployed application, you are somewhat subject to the 
implementation of your servlet container or application server.</p><h2 
id="ClassReloading-ClassLoaderIssues">Class Loader Issues</h2><p>Tapestry uses 
an extra class loader to load page and component classes.</p><p>When a change 
to an underlying Java class file is detected, Tapestry discards the class 
loader and any pooled page instances.</p><p>You should be careful to not hold 
any references to Tapestry pages or components in other code, such as Tapestry 
IoC services. Holding such references
  can cause significant memory leaks, as they can prevent the class loader from 
being reclaimed by the garbage collector.</p><h2 
id="ClassReloading-ClassCastExceptions">ClassCastExceptions</h2><p>Tapestry's 
class loader architecture can cause minor headaches when you make use of a 
services layer, or any time that you pass component instances to objects that 
are not themselves components.</p><p>In such cases you may see 
ClassCastException errors. This is because the same class name, say 
org.example.myapp.pages.Start, exists as two different class instances. One 
class instance is loaded by the web application's default class loader. A 
second class instance has been loaded <em>and transformed</em> by Tapestry's 
reloading class loader.</p><p>Ordinary classes, such as Tapestry IoC Services, 
will be loaded by the default class loader and expect instances to be loaded by 
the same class loader (or a parent).</p><p>The solution to this problem is to 
introduce an interface; the component class
  should implement the interface, and the service should expect an instance of 
the interface, rather than a specific type.</p><p>It is important that the 
interface be loaded by the default class loader. It should not be in the pages 
or components package, but instead be in another package, such as 
services.</p><h2 id="ClassReloading-HandlingReloadsinyourCode">Handling Reloads 
in your Code</h2><p>On occasion, you may need to know when invalidations occur, 
to clear your own cache. For example, if you have a binding that creates new 
classes, the way <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PropertyConduitSource.html";>PropertyConduitSource</a>
 does, you need to discard any cached classes or instances when a change is 
detected in component classes.</p><p>You do this by registering a listener with 
the correct <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tpaestry5/services/InvalidationEv
 entHub.html">InvalidationEventHub</a> service.</p><p>For example, your service 
may be in the business of creating new classes based on component classes, and 
keep a cache of those classes:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class MyServiceImpl implements MyService, 
InvalidationEventListener
 {
   public final Map&lt;String,Class&gt; cache = new 
ConcurrentHashMap&lt;String,Class&gt;();
@@ -131,7 +131,7 @@
 </div></div><p>This is the intent of service builder methods; to do more than 
just injecting dependencies.</p><h2 
id="ClassReloading-CheckingForUpdates">Checking For Updates</h2><p>The built in 
InvalidationEventHub services provide notifications of changes to component 
classes, to component templates, and to component message catalogs. If you wish 
to check some other resources (for example, files in a directory of the file 
system or rows in a database table), you should register as an <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListener.html";>UpdateListener</a>
 with the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/UpdateListenerHub.html";>UpdateListenerHub</a>
 service.</p><p>Periodically (the frequency is configurable), UpdateListeners 
are notified that they should check for updates. Typically, UpdateListeners are 
also InvalidationEventHubs (or provide Invali
 dationEventHubs), so that other interested parties can be alerted when 
underlying data changes.</p><h2 
id="ClassReloading-TroubleshootingLiveClassReloading">Troubleshooting Live 
Class Reloading</h2><h3 id="ClassReloading-QuickChecklist">Quick 
Checklist</h3><ul><li>"Production Mode" must be false (in Tapestry 5.3 and 
later)</li><li>The class must be one that Tapestry instantiates (a page, 
component, or mixin class, or a Tapestry IOC service implementation that 
implements an interface)</li><li>Turn on "Build Automatically" in your IDE, or 
remember to build manually.</li><li>Turn <em>off</em> JVM hot code swapping, if 
your servlet container supports it.</li><li>Eclipse: Uncheck the "derived" 
checkbox for the Target dir (in the Project Explorer view, right click on 
"target", select properties, uncheck "derived" on the Resource 
tab)</li></ul><p>Some of these issues are described in more detail 
below.</p><h3 id="ClassReloading-IfLiveClassReloadingdoesn'twork">If Live Class 
Reloading doesn
 't work</h3><h4 id="ClassReloading-ProductionMode">Production 
Mode</h4><p>Starting with Tapestry 5.3, Live Class Reloading only works when 
not in "Production Mode". Check your application module (usually 
AppModule.java) to be sure you have:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">configuration.add(SymbolConstants.PRODUCTION_MODE, 
"false");
 </pre>
-</div></div><p>and that this isn't being overridden to "true" on your 
application's startup command line.</p><h4 
id="ClassReloading-BuildPathIssues">Build Path Issues</h4><p>Live Class 
Reloading can fail if your build path isn't set correctly, and the exact 
configuration may differ between Maven plugin versions and Eclipse versions. 
The build process must be set to create classes in a folder which is in the 
servlet container's classpath.</p><p>Live Class Reloading won't work correctly 
with vanilla Tomcat without some tweaks (see below).</p><p>Non-Tapestry filters 
can interfere with LCR. Try disabling other filters in your web.xml file to see 
if that helps.</p><h4 id="ClassReloading-BuildingAutomatically">Building 
Automatically</h4><p>Although LCR allows you to see changes without restarting 
your app, you still need to "build" your project (to compile the Java source 
into byte code). Your IDE can be set to do this automatically every time you 
save a file. (In Eclipse, this is done us
 ing <code>Project &gt; Build Automatically</code>.) Alternatively, you can 
manually trigger a build after you save a file. (In Eclipse, this is done using 
<code>Project &gt; Build</code>, or by pressing <code>Control-B</code>.)</p><h4 
id="ClassReloading-TurnoffJVMhotcodeswapping&amp;automaticrestarts">Turn off 
JVM hot code swapping &amp; automatic restarts</h4><p>Many servlet containers, 
including Tomcat and Jetty, support various forms of hot code swapping and/or 
automatic restarts when file changes are detected. These are generally 
<strong>much slower</strong> than LCR and usually should be turned off with 
Tapestry applications. If you're using RunJettyRun plugin for Eclipse, for 
example, edit your Run Configuration, and on the Jetty tab, click Show Advanced 
Options and uncheck the Enable Scanner checkbox.</p><h3 
id="ClassReloading-TomcatSpecifics">Tomcat Specifics</h3><p>See <a  
class="external-link" 
href="http://docs.codehaus.org/display/TYNAMO/Developing+with+Tomcat+and+Eclipse
 " rel="nofollow">these Tomcat-specific hints</a></p><h3 
id="ClassReloading-IfLiveClassReloadingworksbutisslow">If Live Class Reloading 
works but is slow</h3><p>If LCR works for you but is slow (more than a second 
or two), consider the following.</p><ul><li>Be sure your project source files 
(your workspace in Eclipse, for example), are on a local drive, NOT a network 
location. Network drives are always slower, and the file system scanning needed 
for LCR can add a noticable lag if I/O is slow. If you use Maven, be sure to 
put your local repository (e.g. ~/.m2/repository) on a local drive for similar 
reasons.</li><li><p>Java 7 and below: Since LCR adds classes to your PermGen 
space, you may be running low on PermGen memory (and may eventually get a 
"java.lang.OutOfMemoryError: PermGen space" error). Try increasing PermGen size 
with a JVM argument of something like&#160;-XX:MaxPermSize=400m. (PermGen 
settings are not relevant for Java 8 and 
above.)</p></li></ul><p>&#160;</p></div>
+</div></div><p>and that this isn't being overridden to "true" on your 
application's startup command line.</p><h4 
id="ClassReloading-BuildPathIssues">Build Path Issues</h4><p>Live Class 
Reloading can fail if your build path isn't set correctly, and the exact 
configuration may differ between Maven plugin versions and Eclipse versions. 
The build process must be set to create classes in a folder which is in the 
servlet container's classpath.</p><p>Live Class Reloading won't work correctly 
with vanilla Tomcat without some tweaks (see below).</p><p>Non-Tapestry filters 
can interfere with LCR. Try disabling other filters in your web.xml file to see 
if that helps.</p><h4 id="ClassReloading-BuildingAutomatically">Building 
Automatically</h4><p>Although LCR allows you to see changes without restarting 
your app, you still need to "build" your project (to compile the Java source 
into byte code). Your IDE can be set to do this automatically every time you 
save a file. (In Eclipse, this is done us
 ing <code>Project &gt; Build Automatically</code>.) Alternatively, you can 
manually trigger a build after you save a file. (In Eclipse, this is done using 
<code>Project &gt; Build</code>, or by pressing <code>Control-B</code>.)</p><h4 
id="ClassReloading-TurnoffJVMhotcodeswapping&amp;automaticrestarts">Turn off 
JVM hot code swapping &amp; automatic restarts</h4><p>Many servlet containers, 
including Tomcat and Jetty, support various forms of hot code swapping and/or 
automatic restarts when file changes are detected. These are generally 
<strong>much slower</strong> than LCR and usually should be turned off with 
Tapestry applications. If you're using RunJettyRun plugin for Eclipse, for 
example, edit your Run Configuration, and on the Jetty tab, click Show Advanced 
Options and uncheck the Enable Scanner checkbox.</p><h3 
id="ClassReloading-TomcatSpecifics">Tomcat Specifics</h3><p>See <a  
class="external-link" 
href="http://www.tynamo.org/Developing+with+Tomcat+and+Eclipse/"; rel="nofollow">
 these Tomcat-specific hints</a></p><h3 
id="ClassReloading-IfLiveClassReloadingworksbutisslow">If Live Class Reloading 
works but is slow</h3><p>If LCR works for you but is slow (more than a second 
or two), consider the following.</p><ul><li>Be sure your project source files 
(your workspace in Eclipse, for example), are on a local drive, NOT a network 
location. Network drives are always slower, and the file system scanning needed 
for LCR can add a noticable lag if I/O is slow. If you use Maven, be sure to 
put your local repository (e.g. ~/.m2/repository) on a local drive for similar 
reasons.</li><li><p>Java 7 and below: Since LCR adds classes to your PermGen 
space, you may be running low on PermGen memory (and may eventually get a 
"java.lang.OutOfMemoryError: PermGen space" error). Try increasing PermGen size 
with a JVM argument of something like&#160;-XX:MaxPermSize=400m. (PermGen 
settings are not relevant for Java 8 and 
above.)</p></li></ul><p>&#160;</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/component-classes.html
==============================================================================
--- websites/production/tapestry/content/component-classes.html (original)
+++ websites/production/tapestry/content/component-classes.html Fri Feb 16 
03:21:19 2018
@@ -145,7 +145,7 @@
 </div>
 
 
-<p>In most cases, each component class will have a corresponding <a  
href="component-classes.html">component template</a>. However, it is also 
possible for a component class to emit all of its markup itself, without using 
a template.</p><p><em>For Tapestry 4 Users: Component classes in Tapestry 5 are 
much easier than in Tapestry 4. There are no base classes to extend from, the 
classes are concrete (not abstract), and there's no XML file. There is still a 
bit of configuration in the form of Java annotations, but those now go directly 
onto fields of your class, rather than on abstract getters and 
setters.</em></p><h2 id="ComponentClasses-CreatingaTrivialComponent">Creating a 
Trivial Component</h2><p>Creating a page or component in Tapestry 5 is a 
breeze. There are only a few constraints:</p><ul><li>There must be a public 
Java class.</li><li>The class must be in the correct package (see 
below).</li><li>The class must have a public, no-arguments constructor. (The 
default one provided by
  the compiler is fine.)</li></ul><p>Here's a minimal component that outputs a 
fixed message, using a <a  href="component-classes.html">template</a> with a 
matching file name:</p><div class="sectionColumnWrapper"><div 
class="sectionMacro"><div class="sectionMacroRow"><div class="columnMacro"><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>HelloWorld.java</b></div><div class="codeContent panelContent pdl">
+<p>In most cases, each component class will have a corresponding <a  
href="component-templates.html">component template</a>. However, it is also 
possible for a component class to emit all of its markup itself, without using 
a template.</p><p><em>For Tapestry 4 Users: Component classes in Tapestry 5 are 
much easier than in Tapestry 4. There are no base classes to extend from, the 
classes are concrete (not abstract), and there's no XML file. There is still a 
bit of configuration in the form of Java annotations, but those now go directly 
onto fields of your class, rather than on abstract getters and 
setters.</em></p><h2 id="ComponentClasses-CreatingaTrivialComponent">Creating a 
Trivial Component</h2><p>Creating a page or component in Tapestry 5 is a 
breeze. There are only a few constraints:</p><ul><li>There must be a public 
Java class.</li><li>The class must be in the correct package (see 
below).</li><li>The class must have a public, no-arguments constructor. (The 
default one provided 
 by the compiler is fine.)</li></ul><p>Here's a minimal component that outputs 
a fixed message, using a <a  href="component-classes.html">template</a> with a 
matching file name:</p><div class="sectionColumnWrapper"><div 
class="sectionMacro"><div class="sectionMacroRow"><div class="columnMacro"><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>HelloWorld.java</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.myapp.components;
 public class HelloWorld
 {
@@ -171,13 +171,13 @@ public class HelloWorld
     }
 }
 </pre>
-</div></div><p>In this example, just like the first one, the component's only 
job is to write out a fixed message. The @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html";>BeginRender</a>
 annotation is a type of <em><a  href="component-classes.html">render phase 
annotation</a></em>, a method annotation that instructs Tapestry when and under 
what circumstances to invoke methods of your class.</p><p>These methods are not 
necessarily public; they can have any access level you like (unlike in Tapestry 
4). By convention they usually have package-private access level (the 
default).</p><h2 id="ComponentClasses-ComponentPackages">Component 
Packages</h2><p>Component classes must exist within an appropriate package 
(this is necessary for runtime code transformation and class reloading to 
operate).</p><p>These packages exist under the application's root package, as 
follows:</p><ul><li>For pages, place classes in <em>root
 </em>.<strong>pages</strong>. Page names are mapped to classes within this 
package.</li><li>For mixins, place classes in 
<em>root</em>.<strong>mixins</strong>. Mixin types are mapped to classes within 
this package.</li><li>For other components, place classes in 
<em>root</em>.<strong>components</strong>. Component types are mapped to 
classes within this package.</li></ul><p>In addition, it is common for an 
application to have base classes, often <em>abstract</em> base classes, that 
should not be directly referenced. These should <em>not</em> go in the 
<strong>pages</strong>, <strong>components</strong> or <strong>mixins</strong> 
packages, because they then look like valid pages, components or mixins. 
Instead, use the <em>root</em>.<strong>base</strong> package to store such base 
classes.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div class="conflue
 nce-information-macro-body"><p>Only component classes should go in any of 
these controlled packages; classes representing data, or interfaces, or 
anything that isn't precisely a component class, must go elsewhere. Any 
top-level class in any of the controlled packages will be transformed at 
runtime. The only exception is inner classes (anonymous or not), which are 
loaded by the same class loader as the component class loader, but not 
transformed as components.</p></div></div><h2 
id="ComponentClasses-Sub-Folders/Sub-Packages">Sub-Folders / 
Sub-Packages</h2><p>Classes do not have to go directly inside the package 
(pages, components, mixins, etc.). It is valid to create a sub-package to store 
some of the classes. The sub-package name becomes part of the page name or 
component type. Thus you might define a page component 
<code>com.example.myapp.pages.admin.CreateUser</code> and the logical page name 
(which often shows up inside URLs) will be 
<strong>admin/CreateUser</strong>.</p><p>Tapes
 try performs some simple optimizations of the logical page name (or component 
type, or mixin type). It checks to see if the package name is either a prefix 
or a suffix of the unqualified class name (case insensitively, of course) and 
removes the prefix or suffix if so. The net result is that a class name such as 
<code>com.example.myapp.pages.user.EditUser</code> will have a page name of 
<code>user/Edit</code> (instead of user<code>/EditUser</code>). The goal here 
is to provide shorter, more natural URLs.</p><h2 
id="ComponentClasses-IndexPages">Index Pages</h2><p>One special simplification 
exists for Index pages: if the logical page name is Index after removing the 
package name from the unqualified class name, it will map to the root of that 
folder. A class such as <code>com.example.myapp.pages.user.IndexUser</code> or 
<code>com.example.myapp.pages.user.UserIndex</code> will have a page name of 
<code>user/</code>.</p><p>In previous versions of Tapestry there was also the 
concept of a
  start page configured with the <code><a  
href="component-classes.html">tapestry.start-page-name</a></code> configuration 
symbol (defaults to "start"). If a page with a name as configured with that 
symbol exists at the root level, this page is used as the root URL. This has 
precedence over an existing Index page. If for example you have a page class 
<code>com.example.myapp.pages.Start</code> it will map to 
<code>/</code>.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Use of start-pages is discouraged 
and support for it will eventually be removed. Use an Index page 
instead.</p></div></div><h2 id="ComponentClasses-Pagesvs.Components">Pages vs. 
Components</h2><p>The distinction between pages and component is very, very 
small. The primary difference is the package name: 
<em>root</em>.<strong>pages</strong>
 .<em>PageName</em> for pages, and 
<em>root</em>.<strong>components</strong>.<em>ComponentType</em> for 
components. Conceptually, page components are simply the <em>root 
component</em> of a page's component tree.</p><p><em>For Tapestry 4 users: 
there was a much greater distinction in Tapestry 4 between pages and 
components, which showed up as separate interfaces and a hierarchy of abstract 
implementations to extend your classes from.</em></p><h2 
id="ComponentClasses-ClassTransformation">Class Transformation</h2><p>Tapestry 
uses your class as a starting point. It <em>transforms</em> your class at 
runtime. This is necessary for a number of reasons, including to address how 
Tapestry shares pages between requests.</p><p>For the most part, these 
transformations are both sensible and invisible. In a few limited cases, they 
comprise a marginally&#160;<a  class="external-link" 
href="http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html";
 rel="nofollow">leaky abstractio
 n</a>&#160;&#8211; for instance, the scope restrictions on instance variables 
described below &#8211; but the programming model in general supports a very 
high level of developer productivity.</p><p>Because transformation doesn't 
occur until <em>runtime</em>, the build stage of your application is not 
affected by the fact that you are creating a Tapestry application. Further, 
your classes are absolutely simple POJOs during unit testing.</p><h2 
id="ComponentClasses-LiveClassReloading">Live Class Reloading</h2><p>Main 
Article: <a  href="class-reloading.html">Class Reloading</a></p><p>Component 
classes are monitored for changes by the framework. <a  
href="component-classes.html">Classes are reloaded when changed</a>. This 
allows you to build your application with a speed approaching that of a 
scripting environment, without sacrificing any of the power of the Java 
platform.</p><p>And it's fast! You won't even notice that this magic class 
reloading has occurred.</p><p>The net result: sup
 er productivity &#8212; change your class, see the change instantly. This is 
designed to be a blend of the best of scripting environments (such as Python or 
Ruby) with all the speed and power of Java backing it up.</p><p>However, class 
reloading <em>only</em> applies to component classes (pages, components and 
mixins) and, starting in 5.2, Tapestry IOC-based service implementations (with 
some restrictions). Other classes, such as service interfaces, entity/model 
classes, and other data objects, are loaded by the normal class loader and not 
subject to live class reloading.</p><h2 
id="ComponentClasses-InstanceVariables">Instance Variables</h2><p>Tapestry 
components may have instance variables (unlike Tapestry 4, where you had to use 
<em>abstract properties</em>).</p><p>Since release 5.3.2, instance variables 
may be protected, or package private (that is, no access modifier). Under 
specific circumstances they may even be public (public fields must either be 
final, or have the @<a  clas
 s="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html";>Retain</a>&#160;annotation).</p><p><span>Be
 aware that you will need to either provide getter and setter methods to access 
your classes' instance variables, or else annotate the fields 
with</span><span>&#160;@</span><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Property.html";>Property</a>.</p><h2
 id="ComponentClasses-TransientInstanceVariables">Transient Instance 
Variables</h2><p>Unless an instance variable is decorated with an annotation, 
it will be a <em>transient</em> instance variable. This means that its value 
resets to its default value at the end of reach request (when the <a  
href="component-classes.html">page is detached from the request</a>).</p><div 
class="confluence-information-macro confluence-information-macro-note"><p 
class="title">About initialization</p><span class="aui-icon aui-icon-small aui-
 iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Never initialize an instance field 
to a <em>mutable</em> object at the point of declaration. If this is done, the 
instance created from that initializer becomes the default value for that field 
and is reused inside the component on every request. This could cause state to 
inadvertently be shared between different sessions in an 
application.</p></div></div>
+</div></div><p>In this example, just like the first one, the component's only 
job is to write out a fixed message. The @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html";>BeginRender</a>
 annotation is a type of <em><a  href="component-rendering.html">render phase 
annotation</a></em></p><p>, a method annotation that instructs Tapestry when 
and under what circumstances to invoke methods of your class.</p><p>These 
methods are not necessarily public; they can have any access level you like 
(unlike in Tapestry 4). By convention they usually have package-private access 
level (the default).</p><h2 id="ComponentClasses-ComponentPackages">Component 
Packages</h2><p>Component classes must exist within an appropriate package 
(this is necessary for runtime code transformation and class reloading to 
operate).</p><p>These packages exist under the application's root package, as 
follows:</p><ul><li>For pages, place classes in
  <em>root</em>.<strong>pages</strong>. Page names are mapped to classes within 
this package.</li><li>For mixins, place classes in 
<em>root</em>.<strong>mixins</strong>. Mixin types are mapped to classes within 
this package.</li><li>For other components, place classes in 
<em>root</em>.<strong>components</strong>. Component types are mapped to 
classes within this package.</li></ul><p>In addition, it is common for an 
application to have base classes, often <em>abstract</em> base classes, that 
should not be directly referenced. These should <em>not</em> go in the 
<strong>pages</strong>, <strong>components</strong> or <strong>mixins</strong> 
packages, because they then look like valid pages, components or mixins. 
Instead, use the <em>root</em>.<strong>base</strong> package to store such base 
classes.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div class
 ="confluence-information-macro-body"><p>Only component classes should go in 
any of these controlled packages; classes representing data, or interfaces, or 
anything that isn't precisely a component class, must go elsewhere. Any 
top-level class in any of the controlled packages will be transformed at 
runtime. The only exception is inner classes (anonymous or not), which are 
loaded by the same class loader as the component class loader, but not 
transformed as components.</p></div></div><h2 
id="ComponentClasses-Sub-Folders/Sub-Packages">Sub-Folders / 
Sub-Packages</h2><p>Classes do not have to go directly inside the package 
(pages, components, mixins, etc.). It is valid to create a sub-package to store 
some of the classes. The sub-package name becomes part of the page name or 
component type. Thus you might define a page component 
<code>com.example.myapp.pages.admin.CreateUser</code> and the logical page name 
(which often shows up inside URLs) will be <strong>admin/CreateUser</strong>.</p
 ><p>Tapestry performs some simple optimizations of the logical page name (or 
 >component type, or mixin type). It checks to see if the package name is 
 >either a prefix or a suffix of the unqualified class name (case 
 >insensitively, of course) and removes the prefix or suffix if so. The net 
 >result is that a class name such as 
 ><code>com.example.myapp.pages.user.EditUser</code> will have a page name of 
 ><code>user/Edit</code> (instead of user<code>/EditUser</code>). The goal here 
 >is to provide shorter, more natural URLs.</p><h2 
 >id="ComponentClasses-IndexPages">Index Pages</h2><p>One special 
 >simplification exists for Index pages: if the logical page name is Index 
 >after removing the package name from the unqualified class name, it will map 
 >to the root of that folder. A class such as 
 ><code>com.example.myapp.pages.user.IndexUser</code> or 
 ><code>com.example.myapp.pages.user.UserIndex</code> will have a page name of 
 ><code>user/</code>.</p><p>In previous versions of Tapestry there was also the 
 >con
 cept of a start page configured with the <code><a  
href="configuration.html">tapestry.start-page-name</a></code> configuration 
symbol (defaults to "start"). If a page with a name as configured with that 
symbol exists at the root level, this page is used as the root URL. This has 
precedence over an existing Index page. If for example you have a page class 
<code>com.example.myapp.pages.Start</code> it will map to 
<code>/</code>.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Use of start-pages is discouraged 
and support for it will eventually be removed. Use an Index page 
instead.</p></div></div><h2 id="ComponentClasses-Pagesvs.Components">Pages vs. 
Components</h2><p>The distinction between pages and component is very, very 
small. The primary difference is the package name: 
<em>root</em>.<strong>pages</st
 rong>.<em>PageName</em> for pages, and 
<em>root</em>.<strong>components</strong>.<em>ComponentType</em> for 
components. Conceptually, page components are simply the <em>root 
component</em> of a page's component tree.</p><p><em>For Tapestry 4 users: 
there was a much greater distinction in Tapestry 4 between pages and 
components, which showed up as separate interfaces and a hierarchy of abstract 
implementations to extend your classes from.</em></p><h2 
id="ComponentClasses-ClassTransformation">Class Transformation</h2><p>Tapestry 
uses your class as a starting point. It <em>transforms</em> your class at 
runtime. This is necessary for a number of reasons, including to address how 
Tapestry shares pages between requests.</p><p>For the most part, these 
transformations are both sensible and invisible. In a few limited cases, they 
comprise a marginally&#160;<a  class="external-link" 
href="http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html";
 rel="nofollow">leaky abstr
 action</a>&#160;&#8211; for instance, the scope restrictions on instance 
variables described below &#8211; but the programming model in general supports 
a very high level of developer productivity.</p><p>Because transformation 
doesn't occur until <em>runtime</em>, the build stage of your application is 
not affected by the fact that you are creating a Tapestry application. Further, 
your classes are absolutely simple POJOs during unit testing.</p><h2 
id="ComponentClasses-LiveClassReloading">Live Class Reloading</h2><p>Main 
Article: <a  href="class-reloading.html">Class Reloading</a></p><p>Component 
classes are monitored for changes by the framework. <a  
href="class-reloading.html">Classes are reloaded when changed</a>. This allows 
you to build your application with a speed approaching that of a scripting 
environment, without sacrificing any of the power of the Java 
platform.</p><p>And it's fast! You won't even notice that this magic class 
reloading has occurred.</p><p>The net result: 
 super productivity &#8212; change your class, see the change instantly. This 
is designed to be a blend of the best of scripting environments (such as Python 
or Ruby) with all the speed and power of Java backing it up.</p><p>However, 
class reloading <em>only</em> applies to component classes (pages, components 
and mixins) and, starting in 5.2, Tapestry IOC-based service implementations 
(with some restrictions). Other classes, such as service interfaces, 
entity/model classes, and other data objects, are loaded by the normal class 
loader and not subject to live class reloading.</p><h2 
id="ComponentClasses-InstanceVariables">Instance Variables</h2><p>Tapestry 
components may have instance variables (unlike Tapestry 4, where you had to use 
<em>abstract properties</em>).</p><p>Since release 5.3.2, instance variables 
may be protected, or package private (that is, no access modifier). Under 
specific circumstances they may even be public (public fields must either be 
final, or have the @<a  c
 lass="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html";>Retain</a>&#160;annotation).</p><p><span>Be
 aware that you will need to either provide getter and setter methods to access 
your classes' instance variables, or else annotate the fields 
with</span><span>&#160;@</span><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Property.html";>Property</a>.</p><h2
 id="ComponentClasses-TransientInstanceVariables">Transient Instance 
Variables</h2><p>Unless an instance variable is decorated with an annotation, 
it will be a <em>transient</em> instance variable. This means that its value 
resets to its default value at the end of reach request (when the <a  
href="page-life-cycle.html">page is detached from the 
request</a></p><p>).</p><div class="confluence-information-macro 
confluence-information-macro-note"><p class="title">About 
initialization</p><span class="aui-icon aui-icon-sm
 all aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Never initialize an instance field 
to a <em>mutable</em> object at the point of declaration. If this is done, the 
instance created from that initializer becomes the default value for that field 
and is reused inside the component on every request. This could cause state to 
inadvertently be shared between different sessions in an 
application.</p></div></div>
 
 
 <div class="aui-message aui-message-warning">
 Deprecated since 5.2 |
 For Tapestry 5.1 and earlier, in the rare event that you have a variable that 
can keep its value between requests and you would like to defeat that reset 
logic, then you can add a&#160;@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html";>Retain</a>
 annotation to the field. You should take care that no client-specific data is 
stored into such a field, since on a later request the same page 
<em>instance</em> may be used for a different user. Likewise, on a later 
request for the <em>same</em> client, a <em>different</em> page instance may be 
used.
-</div><p>Use <a  href="component-classes.html">persistent fields</a> to hold 
client-specific information from one request to the next.</p><p>Further, final 
fields are (in fact) final, and will not be reset between requests.</p><h2 
id="ComponentClasses-Constructors">Constructors</h2><p>Tapestry will 
instantiate your class using the default, no arguments constructor. Other 
constructors will be ignored.</p><h2 
id="ComponentClasses-Injection">Injection</h2><p>Main Article: <a  
href="injection.html">Injection</a></p><p>Injection of dependencies occurs at 
the field level, via additional annotations. At runtime, fields that contain 
injections become read-only.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div><p>Use <a  href="persistent-page-data.html">persistent fields</a> to 
hold client-specific information from one request to the next.</p><p>Further, 
final fields are (in fact) final, and will not be reset between 
requests.</p><h2 
id="ComponentClasses-Constructors">Constructors</h2><p>Tapestry will 
instantiate your class using the default, no arguments constructor. Other 
constructors will be ignored.</p><h2 
id="ComponentClasses-Injection">Injection</h2><p>Main Article: <a  
href="injection.html">Injection</a></p><p>Injection of dependencies occurs at 
the field level, via additional annotations. At runtime, fields that contain 
injections become read-only.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Inject // inject a resource
 private ComponentResources componentResources;
 
@@ -191,7 +191,7 @@ private Asset banner;
 @Inject // inject a service
 private AjaxResponseRenderer ajaxResponseRenderer;
 </pre>
-</div></div><h2 id="ComponentClasses-Parameters">Parameters</h2><p>Main 
Article: <a  href="component-parameters.html">Component 
Parameters</a></p><p>Component parameters are private fields of your component 
class annotated with @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Parameter.html";>Parameter</a>.
 Component parameters represent a two-way binding of a field of your component 
and a property or resource of its containing component or page.</p><h2 
id="ComponentClasses-PersistentFields">Persistent Fields</h2><p>Main Article: 
<a  href="persistent-page-data.html">Persistent Page Data</a></p><p>Most fields 
in component classes are automatically cleared at the end of each request. 
However, fields may be annotated so that they retain their value across 
requests, using the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html";>Persist</a>
 annotation.</p><h2 i
 d="ComponentClasses-Embedded_ComponentsEmbeddedComponents"><span 
class="confluence-anchor-link" 
id="ComponentClasses-Embedded_Components"></span>Embedded 
Components</h2><p>Components often contain other components. Components inside 
another component's template are called <em>embedded components</em>. The 
containing component's <a  href="component-classes.html">template</a> will 
contain special elements, in the Tapestry namespace, identifying where the the 
embedded components go.</p><p>You can define the type of component inside 
template, or you can create an instance variable for the component and use the 
@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html";>Component</a>
 annotation to define the component type and parameters.</p><p>Example:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+</div></div><h2 id="ComponentClasses-Parameters">Parameters</h2><p>Main 
Article: <a  href="component-parameters.html">Component 
Parameters</a></p><p>Component parameters are private fields of your component 
class annotated with @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Parameter.html";>Parameter</a>.
 Component parameters represent a two-way binding of a field of your component 
and a property or resource of its containing component or page.</p><h2 
id="ComponentClasses-PersistentFields">Persistent Fields</h2><p>Main Article: 
<a  href="persistent-page-data.html">Persistent Page Data</a></p><p>Most fields 
in component classes are automatically cleared at the end of each request. 
However, fields may be annotated so that they retain their value across 
requests, using the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html";>Persist</a>
 annotation.</p><h2 i
 d="ComponentClasses-Embedded_ComponentsEmbeddedComponents"><span 
class="confluence-anchor-link" 
id="ComponentClasses-Embedded_Components"></span>Embedded 
Components</h2><p>Components often contain other components. Components inside 
another component's template are called <em>embedded components</em>. The 
containing component's <a  href="component-templates.html">template</a> will 
contain special elements, in the Tapestry namespace, identifying where the the 
embedded components go.</p><p>You can define the type of component inside 
template, or you can create an instance variable for the component and use the 
@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html";>Component</a>
 annotation to define the component type and parameters.</p><p>Example:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package org.example.app.pages;
 
 import org.apache.tapestry5.annotations.Component;


Reply via email to