Modified: 
websites/production/tapestry/content/defining-tapestry-ioc-services.html
==============================================================================
--- websites/production/tapestry/content/defining-tapestry-ioc-services.html 
(original)
+++ websites/production/tapestry/content/defining-tapestry-ioc-services.html 
Sat Aug  8 17:20:04 2015
@@ -31,8 +31,6 @@
   <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
   <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
   <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
   <script type="text/javascript">
   SyntaxHighlighter.defaults['toolbar'] = false;
   SyntaxHighlighter.all();
@@ -62,39 +60,13 @@
 <div class="clearer"></div>
 
   <div id="breadcrumbs">
-        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IoC</a>&nbsp;&gt;&nbsp;<a 
href="defining-tapestry-ioc-services.html">Defining Tapestry IOC Services</a>
+        <a href="index.html">Apache Tapestry</a>&nbsp;&gt;&nbsp;<a 
href="documentation.html">Documentation</a>&nbsp;&gt;&nbsp;<a 
href="user-guide.html">User Guide</a>&nbsp;&gt;&nbsp;<a 
href="ioc.html">IOC</a>&nbsp;&gt;&nbsp;<a 
href="defining-tapestry-ioc-services.html">Defining Tapestry IOC Services</a>
     <a class="edit" title="Edit this page (requires approval -- just ask on 
the mailing list)" 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=23338492";>edit</a>
   </div>
 
 <div id="content">
-<div id="ConfluenceContent">
-
-<p>Services consist of two main parts: a service interface and a service 
implementation.</p>
-
-<p>The service interface is how the service will be represented throughout the 
rest of the registry. Since what gets passed around is normally a proxy, you 
can't expect to cast a service object down to the implementation class (you'll 
see a ClassCastException instead). In other words, you should be careful to 
ensure that your service interface is complete, since Tapestry IoC effectively 
walls you off from back doors such as casts.</p>
-
-<h1 id="DefiningTapestryIOCServices-ServiceLifeCycle">Service Life Cycle</h1>
-
-<p>Every service has a very specific life cycle.</p>
-
-<ul><li>Defined: The service has a definition (from some module) but has not 
yet been referenced.</li><li>Virtual: The service has been referenced, so a 
proxy for the class has been created.</li><li>Realized: A method on the proxy 
has been invoked, so the service implementation has been instantiated, and any 
decorators applied.</li><li>Shutdown: The entire Registry has been shut down 
and with it, all the proxies have been disabled.</li></ul>
-
-
-<p>When the Registry is first created, all modules are scanned and the 
definitions for all services are created.</p>
-
-<p>Services will be referenced by either accessing them using the Registry, or 
as dependencies of other realized services.</p>
-
-<p>Tapestry IoC waits until the last possible moment to <em>realize</em> the 
service: that's defined as when a method of the service is invoked. Tapestry is 
<em>thread-safe</em>, so even in a heavily contested, highly threaded 
environment (such as a servlet container or application server) things <em>Just 
Work</em>.</p>
-
-<p><span class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-serviceBuilderMethod"></span></p>
-
-<h1 id="DefiningTapestryIOCServices-ServiceBuilderMethods">Service Builder 
Methods</h1>
-
-<p>Tapestry doesn't know how to instantiate and configure your service; 
instead it relies on you to provide the code to do so, in a service builder 
method, a method whose name is (or starts with) "build":</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.myapp.services;
+<div id="ConfluenceContent"><p>Services consist of two main parts: a service 
interface and a service implementation.</p><p>The service interface is how the 
service will be represented throughout the rest of the registry. Since what 
gets passed around is normally a proxy, you can't expect to cast a service 
object down to the implementation class (you'll see a ClassCastException 
instead). In other words, you should be careful to ensure that your service 
interface is complete, since Tapestry IoC effectively walls you off from back 
doors such as casts.</p><h1 
id="DefiningTapestryIOCServices-ServiceLifeCycle">Service Life 
Cycle</h1><p>Every service has a very specific life cycle.</p><ul><li>Defined: 
The service has a definition (from some module) but has not yet been 
referenced.</li><li>Virtual: The service has been referenced, so a proxy for 
the class has been created.</li><li>Realized: A method on the proxy has been 
invoked, so the service implementation has been instantiated, and any 
 decorators applied.</li><li>Shutdown: The entire Registry has been shut down 
and with it, all the proxies have been disabled.</li></ul><p>When the Registry 
is first created, all modules are scanned and the definitions for all services 
are created.</p><p>Services will be referenced by either accessing them using 
the Registry, or as dependencies of other realized services.</p><p>Tapestry IoC 
waits until the last possible moment to <em>realize</em> the service: that's 
defined as when a method of the service is invoked. Tapestry is 
<em>thread-safe</em>, so even in a heavily contested, highly threaded 
environment (such as a servlet container or application server) things <em>Just 
Work</em>.</p><p><span class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-serviceBuilderMethod"></span></p><h1 
id="DefiningTapestryIOCServices-ServiceBuilderMethods">Service Builder 
Methods</h1><p>Tapestry doesn't know how to instantiate and configure your 
service; instead it relies on you to provide
  the code to do so, in a service builder method, a method whose name is (or 
starts with) "build":</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.myapp.services;
 
 public class MyAppModule
 {
@@ -103,25 +75,8 @@ public class MyAppModule
     return new IndexerImpl();
   }
 }</pre>
-</div></div>
-
-<p>Here the service interface is Indexer (presumably inside the 
org.example.myapp.services package, since there isn't an import). Tapestry IoC 
doesn't know about the IndexerImpl class (the service implementation of the 
Indexer service), but it does know about the build() method.</p>
-
-<p>That's one of the great innovations of Tapestry IoC: we don't try to 
encapsulate in XML or annotations all the different ways possible to create a 
service; those things are best expressed in Java code. For a simple case (as 
here), it would be hard for external configuration (again, in XML or Java 
annotations) to be shorter than "new IndexerImpl()".</p>
-
-<p><em>The above paragraph was written before Binding and Autobuilding were 
introduced.</em></p>
-
-<p>For more complex and realistic scenarios, such as injecting dependencies 
via the constructor, or doing more interest work (such as registering the newly 
created service for events published by some other service), the Java code is 
simply the most direct, flexible, extensible and readable approach.</p>
-
-<h1 id="DefiningTapestryIOCServices-BindingandAutobuilding">Binding and 
Autobuilding</h1>
-
-<p>Tapestry IoC can also <em>autobuild</em> your service. Autobuilding is the 
<em>preferred</em> way to instantiate your services.</p>
-
-<p>Every module may have an optional, static bind() method which is passed a 
<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBinder.html";>ServiceBinder</a>.
 Services may be registered with the container by "binding" a service interface 
to a service implementation:</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.myapp.services;
+</div></div><p>Here the service interface is Indexer (presumably inside the 
org.example.myapp.services package, since there isn't an import). Tapestry IoC 
doesn't know about the IndexerImpl class (the service implementation of the 
Indexer service), but it does know about the build() method.</p><p>That's one 
of the great innovations of Tapestry IoC: we don't try to encapsulate in XML or 
annotations all the different ways possible to create a service; those things 
are best expressed in Java code. For a simple case (as here), it would be hard 
for external configuration (again, in XML or Java annotations) to be shorter 
than "new IndexerImpl()".</p><p><em>The above paragraph was written before 
Binding and Autobuilding were introduced.</em></p><p>For more complex and 
realistic scenarios, such as injecting dependencies via the constructor, or 
doing more interest work (such as registering the newly created service for 
events published by some other service), the Java code is simply the most
  direct, flexible, extensible and readable approach.</p><h1 
id="DefiningTapestryIOCServices-BindingandAutobuilding">Binding and 
Autobuilding</h1><p>Tapestry IoC can also <em>autobuild</em> your service. 
Autobuilding is the <em>preferred</em> way to instantiate your 
services.</p><p>Every module may have an optional, static bind() method which 
is passed a <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBinder.html";>ServiceBinder</a>.
 Services may be registered with the container by "binding" a service interface 
to a service implementation:</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.myapp.services;
 
 import org.apache.tapestry5.ioc.ServiceBinder;
 
@@ -132,21 +87,8 @@ public class MyAppModule
     binder.bind(Indexer.class, IndexerImpl.class);
   }
 }</pre>
-</div></div>
-
-<p>You can make repeated calls to ServiceBinder.bind(), to bind additional 
services.</p>
-
-<p>You might ask, "which is better, a builder method for each service, or a 
bind() method for the module?" For simple services, those that are just an 
instantiated instance with simple dependencies, binding is better than 
building. That covers at least 90% of all services, so bind away!</p>
-
-<p>There are many cases, however, where constructing a service is more than 
just instantiating a class. Often the new service will (for example) be 
registered as a listener with some other service. In other cases, the 
implementation of the service is generated at runtime. These are where the 
service builder methods are most useful.</p>
-
-<p>In terms of the evolution of the framework, service builder methods came 
first, and autobuilding was a later addition, inspired by the terseness of the 
<a shape="rect" class="external-link" 
href="http://code.google.com/p/google-guice/"; >Guice</a> IoC container.</p>
-
-<p>Following the convention over configuration principle, the autobuilding of 
services can be even less verbose. If a service interface is passed as a single 
argument to the bind() method, Tapestry will try to find an implementation in 
the same package whose name matches the name of the service interface followed 
by the suffix <em>Impl</em>.</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.myapp.services;
+</div></div><p>You can make repeated calls to ServiceBinder.bind(), to bind 
additional services.</p><p>You might ask, "which is better, a builder method 
for each service, or a bind() method for the module?" For simple services, 
those that are just an instantiated instance with simple dependencies, binding 
is better than building. That covers at least 90% of all services, so bind 
away!</p><p>There are many cases, however, where constructing a service is more 
than just instantiating a class. Often the new service will (for example) be 
registered as a listener with some other service. In other cases, the 
implementation of the service is generated at runtime. These are where the 
service builder methods are most useful.</p><p>In terms of the evolution of the 
framework, service builder methods came first, and autobuilding was a later 
addition, inspired by the terseness of the <a shape="rect" 
class="external-link" href="http://code.google.com/p/google-guice/"; >Guice</a> 
IoC container.</p><
 p>Following the convention over configuration principle, the autobuilding of 
services can be even less verbose. If a service interface is passed as a single 
argument to the bind() method, Tapestry will try to find an implementation in 
the same package whose name matches the name of the service interface followed 
by the suffix <em>Impl</em>.</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.myapp.services;
 
 import org.apache.tapestry5.ioc.ServiceBinder;
 
@@ -157,76 +99,29 @@ public class MyAppModule
     binder.bind(Indexer.class);
   }
 }</pre>
-</div></div>
-
-<h1 id="DefiningTapestryIOCServices-ServiceIds">Service Ids</h1>
-
-<p>Every service will have a unique service id.</p>
-
-<p>When using a service builder method, the service id is the <em>simple 
name</em> of the service interface.</p>
-
-<p>This can be overridden by adding the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html";>ServiceId</a>
 annotation to the service builder method:</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;">
-  @ServiceId("FileSystemIndexer")
+</div></div><h1 id="DefiningTapestryIOCServices-ServiceIds">Service 
Ids</h1><p>Every service will have a unique service id.</p><p>When using a 
service builder method, the service id is the <em>simple name</em> of the 
service interface.</p><p>This can be overridden by adding the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html";>ServiceId</a>
 annotation to the service builder method:</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;">  @ServiceId("FileSystemIndexer")
   public static Indexer buildIndexer(@InjectService("FileSystem") FileSystem 
fileSystem)
   {
      . . .
   }</pre>
-</div></div>
-
-<p>Another option is to add the service id to the method name, after "build", 
for 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;">
-  public static Indexer buildFileSystemIndexer(@InjectService("FileSystem") 
FileSystem fileSystem)
+</div></div><p>Another option is to add the service id to the method name, 
after "build", for 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;">  public static Indexer 
buildFileSystemIndexer(@InjectService("FileSystem") FileSystem fileSystem)
   {
      . . .
   }</pre>
-</div></div>
-
-<p>Here, the service id is "FileSystemIndexer" not "Indexer".</p>
-
-<p>For autobuilt services, the service id can be specified by placing the @<a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html";>ServiceId</a>
 annotation directly on a service implementation class.</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;">
-  @ServiceId("FileSystemIndexer")
+</div></div><p>Here, the service id is "FileSystemIndexer" not 
"Indexer".</p><p>For autobuilt services, the service id can be specified by 
placing the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/ServiceId.html";>ServiceId</a>
 annotation directly on a service implementation class.</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;">  @ServiceId("FileSystemIndexer")
   public class IndexerImpl implements Indexer
   {
       ...
   }</pre>
-</div></div>
-
-<p>When the service is bound, the value of the annotation is used as id:</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;">
-  binder.bind(Indexer.class, IndexerImpl.class);</pre>
-</div></div>
-
-<p>This id can be overriden again by calling the method <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBindingOptions.html#withIdjava.lang.String";>withId</a></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;">
-  binder.bind(Indexer.class, 
IndexerImpl.class).withId("FileSystemIndexer");</pre>
-</div></div>
-
-<h1 
id="DefiningTapestryIOCServices-Injecting_DependenciesInjectingDependencies"><span
 class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-Injecting_Dependencies"></span>Injecting 
Dependencies</h1>
-
-<p>It's pretty unlikely that your service will be able to operate in a total 
vacuum. It will have other dependencies.</p>
-
-<p>Dependencies are provided to a service in one of several ways:</p>
-
-<ul><li>As parameters to the service builder method</li><li>As parameters to 
the service implementation class' constructor (for autobuilt 
services)</li><li>As parameters passed to the constructor of the service's 
module class (to be cached inside instance variables)</li><li>Directly into 
fields of the service implementation</li></ul>
-
-
-<p>For example, let's say the Indexer needs a JobScheduler to control when it 
executes, and a FileSystem to access files and store indexes.</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 static Indexer build(JobScheduler scheduler, FileSystem fileSystem)
+</div></div><p>When the service is bound, the value of the annotation is used 
as id:</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;">  binder.bind(Indexer.class, IndexerImpl.class);</pre>
+</div></div><p>This id can be overriden again by calling the method <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBindingOptions.html#withIdjava.lang.String";>withId</a></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;">  binder.bind(Indexer.class, 
IndexerImpl.class).withId("FileSystemIndexer");</pre>
+</div></div><h1 
id="DefiningTapestryIOCServices-Injecting_DependenciesInjectingDependencies"><span
 class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-Injecting_Dependencies"></span>Injecting 
Dependencies</h1><p>It's pretty unlikely that your service will be able to 
operate in a total vacuum. It will have other dependencies.</p><p>Dependencies 
are provided to a service in one of several ways:</p><ul><li>As parameters to 
the service builder method</li><li>As parameters to the service implementation 
class' constructor (for autobuilt services)</li><li>As parameters passed to the 
constructor of the service's module class (to be cached inside instance 
variables)</li><li>Directly into fields of the service 
implementation</li></ul><p>For example, let's say the Indexer needs a 
JobScheduler to control when it executes, and a FileSystem to access files and 
store indexes.</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 static Indexer build(JobScheduler scheduler, 
FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
 
@@ -234,19 +129,8 @@ public class MyAppModule
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>Tapestry assumes that parameters to builder methods are dependencies; in 
this example it is able to figure out what services to pass in based just on 
the type (later we'll see how we can fine tune this with annotations, when the 
service type is not sufficient to identify a single service).</p>
-
-<p>This is an example of when you would want to use the service builder 
method, rather than just binding the service interface to the implementation 
class: because we want to do something extra, in this case, register the new 
indexer service with the scheduler.</p>
-
-<p>Note that we don't invoke those service builder methods ... we just 
"advertise" (via naming convention or annotation) that we need the named 
services. Tapestry IoC will provide the necessary proxies and, when we start to 
invoke methods on those proxies, will ensure that the full service, including 
its interceptors and its dependencies, are ready to go. Again, this is done in 
a thread-safe manner.</p>
-
-<p>What happens if there is more than one service that implements the 
JobScheduler interface, or the FileSystem interface? You'll see a runtime 
exception, because Tapestry is unable to resolve it down to a <em>single</em> 
service. At this point, it is necessary to <em>disambiguate</em> the link 
between the service interface and <em>one</em> service. One approach is to use 
the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 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;">
-  public static Indexer build(@InjectService("JobScheduler")
+</div></div><p>Tapestry assumes that parameters to builder methods are 
dependencies; in this example it is able to figure out what services to pass in 
based just on the type (later we'll see how we can fine tune this with 
annotations, when the service type is not sufficient to identify a single 
service).</p><p>This is an example of when you would want to use the service 
builder method, rather than just binding the service interface to the 
implementation class: because we want to do something extra, in this case, 
register the new indexer service with the scheduler.</p><p>Note that we don't 
invoke those service builder methods ... we just "advertise" (via naming 
convention or annotation) that we need the named services. Tapestry IoC will 
provide the necessary proxies and, when we start to invoke methods on those 
proxies, will ensure that the full service, including its interceptors and its 
dependencies, are ready to go. Again, this is done in a thread-safe 
manner.</p><p>What happens i
 f there is more than one service that implements the JobScheduler interface, 
or the FileSystem interface? You'll see a runtime exception, because Tapestry 
is unable to resolve it down to a <em>single</em> service. At this point, it is 
necessary to <em>disambiguate</em> the link between the service interface and 
<em>one</em> service. One approach is to use the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 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;">  public static Indexer 
build(@InjectService("JobScheduler")
     JobScheduler scheduler,
 
     @InjectService("FileSystem")
@@ -258,25 +142,8 @@ public class MyAppModule
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>If you find yourself injecting the same dependencies into multiple service 
builder (or service decorator) methods, you can <a shape="rect" 
href="tapestry-ioc-modules.html">cache dependency injections</a> in your 
module, by defining a constructor. This reduces duplication in your module.</p>
-
-<h1 
id="DefiningTapestryIOCServices-DisambiguationwithMarkerAnnotations">Disambiguation
 with Marker Annotations</h1>
-
-<p>In the previous example we were faced with a problem: multiple versions of 
the JobScheduler service. They had the same service interface but unique 
service ids. If you try to inject based on type, the service to inject will be 
ambiguous. Tapestry will throw an exception (identifying the parameter type and 
the matching services that implement that type).</p>
-
-<p>The problem is that when injecting a JobScheduler into some other service 
we need to know which <em>one</em> to inject. Rather than using the service id, 
another approach is to use a <em>marker annotation</em>.</p>
-
-<p>You may optionally link a service implementation with a marker 
annotation.</p>
-
-<p>For example, maybe you have one JobScheduler implementation where the jobs 
are spread across a number of nodes in a cluster, and you have another 
JobScheduler where the jobs are all executed exclusively in the current 
process.</p>
-
-<p>We can associate those two JobSchedulers with two annotations.</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;">
-@Target(
+</div></div><p>If you find yourself injecting the same dependencies into 
multiple service builder (or service decorator) methods, you can <a 
shape="rect" href="tapestry-ioc-modules.html">cache dependency injections</a> 
in your module, by defining a constructor. This reduces duplication in your 
module.</p><h1 
id="DefiningTapestryIOCServices-DisambiguationwithMarkerAnnotations">Disambiguation
 with Marker Annotations</h1><p>In the previous example we were faced with a 
problem: multiple versions of the JobScheduler service. They had the same 
service interface but unique service ids. If you try to inject based on type, 
the service to inject will be ambiguous. Tapestry will throw an exception 
(identifying the parameter type and the matching services that implement that 
type).</p><p>The problem is that when injecting a JobScheduler into some other 
service we need to know which <em>one</em> to inject. Rather than using the 
service id, another approach is to use a <em>marker annotation</em>.
 </p><p>You may optionally link a service implementation with a marker 
annotation.</p><p>For example, maybe you have one JobScheduler implementation 
where the jobs are spread across a number of nodes in a cluster, and you have 
another JobScheduler where the jobs are all executed exclusively in the current 
process.</p><p>We can associate those two JobSchedulers with two 
annotations.</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;">@Target(
 { PARAMETER, FIELD })
 @Retention(RUNTIME)
 @Documented
@@ -303,15 +170,8 @@ public class MyModule
     binder.bind(JobScheduler.class, 
SimpleJobSchedulerImpl.class).withId("InProcessJobScheduler").withMarker(InProcess.class);
   }
 }</pre>
-</div></div>
-
-<p>Notice that the marker annotations have no attributes. Further, we support 
markers on fields (for use in Tapestry components) as well as parameters.</p>
-
-<p>To get the right version of the service, you use one of the annotations:</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
+</div></div><p>Notice that the marker annotations have no attributes. Further, 
we support markers on fields (for use in Tapestry components) as well as 
parameters.</p><p>To get the right version of the service, you use one of the 
annotations:</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
 {
   private final JobScheduler jobScheduler;
 
@@ -322,42 +182,14 @@ public class MyServiceImpl implements My
 
   . . .
 }  </pre>
-</div></div>
-
-<p>The @Clustered annotation on the parameter is combined with the parameter 
type (JobScheduler) to find the exact service implementation.</p>
-
-<p>Why is this better than using the service id? It's more refactoring-safe. 
Service ids can change, which can break your services. However, using an IDE to 
rename or move an annotation class or service interface will be able to update 
all the uses of the annotation or interface.</p>
-
-<p>With a service builder method, you use the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Marker.html";>Marker</a>
 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;">
-  @Marker(Clustered.class)
+</div></div><p>The @Clustered annotation on the parameter is combined with the 
parameter type (JobScheduler) to find the exact service 
implementation.</p><p>Why is this better than using the service id? It's more 
refactoring-safe. Service ids can change, which can break your services. 
However, using an IDE to rename or move an annotation class or service 
interface will be able to update all the uses of the annotation or 
interface.</p><p>With a service builder method, you use the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Marker.html";>Marker</a>
 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;">  @Marker(Clustered.class)
   public JobScheduler buildClusteredJobScheduler()
   {
     return . . .;
   }</pre>
-</div></div>
-
-<p>The @Marker annotation may also be placed on an implementation class, which 
means that you may omit the call to withMarker() inside the bind() method.</p>
-
-<p>Finally, the point of injection may have multiple marker annotations; only 
services that are marked with <em>all</em> those markers will be considered for 
injection. Each marker annotation creates an increasingly narrow subset from 
the set of all possible services (compatible with the indicated dependency 
type).</p>
-
-<h1 id="DefiningTapestryIOCServices-LocalDependencies">Local Dependencies</h1>
-
-<p>A special marker interface, @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Local.html";>Local</a>,
 indicates a dependency that should only be resolved using services from within 
<em>the same module</em>.</p>
-
-<p>@Local can also be combined with other marker annotations.</p>
-
-<h1 
id="DefiningTapestryIOCServices-InjectingDependenciesforAutobuiltServices">Injecting
 Dependencies for Autobuilt Services</h1>
-
-<p>With autobuilt services, there's no service builder method in which to 
specify injections.</p>
-
-<p>Instead, the injections occur on <em>constructor</em> for the 
implementation class:</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.myapp.services;
+</div></div><p>The @Marker annotation may also be placed on an implementation 
class, which means that you may omit the call to withMarker() inside the bind() 
method.</p><p>Finally, the point of injection may have multiple marker 
annotations; only services that are marked with <em>all</em> those markers will 
be considered for injection. Each marker annotation creates an increasingly 
narrow subset from the set of all possible services (compatible with the 
indicated dependency type).</p><h1 
id="DefiningTapestryIOCServices-LocalDependencies">Local Dependencies</h1><p>A 
special marker interface, @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Local.html";>Local</a>,
 indicates a dependency that should only be resolved using services from within 
<em>the same module</em>.</p><p>@Local can also be combined with other marker 
annotations.</p><h1 
id="DefiningTapestryIOCServices-InjectingDependenciesforAutobuiltServices"
 >Injecting Dependencies for Autobuilt Services</h1><p>With autobuilt services, 
 >there's no service builder method in which to specify 
 >injections.</p><p>Instead, the injections occur on <em>constructor</em> for 
 >the implementation class:</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.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
 
@@ -372,17 +204,8 @@ public class IndexerImpl implements Inde
 
   . . .
 }</pre>
-</div></div>
-
-<p>If the class has multiple constructors, the constructor with the 
<em>most</em> parameters will be invoked. Alternately, you may mark a single 
constructor with the Inject annotation, and Tapestry will use <em>that</em> 
constructor specifically, ignoring all other constructors.</p>
-
-<p>Note how we are using final fields for our dependencies; this is generally 
a Good Idea. These services will often execute inside a multi-threaded 
environment, such as a web application, and the use of final fields inside a 
constructor ensures that the fields will be properly published (meaning, 
"visible to other threads") in accordance with the Java Memory Model.</p>
-
-<p>Once thing that is not a good idea is to pass in another service, such as 
JobScheduler in the previous example, and pass <code>this</code> from a 
constructor:</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.myapp.services;
+</div></div><p>If the class has multiple constructors, the constructor with 
the <em>most</em> parameters will be invoked. Alternately, you may mark a 
single constructor with the Inject annotation, and Tapestry will use 
<em>that</em> constructor specifically, ignoring all other 
constructors.</p><p>Note how we are using final fields for our dependencies; 
this is generally a Good Idea. These services will often execute inside a 
multi-threaded environment, such as a web application, and the use of final 
fields inside a constructor ensures that the fields will be properly published 
(meaning, "visible to other threads") in accordance with the Java Memory 
Model.</p><p>Once thing that is not a good idea is to pass in another service, 
such as JobScheduler in the previous example, and pass <code>this</code> from a 
constructor:</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.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
 
@@ -401,21 +224,8 @@ public class IndexerImpl implements Inde
 
   . . .
 }</pre>
-</div></div>
-
-<p>Understanding why this is a bad idea involves a long detour into inner 
details of the Java Memory Model. The short form is that other threads may end 
up invoking methods on the IndexerImpl instance, and its fields (even though 
they are final, even though they appear to already have been set) may be 
uninitialized.</p>
-
-<h1 id="DefiningTapestryIOCServices-FieldInjection">Field Injection</h1>
-
-<p>The @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 and @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 annotations may be used on instance fields of a service implementation class, 
as an alternative to passing dependencies of the service implementation in via 
the constructor.</p>
-
-<p>Note that only dependencies are settable this way; if you want resources, 
including the service's <a shape="rect" 
href="tapestry-ioc-configuration.html">configuration</a>, you must pass those 
through the constructor. You <em>are</em> free to mix and match, injecting 
partially with field injection and partially with constructor injection.</p>
-
-<p>Caution: injection via fields uses reflection to make the fields 
accessible. In addition, it may not be as thread-safe as using the constructor 
to assign to final fields.</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.myapp.services;
+</div></div><p>Understanding why this is a bad idea involves a long detour 
into inner details of the Java Memory Model. The short form is that other 
threads may end up invoking methods on the IndexerImpl instance, and its fields 
(even though they are final, even though they appear to already have been set) 
may be uninitialized.</p><h1 
id="DefiningTapestryIOCServices-FieldInjection">Field Injection</h1><p>The @<a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 and @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 annotations may be used on instance fields of a service implementation class, 
as an alternative to passing dependencies of the service implementation in via 
the constructor.</p><p>Note that only dependencies are settable this way; if 
you want resources, including the s
 ervice's <a shape="rect" 
href="tapestry-ioc-configuration.html">configuration</a>, you must pass those 
through the constructor. You <em>are</em> free to mix and match, injecting 
partially with field injection and partially with constructor 
injection.</p><p>Caution: injection via fields uses reflection to make the 
fields accessible. In addition, it may not be as thread-safe as using the 
constructor to assign to final fields.</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.myapp.services;
 
 import org.apache.tapestry5.ioc.annotations.InjectService;
 
@@ -426,94 +236,12 @@ public class IndexerImpl implements Inde
 
   . . .
 }</pre>
-</div></div>
-
-<h1 id="DefiningTapestryIOCServices-ServiceScopeDefiningServiceScope"><span 
class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-ServiceScope"></span>Defining Service Scope</h1>
-
-<p>Each service has a <em>scope</em> that controls when the service 
implementation is instantiated. There are two built in scopes: "singleton" and 
"perthread", but more can be added.</p>
-
-<p>Service scope is specified using the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Scope.html";>Scope</a>
 annotation, which is attached to a builder method, or to the service 
implementation class.  When this annotation is not present, the default scope, 
"singleton" is used.</p>
-
-<h3 id="DefiningTapestryIOCServices-singleton">singleton</h3>
-
-<p>Most services use the default scope, "singleton". With this scope a 
<em>proxy</em> is created when the service is first referenced. By reference, 
we mean any situation in which the service is requested by name, such as using 
the @InjectService annotation on a service builder method, or by using the <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Registry.html";>Registry</a>
 API from outside the container.</p>
-
-<p>In any case, the service proxy will only create the service implementation 
when a method on the service interface is invoked. Until then, the service can 
be thought of as "virtual". As the first method is invoked, the service builder 
method is invoked, then any service decorations occur. This construction 
process, called "realization", occurs only once.</p>
-
-<p>You should be aware when writing services that your code must be thread 
safe; any service you define could be invoked simultaneously by multiple 
threads. This is rarely an issue in practice, since most services take input, 
use local variables, and invoke methods on other services, without making use 
of non-final instance variables. The few instance variables in a service 
implementation are usually references to other Tapestry IoC services.</p>
-
-<h3 id="DefiningTapestryIOCServices-perthread">perthread</h3>
-
-<p>The perthread service scope exists primarily to help multi-threaded servlet 
applications, though it has other applications.</p>
-
-<p>With perthread, the service proxy will delegate to a local service instance 
that is associated with the current thread. Two different threads, invoking 
methods on the same proxy, will ultimately be invoking methods on two different 
service instances, each reserved to their own thread.</p>
-
-<p>This is useful when a service needs to keep request specific state, such as 
information extracted from the HttpServletRequest (in a web application). The 
default singleton model would not work in such a multithreaded environment. 
Using perthread on select services allows state to be isolated to those 
services. Because the dispatch occurs <em>inside</em> the proxy, you can treat 
the service as a global, like any other.</p>
-
-<p>You will see that your service builder method is invoked more than once. It 
is invoked in each thread where the perthread service is used.</p>
-
-<p>At the end of the request, the Registry's cleanupThread() method is 
invoked; it will discard any perthread service implementations for the current 
thread.</p>
-
-<p><strong>Caution:</strong> A common technique in Tapestry IoC is to have a 
service builder method register a core service implementation as an event 
listener with some event hub service. With non-singleton objects, this can 
cause a number of problems; the event hub will hold a reference to the 
per-thread instance, even after that per-thread instance has been cleaned up 
(discarded by the inner proxy). Simply put, this is a pattern to avoid. For the 
most part, perthread services should be simple holders of data specific to a 
thread or a request, and should not have overly complex relationships with the 
other services in the registry.</p>
-
-<h1 
id="DefiningTapestryIOCServices-DefiningthescopeofAutobuiltServices">Defining 
the scope of Autobuilt Services</h1>
-
-<p>There are two options for defining the scope for an autobuilt service.</p>
-
-<p>The service implementation class may include the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Scope.html";>Scope</a>
 annotation. This is generally the preferred way to specify scope.</p>
-
-<p>In addition, it is possible to specify the scope when binding the 
service:</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;">
-  bind(MyServiceInterface.class, 
MyServiceImpl.class).scope(ScopeConstants.PERTHREAD);</pre>
-</div></div>
-
-<h1 id="DefiningTapestryIOCServices-EagerLoadingServices">Eager Loading 
Services</h1>
-
-<p>Services are normally created only as needed (per the scope discussion 
above).</p>
-
-<p>This can be tweaked slightly; by adding the @<a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>EagerLoad</a>
 annotation to the service builder method, Tapestry will instantiate the 
service when the Registry is first created.</p>
-
-<p>This will cause the service builder method to be invoked, as well as any 
service decorator methods.</p>
-
-<p>This feature is used when a service manages a resource, such as a thread, 
that needs to be created as soon as the application starts up. Another common 
example is a service that listens for events produced by a second service; the 
first service may need to be created, and start listening, before any of its 
service methods are invoked (which would normally trigger the instantiation of 
the service).</p>
-
-<p>Many services may be annotated with @EagerLoad; the order in which services 
are created is not defined.</p>
-
-<p>With the perthread scope, the service builder method will not be invoked 
(this won't happen until a service method is invoked), but the decorators for 
the service will be created.</p>
-
-<h1 id="DefiningTapestryIOCServices-EagerLoadingAutobuiltServices">Eager 
Loading Autobuilt Services</h1>
-
-<p>As with service scope, there are two options for indicating that an 
autobuilt service should be eagerly loaded.</p>
-
-<p>The service implementation class may include the @EagerLoad annotation.</p>
-
-<p>You may also specify eager loading explicitly when binding the service:</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;">
-  bind(MyServiceInterface.class, MyServiceImpl.class).eagerLoad();</pre>
-</div></div>
-
-<h1 id="DefiningTapestryIOCServices-InjectingResources">Injecting 
Resources</h1>
-
-<p>In addition to injecting services, Tapestry will key off of the parameter 
type to allow other things to be injected.</p>
-
-<ul><li>java.lang.String: unique id for the service</li><li><a shape="rect" 
class="external-link" href="http://www.slf4j.org/api/org/slf4j/Logger.html"; 
>org.slf4j.Logger</a>: logger for the service</li><li>java.lang.Class: service 
interface implemented by the service to be constructed</li><li><a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceResources.html";>ServiceResources</a>:
 access to other services</li></ul>
-
-
-<p>No annotation is needed for these cases.</p>
-
-<p>See also <a shape="rect" href="tapestry-ioc-configuration.html">service 
configuration</a> for additional special cases of resources that can be 
injected.</p>
-
-<p>Note: resources may not be injected into fields, they are injectable only 
via method or constructor 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;">
-  public static Indexer build(String serviceId, Log serviceLog,
+</div></div><h1 
id="DefiningTapestryIOCServices-ServiceScopeDefiningServiceScope"><span 
class="confluence-anchor-link" 
id="DefiningTapestryIOCServices-ServiceScope"></span>Defining Service 
Scope</h1><p>Each service has a <em>scope</em> that controls when the service 
implementation is instantiated. There are two built in scopes: "singleton" and 
"perthread", but more can be added.</p><p>Service scope is specified using the 
@<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Scope.html";>Scope</a>
 annotation, which is attached to a builder method, or to the service 
implementation class. When this annotation is not present, the default scope, 
"singleton" is used.</p><h3 
id="DefiningTapestryIOCServices-singleton">singleton</h3><p>Most services use 
the default scope, "singleton". With this scope a <em>proxy</em> is created 
when the service is first referenced. By reference, we mean any situation in 
which the service i
 s requested by name, such as using the @InjectService annotation on a service 
builder method, or by using the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Registry.html";>Registry</a>
 API from outside the container.</p><p>In any case, the service proxy will only 
create the service implementation when a method on the service interface is 
invoked. Until then, the service can be thought of as "virtual". As the first 
method is invoked, the service builder method is invoked, then any service 
decorations occur. This construction process, called "realization", occurs only 
once.</p><p>You should be aware when writing services that your code must be 
thread safe; any service you define could be invoked simultaneously by multiple 
threads. This is rarely an issue in practice, since most services take input, 
use local variables, and invoke methods on other services, without making use 
of non-final instance variables. The few insta
 nce variables in a service implementation are usually references to other 
Tapestry IoC services.</p><h3 
id="DefiningTapestryIOCServices-perthread">perthread</h3><p>The perthread 
service scope exists primarily to help multi-threaded servlet applications, 
though it has other applications.</p><p>With perthread, the service proxy will 
delegate to a local service instance that is associated with the current 
thread. Two different threads, invoking methods on the same proxy, will 
ultimately be invoking methods on two different service instances, each 
reserved to their own thread.</p><p>This is useful when a service needs to keep 
request specific state, such as information extracted from the 
HttpServletRequest (in a web application). The default singleton model would 
not work in such a multithreaded environment. Using perthread on select 
services allows state to be isolated to those services. Because the dispatch 
occurs <em>inside</em> the proxy, you can treat the service as a global, like 
 any other.</p><p>You will see that your service builder method is invoked more 
than once. It is invoked in each thread where the perthread service is 
used.</p><p>At the end of the request, the Registry's cleanupThread() method is 
invoked; it will discard any perthread service implementations for the current 
thread.</p><p><strong>Caution:</strong> A common technique in Tapestry IoC is 
to have a service builder method register a core service implementation as an 
event listener with some event hub service. With non-singleton objects, this 
can cause a number of problems; the event hub will hold a reference to the 
per-thread instance, even after that per-thread instance has been cleaned up 
(discarded by the inner proxy). Simply put, this is a pattern to avoid. For the 
most part, perthread services should be simple holders of data specific to a 
thread or a request, and should not have overly complex relationships with the 
other services in the registry.</p><h1 id="DefiningTapestryIOCServi
 ces-DefiningthescopeofAutobuiltServices">Defining the scope of Autobuilt 
Services</h1><p>There are two options for defining the scope for an autobuilt 
service.</p><p>The service implementation class may include the @<a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Scope.html";>Scope</a>
 annotation. This is generally the preferred way to specify scope.</p><p>In 
addition, it is possible to specify the scope when binding the service:</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;">  bind(MyServiceInterface.class, 
MyServiceImpl.class).scope(ScopeConstants.PERTHREAD);</pre>
+</div></div><h1 id="DefiningTapestryIOCServices-EagerLoadingServices">Eager 
Loading Services</h1><p>Services are normally created only as needed (per the 
scope discussion above).</p><p>This can be tweaked slightly; by adding the @<a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>EagerLoad</a>
 annotation to the service builder method, Tapestry will instantiate the 
service when the Registry is first created.</p><p>This will cause the service 
builder method to be invoked, as well as any service decorator 
methods.</p><p>This feature is used when a service manages a resource, such as 
a thread, that needs to be created as soon as the application starts up. 
Another common example is a service that listens for events produced by a 
second service; the first service may need to be created, and start listening, 
before any of its service methods are invoked (which would normally trigger the 
instantiation o
 f the service).</p><p>Many services may be annotated with @EagerLoad; the 
order in which services are created is not defined.</p><p>With the perthread 
scope, the service builder method will not be invoked (this won't happen until 
a service method is invoked), but the decorators for the service will be 
created.</p><h1 
id="DefiningTapestryIOCServices-EagerLoadingAutobuiltServices">Eager Loading 
Autobuilt Services</h1><p>As with service scope, there are two options for 
indicating that an autobuilt service should be eagerly loaded.</p><p>The 
service implementation class may include the @EagerLoad annotation.</p><p>You 
may also specify eager loading explicitly when binding the service:</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;">  bind(MyServiceInterface.class, 
MyServiceImpl.class).eagerLoad();</pre>
+</div></div><h1 id="DefiningTapestryIOCServices-InjectingResources">Injecting 
Resources</h1><p>In addition to injecting services, Tapestry will key off of 
the parameter type to allow other things to be 
injected.</p><ul><li>java.lang.String: unique id for the service</li><li><a 
shape="rect" class="external-link" 
href="http://www.slf4j.org/api/org/slf4j/Logger.html"; >org.slf4j.Logger</a>: 
logger for the service</li><li>java.lang.Class: service interface implemented 
by the service to be constructed</li><li><a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceResources.html";>ServiceResources</a>:
 access to other services</li></ul><p>No annotation is needed for these 
cases.</p><p>See also <a shape="rect" 
href="tapestry-ioc-configuration.html">service configuration</a> for additional 
special cases of resources that can be injected.</p><p>Note: resources may not 
be injected into fields, they are injectable only via method or
  constructor 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;">  public static Indexer build(String serviceId, Log 
serviceLog,
      JobScheduler scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem);
@@ -522,19 +250,8 @@ public class IndexerImpl implements Inde
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>The order of parameters is completely irrelevant. They can come first or 
last or be interspersed however you like.</p>
-
-<p>Injecting in the ServiceResources can be handy when you want to calculate 
the name of a service dependency on the fly. However, in the general case 
(where the id of service dependencies is known at build time), it is easier to 
use the @InjectService annotation.</p>
-
-<p>The Log's name (used when configuring logging settings for the service) 
consists of the module class name and the service id seperated by a period, 
i.e. "org.example.myapp.MyModule.Indexer".</p>
-
-<p>Further, ServiceResources includes an autobuild() method that allows you to 
easily trigger the construction of a class, including dependencies. Thus the 
previos example could be rewritten as:</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 static Indexer build(ServiceResources resources, JobScheduler 
jobScheduler)
+</div></div><p>The order of parameters is completely irrelevant. They can come 
first or last or be interspersed however you like.</p><p>Injecting in the 
ServiceResources can be handy when you want to calculate the name of a service 
dependency on the fly. However, in the general case (where the id of service 
dependencies is known at build time), it is easier to use the @InjectService 
annotation.</p><p>The Log's name (used when configuring logging settings for 
the service) consists of the module class name and the service id seperated by 
a period, i.e. "org.example.myapp.MyModule.Indexer".</p><p>Further, 
ServiceResources includes an autobuild() method that allows you to easily 
trigger the construction of a class, including dependencies. Thus the previos 
example could be rewritten as:</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 static Indexer build(ServiceResources 
resources, JobScheduler jobScheduler)
   {
     IndexerImpl indexer = resources.autobuild(IndexerImpl.class);
 
@@ -542,19 +259,8 @@ public class IndexerImpl implements Inde
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>This works the exact same way with autobuilt services, except that the 
parameters of the service implementation constructor are considered, rather 
than the parameters of the service builder method.</p>
-
-<p>The @InjectService annotation takes precedence over these resources.</p>
-
-<p>If the @InjectService annotation is not present, and the parameter type 
does not exactly match a resource type, then <a shape="rect" 
href="object-providers.html">object injection</a> occurs. Object injection will 
find the correct object to inject based on a number of (extensible) factors, 
including the parameter type and any additional annotations on the 
parameter.</p>
-
-<p>Every once and a while, you'll have a conflict between a resource type and 
an object injection. For example, the following does not work as expected:</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 static Indexer build(String serviceId, Log serviceLog,
+</div></div><p>This works the exact same way with autobuilt services, except 
that the parameters of the service implementation constructor are considered, 
rather than the parameters of the service builder method.</p><p>The 
@InjectService annotation takes precedence over these resources.</p><p>If the 
@InjectService annotation is not present, and the parameter type does not 
exactly match a resource type, then <a shape="rect" 
href="object-providers.html">object injection</a> occurs. Object injection will 
find the correct object to inject based on a number of (extensible) factors, 
including the parameter type and any additional annotations on the 
parameter.</p><p>Every once and a while, you'll have a conflict between a 
resource type and an object injection. For example, the following does not work 
as expected:</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 static Indexer build(String serviceId, Log 
serviceLog,
      JobScheduler scheduler, FileSystem fileSystem,
      @Value("${index-alerts-email}")
      String alertEmail)
@@ -565,13 +271,8 @@ public class IndexerImpl implements Inde
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>It doesn't work because type String always gets the service id, as a 
resource (as with the serviceId parameter). In order to get this to work, we 
need to turn off the resource injection for the alertEmail parameter. That's 
what the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 annotation does:</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 static Indexer build(String serviceId, Log serviceLog,
+</div></div><p>It doesn't work because type String always gets the service id, 
as a resource (as with the serviceId parameter). In order to get this to work, 
we need to turn off the resource injection for the alertEmail parameter. That's 
what the @<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Inject.html";>Inject</a>
 annotation does:</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 static Indexer build(String serviceId, Log 
serviceLog,
      JobScheduler scheduler, FileSystem fileSystem,
      @Inject @Value("${index-alerts-email}")
      String alertEmail)
@@ -582,32 +283,8 @@ public class IndexerImpl implements Inde
 
     return indexer;
   }</pre>
-</div></div>
-
-<p>Here, the alertEmail parameter will receive the configured alerts email 
(see <a shape="rect" href="symbols.html">the symbols documentation</a> for more 
about this syntax) rather than the service id.</p>
-
-<h1 id="DefiningTapestryIOCServices-BindingServiceBuilders">Binding 
ServiceBuilders</h1>
-
-<p>Yet another option is available: instead of binding an interface to a 
implemention class, you can bind a service to a <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBuilder.html";>ServiceBuilder</a>,
 a callback used to create the service implementation. This is very useful in 
very rare circumstances.</p>
-
-<h1 id="DefiningTapestryIOCServices-BuiltinServices">Builtin Services</h1>
-
-<p>A few services within the Tapestry IOC Module are "builtin"; there is no 
service builder method in the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TapestryIOCModule.html";>TapestryIOCModule</a>
 class.</p>
-
-<div class="table-wrap"><table class="confluenceTable"><tbody><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p> <strong>Service Id</strong> 
</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <strong>Service 
Interface</strong> </p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p> ClassFactory </p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p> <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/ClassFactory.html";>ClassFactory</a>
 </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> 
LoggerSource </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <a 
shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/LoggerSource.html";>LoggerSource</a>
 </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> 
RegistryShutdownHub </p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p> <a 
 shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/RegistryShutdownHub.html";>RegistryShutdownHub</a>
 </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> 
PerthreadManager </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> 
<a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PerthreadManager.html";>PerthreadManager</a>
 </p></td></tr></tbody></table></div>
-
-
-<p>Consult the JavaDoc for each of these services to identify under what 
circumstances you'll need to use them.</p>
-
-<h1 id="DefiningTapestryIOCServices-MutuallyDependentServices">Mutually 
Dependent Services</h1>
-
-<p>One of the benefits of Tapestry IoC's proxy-based approach to just-in-time 
instantiation is the automatic support for mutually dependent services. For 
example, suppose that the Indexer and the FileSystem needed to talk directly to 
each other. Normally, this would cause a "chicken-and-the-egg" problem: which 
one to create first?</p>
-
-<p>With Tapestry IoC, this is not even considered a special case:</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 static Indexer buildIndexer(JobScheduler scheduler, FileSystem 
fileSystem)
+</div></div><p>Here, the alertEmail parameter will receive the configured 
alerts email (see <a shape="rect" href="symbols.html">the symbols 
documentation</a> for more about this syntax) rather than the service 
id.</p><h1 id="DefiningTapestryIOCServices-BindingServiceBuilders">Binding 
ServiceBuilders</h1><p>Yet another option is available: instead of binding an 
interface to a implemention class, you can bind a service to a <a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ServiceBuilder.html";>ServiceBuilder</a>,
 a callback used to create the service implementation. This is very useful in 
very rare circumstances.</p><h1 
id="DefiningTapestryIOCServices-BuiltinServices">Builtin Services</h1><p>A few 
services within the Tapestry IOC Module are "builtin"; there is no service 
builder method in the <a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TapestryIOCM
 odule.html">TapestryIOCModule</a> class.</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><strong>Service Id</strong></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><strong>Service 
Interface</strong></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>ClassFactory</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/ClassFactory.html";>ClassFactory</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>LoggerSource</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/LoggerSource.html";>LoggerSource</a></p></td></tr><tr><td
 colspan="1" rowspan="1" 
class="confluenceTd"><p>RegistryShutdownHub</p></td><td colspan="1" rowspan="1
 " class="confluenceTd"><p><a shape="rect" class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/RegistryShutdownHub.html";>RegistryShutdownHub</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>PerthreadManager</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a shape="rect" 
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PerthreadManager.html";>PerthreadManager</a></p></td></tr></tbody></table></div><p>Consult
 the JavaDoc for each of these services to identify under what circumstances 
you'll need to use them.</p><h1 
id="DefiningTapestryIOCServices-MutuallyDependentServices">Mutually Dependent 
Services</h1><p>One of the benefits of Tapestry IoC's proxy-based approach to 
just-in-time instantiation is the automatic support for mutually dependent 
services. For example, suppose that the Indexer and the FileSystem needed to 
talk directly to each other
 . Normally, this would cause a "chicken-and-the-egg" problem: which one to 
create first?</p><p>With Tapestry IoC, this is not even considered a special 
case:</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 static Indexer buildIndexer(JobScheduler 
scheduler, FileSystem fileSystem)
   {
     IndexerImpl indexer = new IndexerImpl(fileSystem);
 
@@ -620,16 +297,7 @@ public class IndexerImpl implements Inde
   {
     return new FileSystemImpl(indexer);
   }  </pre>
-</div></div>
-
-<p>Here, Indexer and FileSystem are mutually dependent. Eventually, one or the 
other of them will be created ... let's say its FileSystem. The 
buildFileSystem() builder method will be invoked, and a proxy to Indexer will 
be passed in. Inside the FileSystemImpl constructor (or at some later date), a 
method of the Indexer service will be invoked, at which point, the 
builderIndexer() method is invoked. It still receives the proxy to the 
FileSystem service.</p>
-
-<p>If the order is reversed, such that Indexer is built before FileSystem, 
everything still works the same.</p>
-
-<p>This approach can be very powerful.  For example, it can be used to break 
apart untestable monolithic code into two mutually dependent halves, each of 
which can be unit tested.</p>
-
-<p>The exception to this rule is a service that depends on itself <em>during 
construction</em>. This can occur when (indirectly, through other services) 
building the service tries to invoke a method on the service being built. This 
can happen when the service implementation's constructor invoke methods on 
service dependencies passed into it, or when the service builder method itself 
does the same. This is actually a very rare case and difficult to 
illustrate.</p>
-</div>
+</div></div><p>Here, Indexer and FileSystem are mutually dependent. 
Eventually, one or the other of them will be created ... let's say its 
FileSystem. The buildFileSystem() builder method will be invoked, and a proxy 
to Indexer will be passed in. Inside the FileSystemImpl constructor (or at some 
later date), a method of the Indexer service will be invoked, at which point, 
the builderIndexer() method is invoked. It still receives the proxy to the 
FileSystem service.</p><p>If the order is reversed, such that Indexer is built 
before FileSystem, everything still works the same.</p><p>This approach can be 
very powerful. For example, it can be used to break apart untestable monolithic 
code into two mutually dependent halves, each of which can be unit 
tested.</p><p>The exception to this rule is a service that depends on itself 
<em>during construction</em>. This can occur when (indirectly, through other 
services) building the service tries to invoke a method on the service being 
built. This
  can happen when the service implementation's constructor invoke methods on 
service dependencies passed into it, or when the service builder method itself 
does the same. This is actually a very rare case and difficult to 
illustrate.</p><p>&#160;</p><p></p></div>
 </div>
 
 <div class="clearer"></div>

Modified: 
websites/production/tapestry/content/dependencies-tools-and-plugins.html
==============================================================================
--- websites/production/tapestry/content/dependencies-tools-and-plugins.html 
(original)
+++ websites/production/tapestry/content/dependencies-tools-and-plugins.html 
Sat Aug  8 17:20:04 2015
@@ -27,16 +27,6 @@
   </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css">
 
-    <link href='/resources/highlighter/styles/shCoreCXF.css' rel='stylesheet' 
type='text/css' />
-  <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
-  <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
-  <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
-  <script type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,7 +57,7 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p>As much as we would like to dive into Tapestry 
right now, we must first talk about setting up your development environment. 
The joy and the pain of Java development is the volume of choice available. 
There's just a bewildering number of JDKs, IDEs and other TLAs (Three Letter 
Acronyms) out there.</p><p>Let's talk about a stack of tools, all open source 
and freely available, that you'll need to setup. Likely you have some of these, 
or some version of these, already on your development machine.</p><h1 
id="Dependencies,ToolsandPlugins-JDK1.5orNewer">JDK 1.5 or 
Newer</h1><p>Tapestry requires Java Development Kit (JDK) version 1.5 or newer, 
except that starting with Tapestry 5.4 you must use JDK 1.6 or newer. JDK 1.8 
works only for Tapestry 5.3.8 or newer (but see the <a shape="rect" 
href="release-notes-538.html">release notes</a>).</p><h1 
id="Dependencies,ToolsandPlugins-EclipseIDE">Eclipse IDE</h1><p>For this 
tutorial we'll assume you're using Eclipse as 
 your Integrated Development Environment (IDE). Eclipse is a popular IDE, but 
feel free to adapt these instructions to IntelliJ, NetBeans, or any 
other.</p><p>Eclipse comes in various flavors, and includes a reasonable XML 
editor built-in. It can be <a shape="rect" class="external-link" 
href="http://www.eclipse.org/downloads/"; >downloaded from the eclipse.org web 
site</a>. We recommend the latest version of Eclipse IDE for Java Developers 
(but anything from version 3.7 onward should work fine).</p><h1 
id="Dependencies,ToolsandPlugins-ApacheMaven3">Apache Maven 3</h1><p>Maven is a 
software build tool with the ability to automatically download project 
dependencies (such as the Tapestry JAR files, and the JAR files that Tapestry 
itself depends on) from one of several central repositories.</p><p>Maven is not 
essential for using Tapestry, but is especially helpful when performing the 
initial set-up of a Tapestry application.</p><p>Eclipse comes with a Maven 
plugin,&#160;<a shape="rect" cl
 ass="external-link" href="http://eclipse.org/m2e/"; >M2Eclipse</a> (also known 
as m2e) with an embedded version of Maven. We'll use that here for simplicity's 
sake. Alternatively, you could install Maven from <a shape="rect" 
class="external-link" 
href="http://maven.apache.org/download.html";>http://maven.apache.org/download.html</a>
 and use it from the command line ("mvn").</p><h1 
id="Dependencies,ToolsandPlugins-Jetty">Jetty</h1><p>Jetty is an open source 
web server and servlet container available from the Eclipse Foundation. Jetty 
is designed for high performance and easy embedding in other software. Maven 
can download it for you and run it automatically, so you DO NOT have to 
download it for this tutorial. Alternatively, you could download and install 
the RunJettyRun Eclipse plugin from the Eclipse Marketplace.</p><h1 
id="Dependencies,ToolsandPlugins-Tapestry">Tapestry</h1><p>You should not have 
to download this directly; as we'll see, Maven should take care of downloading 
Tapestry
 , and its dependencies, as needed.</p><p>Next: <a shape="rect" 
href="creating-the-skeleton-application.html">Creating The Skeleton 
Application</a></p><hr><p></p></div>
+<div id="ConfluenceContent"><p>As much as we would like to dive right into the 
code, we must first set up your development environment. Likely you have some 
of these, or reasonable alternatives, already on your development 
machine.</p><h1 id="Dependencies,ToolsandPlugins-JDK1.5orNewer">JDK 1.5 or 
Newer</h1><p>Tapestry requires Java Development Kit (JDK) version 1.5 or newer, 
except that starting with Tapestry 5.4 you must use JDK 1.6 or newer. JDK 1.8 
works only for Tapestry 5.3.8 or newer (but see the <a shape="rect" 
href="release-notes-538.html">release notes</a>).</p><h1 
id="Dependencies,ToolsandPlugins-EclipseIDE">Eclipse IDE</h1><p>For this 
tutorial we'll assume you're using Eclipse as your Integrated Development 
Environment (IDE). Eclipse is a popular IDE, but feel free to adapt these 
instructions to IntelliJ, NetBeans, or any other.</p><p>Eclipse comes in 
various flavors, and includes a reasonable XML editor built-in. It can be <a 
shape="rect" class="external-link" href="http
 ://www.eclipse.org/downloads/" >downloaded from the eclipse.org web site</a>. 
We recommend the latest version of Eclipse IDE for Java Developers (but 
anything from version 3.7 onward should work fine).</p><h1 
id="Dependencies,ToolsandPlugins-ApacheMaven3">Apache Maven 3</h1><p>Maven is a 
software build tool with the ability to automatically download project 
dependencies (such as the Tapestry JAR files, and the JAR files that Tapestry 
itself depends on) from one of several central repositories.</p><p>Maven is not 
essential for using Tapestry, but is especially helpful when performing the 
initial set-up of a Tapestry application.</p><p>Eclipse comes with a Maven 
plugin,&#160;<a shape="rect" class="external-link" 
href="http://eclipse.org/m2e/"; >M2Eclipse</a> (also known as m2e) with an 
embedded version of Maven. We'll use that here for simplicity's sake. 
Alternatively, you could install Maven from <a shape="rect" 
class="external-link" href="http://maven.apache.org/download.html";>http:/
 /maven.apache.org/download.html</a> and use it from the command line 
("mvn").</p><h1 id="Dependencies,ToolsandPlugins-Jetty">Jetty</h1><p>For 
simplicity, this tutorial uses Jetty, a lightweight open source web server and 
servlet container available from the Eclipse Foundation. Of course, you could 
use pretty much any other Java servlet container (Tomcat, Glassfish, JBoss, 
etc), but the instructions that follow assume Jetty.</p><p>We will use Maven to 
download and run Jetty automatically, so you will NOT have to download it for 
this tutorial. (Alternatively, you could download and install the RunJettyRun 
Eclipse plugin from the Eclipse Marketplace.)</p><h1 
id="Dependencies,ToolsandPlugins-Tapestry">Tapestry</h1><p>Tapestry is 
available as a set of JAR files, but you will not have to download them 
yourself. As with Jetty, Maven will take care of downloading Tapestry and its 
dependencies.</p><p>Next: <a shape="rect" 
href="creating-the-skeleton-application.html">Creating The Skeleton Ap
 plication</a></p><hr><p></p><p>&#160;</p><p>&#160;</p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/exploring-the-project.html
==============================================================================
--- websites/production/tapestry/content/exploring-the-project.html (original)
+++ websites/production/tapestry/content/exploring-the-project.html Sat Aug  8 
17:20:04 2015
@@ -233,13 +233,13 @@ public class Index
 
 
 
-<span class="gliffy-container" id="gliffy-container-24346949-5851" 
data-fullwidth="913" data-ceoid="24188263" 
data-edit="${diagramEditLink.getLinkUrl()}" 
data-full="${diagramZoomLink.getLinkUrl()}" data-filename="Templates and 
Parameters">
+<span class="gliffy-container" id="gliffy-container-24346949-9971" 
data-fullwidth="913" data-ceoid="24188263" 
data-edit="${diagramEditLink.getLinkUrl()}" 
data-full="${diagramZoomLink.getLinkUrl()}" data-filename="Templates and 
Parameters">
 
-    <map id="gliffy-map-24346949-5636" name="gliffy-map-24346949-5636"></map>
+    <map id="gliffy-map-24346949-3231" name="gliffy-map-24346949-3231"></map>
 
-    <img class="gliffy-image gliffy-image-border" 
id="gliffy-image-24346949-5851" width="304" height="300" data-full-width="913" 
data-full-height="901" 
src="https://cwiki.apache.org/confluence/download/attachments/24188263/Templates%20and%20Parameters.png?version=2&amp;modificationDate=1371888025000&amp;api=v2";
 alt="Templates and Parameters" usemap="#gliffy-map-24346949-5636">
+    <img class="gliffy-image gliffy-image-border" 
id="gliffy-image-24346949-9971" width="304" height="300" data-full-width="913" 
data-full-height="901" 
src="https://cwiki.apache.org/confluence/download/attachments/24188263/Templates%20and%20Parameters.png?version=2&amp;modificationDate=1371888025000&amp;api=v2";
 alt="Templates and Parameters" usemap="#gliffy-map-24346949-3231">
 
-    <map class="gliffy-dynamic" id="gliffy-dynamic-map-24346949-5851" 
name="gliffy-dynamic-map-24346949-5851"></map>
+    <map class="gliffy-dynamic" id="gliffy-dynamic-map-24346949-9971" 
name="gliffy-dynamic-map-24346949-9971"></map>
 </span>
 
 
@@ -254,7 +254,7 @@ public class Index
 </pre>
 </div></div><p>Make sure you save changes; then click the refresh link in the 
web browser:</p><p><span class="confluence-embedded-file-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image" 
width="700" 
src="exploring-the-project.data/app-live-reload.png"></span></p><div 
class="navmenu" style="float:right; width:30%; background:white; margin:3px; 
padding:3px">
 <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>If Live Class Reloading isn't working for you, check the Troubleshooting 
section at <a shape="rect" href="class-reloading.html" title="Class 
Reloading">Class Reloading</a>.</p></div></div></div>This is one of Tapestry's 
early <em>wow factor</em> features: changes to your component classes are 
picked up immediately (a feature we call Live Class Reloading). No restart. No 
re-deploy. Make the changes and see them <em>now</em>. Nothing should slow you 
down or get in the way of you getting your job done.<p>But ... what if you make 
a mistake? What if you got the name in the template wrong. Give it a try; in 
the template, change ${currentTime} to, say, ${currenTime}, and see what you 
get:</p><p><span class="confluence-embedded-file-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image" 
width="700" src="exploring-the-project.data/app-error-1.png"></span></p><p>This 
is Tapestry's exception report page. It's quite detailed. It clearly identifies 
what Tapestry was d
 oing, and relates the problem to a specific line in the template, which is 
shown in context. Tapestry always expands out the entire stack of exceptions, 
because it is so common for exceptions to be thrown, caught, and re-thrown 
inside other exceptions. In fact, if we scroll down just a little bit, we see 
more detail about this exception, plus a little bit of help:</p><p><span 
class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img 
class="confluence-embedded-image" width="700" 
src="exploring-the-project.data/app-error-2.png"></span></p><p>This is part of 
Tapestry's way: it not only spells out exactly what it was doing and what went 
wrong, but it even helps you find a solution; here it tells you the names of 
properties you could have used.</p><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-bod
 y"><p>This level of detail reflects that the application has been configured 
to run in <em>development mode</em> instead of <em>production mode</em>. In 
production mode, the exception report would simply be the top level exception 
message. However, most production applications go further and customize how 
Tapestry handles and reports exceptions.</p></div></div><p>Tapestry displays 
the stack trace of the deepest exception, along with lots of details about the 
run-time environment: details about the current request, the HttpSession (if 
one exists), and even a detailed list of all JVM system properties. Scroll down 
to see all this information.</p><p>Next: <a shape="rect" 
href="implementing-the-hi-lo-guessing-game.html">Implementing the Hi-Lo 
Guessing Game</a></p><hr><p></p></div>
+<p>If Live Class Reloading isn't working for you, check the Troubleshooting 
section at <a shape="rect" href="class-reloading.html" title="Class 
Reloading">Class Reloading</a>.</p></div></div></div>This is one of Tapestry's 
early <em>wow factor</em> features: changes to your component classes are 
picked up immediately (a feature we call Live Class Reloading). No restart. No 
re-deploy. Make the changes and see them <em>now</em>. Nothing should slow you 
down or get in the way of you getting your job done.<p>But ... what if you make 
a mistake? What if you got the name in the template wrong. Give it a try; in 
the template, change ${currentTime} to, say, ${currenTime}, and see what you 
get:</p><p><span class="confluence-embedded-file-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image" 
width="700" src="exploring-the-project.data/app-error-1.png"></span></p><p>This 
is Tapestry's exception report page. It's quite detailed. It clearly identifies 
what Tapestry was d
 oing, and relates the problem to a specific line in the template, which is 
shown in context. Tapestry always expands out the entire stack of exceptions, 
because it is so common for exceptions to be thrown, caught, and re-thrown 
inside other exceptions. In fact, if we scroll down just a little bit, we see 
more detail about this exception, plus a little bit of help:</p><p><span 
class="confluence-embedded-file-wrapper confluence-embedded-manual-size"><img 
class="confluence-embedded-image" width="700" 
src="exploring-the-project.data/app-error-2.png"></span></p><p>This is part of 
Tapestry's way: it not only spells out exactly what it was doing and what went 
wrong, but it even helps you find a solution; here it tells you the names of 
properties you could have used.</p><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-bod
 y"><p>This level of detail reflects that the application has been configured 
to run in <em>development mode</em> instead of <em>production mode</em>. In 
production mode, the exception report would simply be the top level exception 
message. However, most production applications go further and customize how 
Tapestry handles and reports exceptions.</p></div></div><p>Tapestry displays 
the stack trace of the deepest exception, along with lots of details about the 
run-time environment: details about the current request, the HttpSession (if 
one exists), and even a detailed list of all JVM system properties. Scroll down 
to see all this information.</p><p>Next: <a shape="rect" 
href="implementing-the-hi-lo-guessing-game.html">Implementing the Hi-Lo 
Guessing Game</a></p><p>&#160;</p><p></p></div>
 </div>
 
 <div class="clearer"></div>


Reply via email to