Author: buildbot
Date: Tue Feb 13 03:21:20 2018
New Revision: 1025321
Log:
Production update by buildbot for tapestry
Modified:
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/ioc-cookbook-service-configurations.html
websites/production/tapestry/content/property-expressions.html
websites/production/tapestry/content/supported-environments-and-versions.html
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 Tue Feb 13
03:21:20 2018
@@ -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 > Build Automatically</code>.) Alternatively, you can
manually trigger a build after you save a file. (In Eclipse, this is done using
<code>Project > Build</code>, or by pressing <code>Control-B</code>.)</p><h4
id="ClassReloading-TurnoffJVMhotcodeswapping&automaticrestarts">Turn off
JVM hot code swapping & 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>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
<code>-XX:MaxPermSize=400m</code></li></ul><p></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 > Build Automatically</code>.) Alternatively, you can
manually trigger a build after you save a file. (In Eclipse, this is done using
<code>Project > Build</code>, or by pressing <code>Control-B</code>.)</p><h4
id="ClassReloading-TurnoffJVMhotcodeswapping&automaticrestarts">Turn off
JVM hot code swapping & 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 -XX:MaxPermSize=400m. (PermGen
settings are not relevant for Java 8 and
above.)</p></li></ul><p> </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 Tue Feb 13
03:21:20 2018
@@ -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 <a class="external-link"
href="http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html"
rel="nofollow">leaky abstractio
n</a> – for instance, the scope restrictions on instance variables
described below – 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="component-classes.html">Component
Classes</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:
super productivity — 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
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Retain.html">Retain</a> 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> @</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-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 <a class="external-link"
href="http://www.joelonsoftware.com/printerFriendly/articles/LeakyAbstractions.html"
rel="nofollow">leaky abstractio
n</a> – for instance, the scope restrictions on instance variables
described below – 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 — 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> 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> @</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 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 @<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="component-classes.html">Component Classes</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="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">
<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-classes.html">Component
Classes</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="component-classes.html">Component Classes</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 id="Component
Classes-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-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">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">package org.example.app.pages;
import org.apache.tapestry5.annotations.Component;