<document>
  <header>
    <title>Scheduled Task</title>
    <type>contents</type>
    <description>
    <p>Resin's &lt;scheduled-task> capability lets you schedule
      events using a flexible cron-style trigger.  The task can be
      any <code>Runnable</code> bean, a method specified by EL, or
      a URL.</p>
    </description>
  </header>

  <body>

<localtoc/>

<s1 title="&lt;scheduled-task>"> version="Resin 3.1.6">

<p>&lt;scheduled-task> schedules a job to be executed at specific times
or after specific delays.  The times can be specified by a cron syntax or
by a simple delay parameter.  The job can be either a <code>Runnable</code>
bean, a method specified by an EL expression, or a URL.</p>

<p>When specified as an IoC bean, the bean task has full IoC capabilities,
including injection, @TransactionAttribute aspects, interception and
@Observes.</p>

<deftable title="&lt;scheduled-task> Attributes">
<tr>
  <th>Attribute</th>
  <th>Description</th>
</tr>
<tr>
  <td>class</td>
  <td>the classname of the singleton bean to create</td>
</tr>
<tr>
  <td>cron</td>
  <td>a cron-style scheduling description</td>
</tr>
<tr>
  <td>delay</td>
  <td>a simple delay-based execution</td>
</tr>
<tr>
  <td>init</td>
  <td>IoC initialization for the bean</td>
</tr>
<tr>
  <td>mbean-name</td>
  <td>optional MBean name for JMX registration</td>
</tr>
<tr>
  <td>method</td>
  <td>EL expression for a method to be invoked as the task</td>
</tr>
<tr>
  <td>name</td>
  <td>optional IoC name for registering the task</td>
</tr>
<tr>
  <td>period</td>
  <td>how often the task should be invoked in simple mode</td>
</tr>
<tr>
  <td>task</td>
  <td>alternate task assignment for predefined beans</td>
</tr>
</deftable>

<def title="&lt;scheduled-task> schema">
element scheduled-task {
  class?
  &amp; cron?
  &amp; delay?
  &amp; init?
  &amp; mbean-name?
  &amp; method?
  &amp; name?
  &amp; period?
  &amp; task?
}
</def>

<s2 title="bean-style job configuration">

<p>The most common and flexible job configuration uses standard IoC
bean-style configuration.  The bean must implement <code>Runnable</code>.
Like the &lt;bean> tag, the <var>class</var> attribute specifies the
<code>Runnable</code> class, and any <var>init</var> section configures
the bean using <a href="resin-ioc.xtp">Resin IoC</a> configuration.</p>

<example title="Example: 5min cron bean task">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;scheduled-task class="qa.MyTask">
    &lt;cron>*/5&lt;/cron>
  &lt;/scheduled-task>

&lt;/web-app>
</example>

</s2>

<s2 title="task reference job configuration">

<p>The task bean can also be passed to the &lt;scheduled-task> using
a Resin-IoC EL reference.  The name of the task bean would be defined
previously, either in a &lt;bean> or &lt;component> or picked up by classpath
scanning.  Like the bean-style job configuration, the reference bean must
implement <code>Runnable</code>.</p>

<example title="Example: midnight cron bean task">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;scheduled-task task="#{taskBean}">
    &lt;cron>0 0 *&lt;/cron>
  &lt;/scheduled-task>

&lt;/web-app>
</example>

</s2>

<s2 title="method reference job configuration">

<p>&lt;scheduled-task> can execute a method on a defined bean as the
scheduler's task.  The method is specified using EL reference syntax.
At each trigger time, &lt;scheduled-task> will invoke the EL method
expression.</p>

<p>In the following example, the task invokes <code>myMethod()</code>
on the <var>myBean</var> singleton every 1 hour.</p>

<example title="Example: 1h period method task">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;bean name="myBean" class="qa.MyBean"/>

  &lt;scheduled-task method="#{myBean.myMethod}">
    &lt;delay>10m&lt;/delay>
    &lt;period>1h&lt;/period>
  &lt;/scheduled-task>

&lt;/web-app>
</example>

</s2>

<s2 title="url job configuration">

<p>In a &lt;web-app>, the &lt;scheduled-task> can invoke a servlet URL
at the trigger times.  The task uses the servlet <code>RequestDispatcher</code>
and forwards to the specified URL.  The URL is relative to the &lt;web-app>
which contains the &lt;scheduled-task.</p>

<example title="Example: sunday cron url task">
&lt;web-app xmlns="http://caucho.com/ns/resin">

  &lt;scheduled-task url="/cron.php">
    &lt;cron>0 15 * * 0&lt;/cron>
  &lt;/scheduled-task>

&lt;/web-app>
</example>

</s2>

<s2 title="cron trigger syntax">

<p>Some ascii art from the <a href="http://en.wikipedia.org/wiki/Crontab">wikipedia
cron entry</a></p>

<def title="cron fields">
# +---------------- minute (0 - 59)
# |  +------------- hour (0 - 23)
# |  |  +---------- day of month (1 - 31)
# |  |  |  +------- month (1 - 12)
# |  |  |  |  +---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
  *  *  *  *  *
</def>

<deftable title="cron patterns">
<tr>
  <th>Pattern</th>
  <th>Description</th>
</tr>
<tr>
  <td>*</td>
  <td>matches all time periods</td>
</tr>
<tr>
  <td>15</td>
  <td>matches the specific time, e.g. 15 for minutes</td>
</tr>
<tr>
  <td>15,45</td>
  <td>matches a list of times, e.g. every :15 and :45</td>
</tr>
<tr>
  <td>*/5</td>
  <td>matches every <var>n</var> times, e.g. every 5 minutes</td>
</tr>
<tr>
  <td>1-5</td>
  <td>matches a range of times, e.g. mon, tue, wed, thu, fri (1-5)</td>
</tr>
</deftable>

<p>Each field specifies a range of times to be executed.  The patterns
allowed are:</p>

<deftable title="example ranges">
<tr>
  <th>range</th>
  <th>explanation (using minutes as example)</th>
</tr>
<tr>
  <td>*</td>
  <td>run every minute</td>
</tr>
<tr>
  <td>*/5</td>
  <td>run every 5 minutes</td>
</tr>
<tr>
  <td>0,5,50</td>
  <td>run at :00, :05, :50 every hour</td>
</tr>
  <tr><td>0-4</td>
  <td>run at :00, :01, :02, :03, :04</td>
</tr>
<tr>
  <td>0-30/2</td>
  <td>run every 2 minutes for the first half hour</td>
</tr>
</deftable>

<p>The minutes field is always required, and the hours, days, and
months fields are optional.</p>

<deftable title="example times">
<tr>
  <th>range</th>
  <th>explanation</th>
</tr>
<tr>
  <td>0 */3</td>
  <td>run every 3 hours</td>
</tr>
<tr>
  <td>15 2 *</td>
  <td>run every day at 0215 local time</td>
</tr>
<tr>
  <td>0 0 */3</td>
  <td>run every third day at midnight</td>
</tr>
<tr>
  <td>15 0 * * 6</td>
  <td>run every Saturday at 0015</td>
</tr>
</deftable>

</s2>

<s2 title="com.caucho.resources.CronResource">
<p>Often, applications need to run a task at specific times.  The
<code>CronResource</code> provides a standard way of doing that.
Applications need only create a standard
<code>java.lang.Runnable</code> task and configure the CronResource.
Resin configure's the work task with 
<a href="ioc-bean-patterns.xtp">bean-style configuration</a>.
</p>

<example title="Task running every 15 minutes">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;resource type="com.caucho.resources.CronResource"&gt;
    &lt;init&gt;
      &lt;cron&gt;*/15&lt;/cron&gt;
      &lt;work resin:type="example.PeriodicWork"&gt;
        &lt;foo&gt;Custom Config&lt;/foo&gt;
      &lt;/work&gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<deftable-parameters>
<tr><td>cron</td><td>Specifies the times the task should be run</td><td>required
</td></tr><tr><td>work</td><td>Specifies application's work bean</td><td>required
</td></tr></deftable-parameters>

<p>The cron specification follows the Unix crontab format.  The cron
is composed of 5 fields: minutes, hours, day of month, month, and day
of week.</p>

<p>Each field specifies a range of times to be executed.  The patterns
allowed are:</p>

<deftable title="example ranges">
<tr><th>range</th><th>explanation (using minutes as example)
</th></tr><tr><td>*</td><td>run every minute
</td></tr><tr><td>*/5</td><td>run every 5 minutes
</td></tr><tr><td>0,5,50</td><td>run at :00, :05, :50 every hour
</td></tr><tr><td>0-4</td><td>run at :00, :01, :02, :03, :04
</td></tr><tr><td>0-30/2</td><td>run every 2 minutes for the first half hour
</td></tr></deftable>

<p>The minutes field is always required, and the hours, days, and
months fields are optional.</p>

<deftable title="example times">
<tr><th>range</th><th>explanation
</th></tr><tr><td>0 */3</td><td>run every 3 hours
</td></tr><tr><td>15 2 *</td><td>run every day at 0215 local time
</td></tr><tr><td>0 0 */3</td><td>run every third day at midnight
</td></tr><tr><td>15 0 * * 6</td><td>run every Saturday at 0015
</td></tr></deftable>
</s2>

<s2 title="Hello, World example">

<example title="Example: WEB-INF/web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;

  &lt;scheduled-task class="example.PeriodicWork"&gt;
    &lt;!-- every 5 minutes --&gt;
    &lt;cron&gt;*/5&lt;/cron&gt;
  &lt;/resource&gt;

&lt;/web-app&gt;
</example>

<example title="Example: WEB-INF/classes/example/PeriodicWork.java">

package example;

import java.util.logging.Level;
import java.util.logging.Logger;

public class PeriodicWork implements Runnable {
  static protected final Logger log = 
    Logger.getLogger(PeriodicWork.class.getName());

  public PeriodicWork()
  {
    log.info("PeriodicWork: constructor");
  }

  /**
   * Required implementation of java.lang.Runnable.run()
   */
  public void run()
  {
    log.info("PeriodicWork: run() Hello, World");
  }
}
</example>

<results>
[13:04:27.429] PeriodicWork: constructor
[13:05:00.095] PeriodicWork: run() Hello, World
[13:10:00.182] PeriodicWork: run() Hello, World
</results>
</s2>

<s2 title="Example: bean-style configuration example">

<example title="WEB-INF/web.xml">
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;

  &lt;scheduled-task class="example.PeriodicWork"&gt;
    &lt;!-- every minute --&gt;
    &lt;cron&gt;*&lt;/cron&gt;

    &lt;init&gt;
      &lt;message&gt;Goodybye, World&lt;/message&gt;
    &lt;/init&gt;
  &lt;/scheduled-task&gt;

&lt;/web-app&gt;
</example>

<example title="Example: WEB-INF/classes/example/PeriodicWork.java">
package example;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.resource.spi.work.Work;

public class PeriodicWork implements Work {
  static protected final Logger log = 
    Logger.getLogger(PeriodicWork.class.getName());

  String _message;

  public PeriodicWork()
  {
    log.info("PeriodicWork: constructor");
  }

  /**
   * Optional, called in response to presence of &lt;message&gt;
   * configuration tag. 
   */
  public void setMessage(String message)
  {
    log.info("PeriodicWork: setMessage");
    _message = message;
  }

  /**
   * Optional, called after bean is created and any setters
   * from configuration are called.
   */
  @PostConstruct
  public void init()
    throws Exception
  {
    log.info("PeriodicWork: init()");

    if (_message == null)
      throw new Exception("`message' is required");
  }

  /**
   * Required implementation of java.lang.Runnable.run()
   */
  public void run()
  {
    log.info("PeriodicWork: run() " + _message);
  }

  /**
   * Implementation of javax.resource.spi.work.Work.release()
   */
  public void release()
  {
    log.info("PeriodicWork: release()");
  }
}
</example>

<results>
[13:04:27.429] PeriodicWork: constructor
[13:04:27.429] PeriodicWork: setMessage
[13:04:27.429] PeriodicWork: init()
[13:05:00.095] PeriodicWork: run() Goodbye, World
[13:06:00.182] PeriodicWork: run() Goodbye, World
(close Resin)
[13:06:00.345] PeriodicWork: release()
</results>
</s2>
</s1> <!-- scheduled-task -->

<s1 name="concepts" title="RMI Resource">

<p>
The goal of RMI is to provide <var>services</var> to remote clients.  A remote
client obtains and uses a <var>proxy object</var> that implements an
<var>interface</var>.  The interface is the contract for the service, it is the
definition of the methods that the service provides.
</p>

<p>
Because the client is using a proxy object, the actual execution of code
occurs on the server.  A proxy object is placeholder that the client uses
to cause execution of code on a server.
</p>

<s2 name="concepts/registry" title="Registry">

<p>
The RMI registry is used to store a list of available services.  A client uses
the registry to make it's proxy object, and the Registry is responsible for
giving appropriate information to the client so that it can hook up with the
server that implements the service.  
</p>

<p>
In many scenarios, the Registry and the server for the services are in the same
JVM.  It is possible, however, for the Registry to run in a different
JVM or even on a different machine than the server or servers that implement
the services. 
</p>

<p>
A registry has a TCP port that it uses to listen to incoming requests,
typically this is port 1099.  The RMI registry is a global resource, each JVM
can have only one Registry on a particular port.  This has important
ramifications for the naming of services.
</p>

</s2> <!-- concepts/registry -->

<s2 title="The Hessian alternative">

<p>If you are considering RMI as a mechanism for publishing services, you may
want to consider using <a href="hessian.xtp">Hessian</a> instead.  Hessian offers the following
advantages:</p>

<ul>
<li>it does not have a global namespace, separate web-app's can provide
services with the same name without conflict
</li><li>it supports the use of clients written in languages other than Java
</li><li>it does not require the manual generation of stubs
</li><li>it does not require a security-manager
</li></ul>

<p>
More information is available in the 
<a href="hessian.xtp">Hessian</a> section of the documentation.
</p>

</s2>

<s2 name="security-manager" title="Requirement: security-manager">

<p>
The JDK requires that a security manager be in place for the use of RMI.
This is true for both clients and servers.
A security manager is enabled in Resin using the <a config-tag="security-manager"/> configuration:
</p>

<example title="enabling security-manager in resin.xml">
&lt;resin xmlns="http://caucho.com/ns/resin"
       xmlns:resin="http://caucho.com/ns/resin/core"&gt;

  &lt;security-manager/&gt;

  ...
</example>

<p>
For clients that are applets, the developer does not need to enable the
security manager; the browser provides the security manager.
</p>

<p>
More information is available in the 
<a href="securitymanager.xtp">Security</a>
section of the documentation.
</p>

</s2>

<s2 name="ref" title="com.caucho.resources.rmi.RmiRegistry">
<p>
Resin provides the resource class 
<a href="javadoc|com.caucho.resources.rmi.RmiRegistry|"/>
to define an RMI Registry and register services with it.
If the Registry is on the `localhost' server, then Resin will also start the
RMI Registry if needed.
</p>

<example title="Example use of RMI Registry">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;localhost&lt;/server&gt;  <!-- optional, default is `localhost' -->
      &lt;port&gt;1099&lt;/port&gt;           <!-- optional, default is `1099' -->

      &lt;rmi-service service-name="HelloWorld" 
                      service-class="example.HelloWorldImpl"/&gt;
      &lt;rmi-service .... &gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>


<s3 title="com.caucho.resources.rmi.RmiRegistry" version="Resin 3.0.6" type="defun">

<deftable-childtags>
<tr><td occur="?">server</td><td>the ip address of the server with the Registry</td><td>localhost
</td></tr><tr><td occur="?">port</td><td>the port of the Registry</td><td>1099
</td></tr><tr><td occur="*">rmi-service</td><td>an rmi service (see below)</td><td>&#160;
</td></tr></deftable-childtags>

<p>
<code>RmiRegistry</code> is used to define the location of an RMI Registry to
use.  If <code>server</code> is `localhost', then the Registry will be started
on the specified port, if it has not already been started.
</p>

<p>
If <code>server</code> is something other than `localhost', then it is assumed
that the Registry has been started by some other JVM , and is treated as remote Registry to register any services defined with <code>rmi-server</code>.
</p>
</s3>
 

<s3 title="rmi-service" version="Resin 3.0.6" type="defun">
<parents>com.caucho.resources.rmi.RmiRegistry</parents>

<p>
Each <code>RmiRegistry</code> can have <code>rmi-service</code> children, which
causes the service to be instantiated and registered with the RMI Registry
defined by the containing <code>RmiRegistry</code>.  
</p>

<deftable-childtags>
<tr><td occur="1">service-name</td><td>the name of the service, used for registration in the Registry and also used by clients to locate the service.</td><td>required
</td></tr><tr><td occur="1">server-class</td><td>the name of the implementation class for the service</td><td>required
</td></tr></deftable-childtags>
</s3>
</s2> <!-- ref -->

<s2 name="implement" title="Implementing a service">

<s3 title="Interface and Implementaion">

<p>An RMI service requires the developer to create two classes - an interface
and an implementation.  The interface defines the contract for the service, it
is given to the client and it is the client view of the service.  The
implementation class implements the functionality; it implements
the interface and is used on on the server.</p>

<p>The following is a simple hello world example.</p>

<example title="interface - WEB-INF/classes/example/HelloWorld.java">
package example;

import java.rmi.Remote;
import java.rmi.RemoteException;


public interface HelloWorld extends Remote
{
  public String sayHello()
    throws RemoteException;
}
</example>

<example title="implementation - WEB-INF/classes/example/HelloWorldImpl.java">
package example;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;


public class HelloWorldImpl extends UnicastRemoteObject implements HelloWorld
{
  public HelloWorldImpl()
    throws RemoteException
  {
    super();
  }

  public String sayHello()
    throws RemoteException
  {
    return "Hello, World";
  }
}
</example>

</s3>

<s3 title="Making Stubs">

<p>When the client uses a service, it uses a <var>proxy object</var>.  The proxy
object is a placeholder, it implements the interface defined for the service,
and call's through to the server so that the code is executed on the
server.</p>

<p>RMI calls proxy objects <code>Stubs</code>, and the stubs must be manually
generated.  The generation of stubs is done using the <code>rmic</code>
tool.</p>

<example title="using rmic to generate Stubs">
rmic -v1.2 -d WEB-INF/classes/  example.HelloWorldImpl 
</example>

<p>
This call to <code>rmic</code> will use the file
<code>WEB-INF/classes/example/HelloWorldImpl.class</code> to generate the class
file <code>WEB-INF/classes/example/HelloWorldImpl_Stub.class</code>.
</p>

<p>
It is tedious to perform this step manually, an ant build script (as shown
in a later section) can be used to expediate the process.
</p>

</s3>

<s3 name="implement/deploy" title="Deploying the service with Resin">
<p>
Once the work of making an interface, an implementation, and generating a stub
is complete, it is a simple process to deploy the service in Resin.  
</p>

<example title="Deploying the service with Resin">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;localhost&lt;/server&gt;  <!-- optional, default is `localhost' -->
      &lt;port&gt;1099&lt;/port&gt;           <!-- optional, default is `1099' -->

      &lt;rmi-service service-name="HelloWorld" service-class="example.HelloWorldImpl"/&gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<p>
More than once service is easily deployed
with the use of multiple <code>rmi-service</code> tags:
</p>

<example title="Deploying more than once service with Resin">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;localhost&lt;/server&gt;  <!-- optional, default is `localhost' -->
      &lt;port&gt;1099&lt;/port&gt;           <!-- optional, default is `1099' -->

      &lt;rmi-service service-name="HelloWorld" service-class="example.HelloWorldImpl"/&gt;
      &lt;rmi-service service-name="HelloAgainWorld" service-class="example.HelloAgainWorldImpl"/&gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<s4 title="Choosing a name">

<p>By convention, the name chosen for the service often matches the name of the
interface class.  For example, if the interface name is "example.HelloWorld"
then service-name is "HelloWorld" or even "example.HelloWorld" to match.
</p>

<p>The RMI Registry has a global namespace.  If two different web-app's try to
publish the same service, with the same name, there will be conflicts.</p>

</s4>
</s3>  <!-- implement/deploy -->

<s3 title="An example build file">
<p>
An ant build file is useful for completing the <code>rmic</code> step, and for
preparing a jar for use by the client.  The client jar contains the interfaces
and the stubs.
</p>

<p>
The following build file, placed in <code>/WEB-INF/build</code>, creates
the jar file <code>/rmiclient.jar</code>.
</p>

<example title="WEB-INF/build.xml">
&lt;project name="rmiexample" default="dist" basedir="."&gt;

&lt;property file="local.properties"/&gt;
&lt;property file="build.properties"/&gt;
&lt;property environment="env"/&gt; 

&lt;property name="build.compiler.emacs" value="true"/&gt; 
&lt;property name="resin.home" value="${'${'}env.RESIN_HOME}"/&gt; 

&lt;property name="rmiclient.jar" value="../rmiclient.jar"/&gt;

&lt;!-- NOTE: new RMI interfaces must have corresponding entries addeed
   -       in the rmiclient.jar taget
   --&gt;

&lt;path id="compile.classpath"&gt;
  &lt;fileset dir="${'${'}resin.home}/lib"&gt;
    &lt;include name="**/*.jar" /&gt;
  &lt;/fileset&gt;
&lt;/path&gt;

&lt;target name="init"&gt;
  &lt;tstamp/&gt;
&lt;/target&gt;

&lt;target name="compile" depends="init"&gt;
  &lt;mkdir dir="classes"/&gt;
  &lt;javac classpathref="compile.classpath"
         destdir="classes"
         debug="true"&gt;
    &lt;src path="classes"/&gt;
  &lt;/javac&gt;
&lt;/target&gt;

&lt;target name="rmic" depends="init,compile"&gt;
  &lt;rmic base="classes"
        classpathref="compile.classpath"
        includes="**/*Impl.class"/&gt;
&lt;/target&gt;


&lt;target name="rmiclient.jar" depends="init,rmic"&gt;
  &lt;jar destfile="${'${'}rmiclient.jar}"&gt;
    &lt;fileset dir="classes"&gt;
      &lt;patternset&gt;
        &lt;include name="**/HelloWorld.class"/&gt;
        &lt;include name="**/*_Stub.class"/&gt;
      &lt;/patternset&gt;
    &lt;/fileset&gt;
  &lt;/jar&gt;
&lt;/target&gt;

&lt;target name="dist" depends="rmiclient.jar"/&gt;

&lt;/project&gt;
</example>

</s3>

</s2>

<s2 name="client" title="Implementing a client">
<p>
The client is usually on a different machine, or at least in a different JVM, than the server.  That is the point of RMI, it enables the execution of code on a remote machine.
</p>

<p>
In order to use the RMI service, the client needs the interface classes and the
Stubs.  The easiest way to provide these to the client is to provide a jar; the
ant build file above provides an example of using ant to automate the creation
of the jar file for the client.  
</p>

<p>
Once the jar file is available to the client, using the RMI service id fairly simple.
</p>

<example title="An RMI client">
  String server = "//server-with-registry.com:1099/";
  HelloWorld remote = (HelloWorld) Naming.lookup(server + "HelloWorld");

  System.out.println(remote.sayHello());
</example>

</s2> <!-- client -->

<s2 name="scenarios" title="Scenarios">

<s3 title="A Resin server that provides the Registry and the service">

<p>In the most common scenario, the Resin server provides both the RMI Registry
and the RMI services.  When the registry server is defined as `localhost',
Resin will start the rmi registry if has not been started already.</p>

<p>This provides a simple method of using RMI, you don't have to worry about
the (somewhat tricky) process of starting the rmi registry yourself.</p>

<example title="Scenario: a Resin server that provides the Registry and the service">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;localhost&lt;/server&gt;
      &lt;port&gt;1099&lt;/port&gt;

      &lt;rmi-service service-name="HelloWorld" service-class="example.HelloWorldImpl"/&gt;
      &lt;rmi-service .... &gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<p>
When the Resin server starts, it will start the rmi registry on port 1099 and register the `HelloWorld' service with it.
</p>
</s3>

<s3 title="A Registry on a different server">

<p>In this scenario, the rmi registry is located on the machine
<code>services.hogwarts.com</code>.  The registry is started with a custom (not
Resin) server implemented by Hogwarts.</p>

<p>The requirement is for the HelloWorld service, implemented within a Resin
server, to be registered with the remote Registry.</p>

<p>In this scenario, the Resin resource RmiRegistry is used to attach to the
existing RMI registry running on <code>services.hogwarts.com</code>.  </p>

<example title="A Registry on a different server">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;services.hogwarts.com&lt;/server&gt;
      &lt;port&gt;1099&lt;/port&gt;

      &lt;rmi-service service-name="HelloWorld" service-class="example.HelloWorldImpl"/&gt;
      &lt;rmi-service .... &gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<p>
When the Resin server starts, it will register the `HelloWorld' service with
the RMI Registry on <code>services.hogwarts.com</code>.  Since the server is on
a remote machine, Resin will not create a registry on the local machine.  When
the REsin server shuts down, or is restarted, the `HelloWorld' service will be
removed from the remote registry.
</p>
</s3>

<s3 title="A Registry in a different JVM">

<p>In this scenario, the rmi registry is located on the same machine
as the Resin server, but is started  with a custom (not
Resin) server implemented by Hogwarts.</p>

<p>This is essentially the same scenario as having a Registry on a different
szerver.  The server name cannot be provided as `localhost', however, because
Resin will try to create the RMI registry.</p>

<p>The solution is to use an IP address of `127.0.0.1' as the address of the
server.  Because the server name is not `localhost', the RMI registry will not
be created.</p>

<example title="A Registry in a different JVM">
&lt;web-app&gt;
  &lt;resource type="com.caucho.resources.rmi.RmiRegistry"&gt;
    &lt;init&gt;
      &lt;server&gt;127.0.0.1&lt;/server&gt;
      &lt;port&gt;1099&lt;/port&gt;

      &lt;rmi-service service-name="HelloWorld" service-class="example.HelloWorldImpl"/&gt;
      &lt;rmi-service .... &gt;
    &lt;/init&gt;
  &lt;/resource&gt;
&lt;/web-app&gt;
</example>

<p>
When the Resin server starts, it will register the `HelloWorld' service with
the RMI Registry on the local machine.  Since the server is not `localhost',
Resin will not create a registry on the local machine.  When
the Resin server shuts down, or is restarted, the `HelloWorld' service will be
removed from the remote registry.
</p>

</s3>

</s2> <!-- scenarios -->
</s1>

  </body>
</document>