vinayc      2003/08/28 11:47:24

  Added:       xdocs    client-usage.xml credits.xml facades.xml faq.fml
                        generating-proxies.xml index.xml monitors.xml
                        navigation.xml otherfeatures.xml pingers.xml
                        publishing.xml site.xml transports.xml
  Log:
  Refactorize (includes modularize,mavenize & rest of the nice's)
  
  Revision  Changes    Path
  1.1                  incubator-altrmi/xdocs/client-usage.xml
  
  Index: client-usage.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
   <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Client Usage</title>
      </properties>
    <body>
      <section name="Introduction">
        <p>
          On the client you can choose to use JNDI or AltRMI's own clases to 
lookup a 
          remote interface.
        </p>
      </section>          
      <section name="JNDI">
        <p>    
          If you are using Ant for builds, then you can use the 'altrmiproxies' 
taskdef 
          to make proxies in advance of use.
        </p>              
  <source>
  <![CDATA[
  Hashtable env = new Hashtable();
  env.put(
      Context.INITIAL_CONTEXT_FACTORY,
      "org.apache.altrmi.client.impl.naming.DefaultInitialContextFactory");
  env.put(Context.PROVIDER_URL, "altrmi://somehost:1235/SocketCustomStream");
  Context ctx = new InitialContext(env);
  TestInterface ti = (TestInterface) ctx.lookup("Hello");
  ]]>
  </source>
      </section>
      <section name="Custom AltRMI lookup">
        <p>    
          Directly using AltRMI classes, you can lookup the same interface.
        </p>              
  <source>
  <![CDATA[
  Factory factory = new ClientSideClassFactory(false);
  factory.setHostContext(new SocketCustomStreamHostContext("somehost", 1235));
  TestInterface ti = (TestInterface) af.lookup("Hello");
  ]]>
  </source>
  
      </section>       
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/credits.xml
  
  Index: credits.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
   <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Credits</title>
      </properties>  
  <body>
      <section name="Coders who've worked on AltRMI">
        <p>
          A broad group of people have contributed at various stages. Here 
listed in alphabetical order:
        </p>
        <ol>
          <li>Benjamin David Hall (patch)</li>
          <li>Berin Loritsch</li>
          <li>Mauro Talevi (pairing)</li>
          <li>Mike Miller (patch submission)</li>
          <li>Paul Hammant</li>
          <li>Peter Royal</li>
          <li>Thomas Kiesgen (patch submission)</li>
          <li>Vinay Chandrasekharan</li>
        </ol>
      </section>       
      <section name="Forked code from other Apache projects">
        <p>
          We've borrowed code from elsewhere at Apache. Thus there are 
accidental authors:
        </p>
        <ol>
          <li>Anil K. Vijendran - JavaCompiler</li>
          <li>Costin Manolache - JavaCompiler</li>
          <li>Peter Donald - Dynamic Proxy</li>
          <li>Sam Ruby - JavaCompiler</li>
        </ol>
      </section>       
  
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/facades.xml
  
  Index: facades.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
     <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Facade Design</title>
      </properties>
    <body>
      <section name="Introduction">
        <p>
          AltRMI publishes an object via its interface.  It does not replicate 
the object
          on the client side, it generates proxies for it defined as facades.
        </p>
      </section>          
      <section name="Facades">
        <p>    
          Consider a system that models weather stations (fixed and mobile) and
          the meterologists that staff the stations.....
        </p>
        <image src="images/facades.gif" alt="Picture of Facades"/>      
        <p>
          The interfaces and the class on the right of the green line are 
'interface'
          or API, and we want them to exist as is on the client side for 
general use.  Things on the
          left are the implementation classes and they exist on the server side 
only.  Though not
          shown here, it would be easiest to have them in a separate package.  
Representing those
          objects on the client side are generated proxies.  Proxies are 
pass-by-reference
          boundaries but are castable to any of the interfaces they represent.  
There is one
          pass-by-value object and that is Coordinate.  It should be 
serializable and final
          (Immutable pattern).
        </p>
        <p>
          The principle point of entry into the system from the client point of 
view is
          'WeatherSystem'.  The mechanism of entry is a lookup on an agreed 
name. We recommend
          'WeatherSystem' or 'WeatherSystem_1.0' etc.
        </p>
        <p>
          Once the client has a handle on the WeatherSystem normal Java 
tarversals are possible
        </p>        
  <source>
  WeatherSystem ws = getWeatherSystem(); // some thing that does the JNDI 
lookup.
  // yes we know the following could throw NPEs or Array Index issues.
  String aName = 
ws.getWeatherStation("ArcticOne").getMeteorologists()[0].getName();
  </source>
        <p>
         To generate the correct proxies for the above, you would want to have 
the interface as
         'WeatherSystem' and additional-facades of 'Meteorologist' and 
'WeatherStation'
        </p>
      </section>
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/faq.fml
  
  Index: faq.fml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  
  
  <faqs title="Frequently Asked Questions">
  
    <part id="build">
      <title>Building AltRMI</title>
      <faq id="howto">
        <question>
          HowTo build AltRMI?
        </question>
        <answer>
          <p>
            AltRMI project comes with both <link href="ext:ant">Ant</link> as 
well as <link href="ext:maven">Apache Maven</link> to
            build the source+documentation.
          </p>
        </answer>
      </faq>
  
    </part>
  
  </faqs>
  
  
  
  1.1                  incubator-altrmi/xdocs/generating-proxies.xml
  
  Index: generating-proxies.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
   <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Generating Proxies</title>
      </properties>
  <body>
      <section name="Introduction">
        <p>
          You can choose to generate your proxies in advance of use, or to 
defer generation
          until runtime.  As the generation requires javac in tools.jar (multi 
megabyte), you 
          have to decide whether your runtime environment or distribution can 
support or 
          legally distribute it.
        </p>
      </section>          
      <section name="Generation in advance">
        <p>    
          If you are using Ant for builds, then you can use the 'altrmiproxies' 
taskdef to make 
          proxies in advance of use.
        </p>        
  <source>
  <![CDATA[
  <altrmiproxies genname="Hello" srcgendir="${build.home}/genjava" 
      classgendir="${build.home}/classesection" verbose="true"
      interfaces="org.apache.altrmi.test.TestInterface"
      additionalfacades="org.apache.altrmi.test.TestInterface2">
    <classpath>
      <pathelement location="${build.home}/classes"/>
    </classpath>
  </altrmiproxies>   
  ]]>
  </source>
        <p>
         All you have to do after that is place them in a jar for later use.  
That jar could be 
         client or server-side, thus classes can be retrieved from the server 
for use on the client 
         or preexist in clients environment.
        </p>      
      </section>
      <section name="Generation at runtime">
        <p>    
          If you are using Ant for builds, then you can use the 'altrmiproxies' 
taskdef to make 
          proxies in advance of use.
        </p>        
  <source>
  <![CDATA[
  DynamicGeneratorClassRetriever dgcr = new 
DynamicGeneratorClassRetriever(mGenJarURL);
  
  PublicationDescription pd = new PublicationDescription(TestInterface.class, 
new Class[] { TestInterface2 });
  dgcr.generate("Hello", pd, this.getClass().getClassLoader());
  ]]>
  </source>
        <p>
         This by implication means server-side classes, so the above is code in 
the server. It also 
         has a performance hit at time of first retrieval.
        </p>      
      </section>       
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
     <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Overview</title>
      </properties>
    <body>
      <section name="Introduction">
        <p>
          AltRMI is a from-scratch replacement for RMI.  It has a number of 
different features 
          that make it easier to use.  It tries as far as possible to be 
transparent in use.  It 
          is also inspired by the remoting facility in .NET.  This does not 
mean that it has SOAP 
          capabilty (yet), as it is more like the proprietary RPC transport for 
the .NET framework.
        </p>
        <p>
          The name AltRMI is inspired by the 'alt' usenet newsgroup hierarchy.  
We have thought about 
          renaming it especially as alt means old in German.  DRMI (Distributed 
RMI), PMI (Proxied 
          Method Invocation), ARC (Apache Remote Control) and JRemoting were 
all considered as 
          replacements, but for now we stick with AltRMI.
        </p>
        <p>
          The mail list for this project is 'projects at incubator.apache.org'. 
Subscribe 
          <link href="mailto:[EMAIL PROTECTED]">here</link>. Please mark your 
          emails with a subject of [altrmi] + your normal subject choice.
        </p>
        
      </section>          
      <section name="Feature Differences">
        <p>    
          Some good, some bad:
        </p>        
        <ul>
          <li>It transports normal Java interfaces (no need to extend 
java.rmi.Remote)</li>
          <li>None of the remote capable methods have to throw 
java.rmi.RemoteException.</li>
          <li>Compared to RMI in use for EJB, it does not transport over CORBA 
(yet).</li>
        </ul>     
      </section>
      <section name="Connection Robustness">
        <p>
          Given that there are  <link 
href="http://java.sun.com/people/jag/Fallacies.html";>eight 
          fallacies of distributed computing</link>, we feel it important to 
show that AltRMI 
          is not ignoring these issues.<br/>    
          The principal benefit for a developer making beans or an application 
server is 
          that RemoteException is missing.  That does not mean that 
communications failure 
          is ignored.  AltRMI still illustrates communication failure via 
          InvocationException which a subclass of RuntimeException.  This 
basically 
          allows the exception to be thrown, but not specified on each method 
(like 
          RemoteException does).  Many feel that allowing the bean developer to 
          ignore the robustness issues is a mistake.  We think not given the 
following.
        </p>      
        <ol>
          <li>The container could be programmed to know about 
InvocationException.</li>
          <li>AltRMI has configurable policies that can help re-establish 
connection whilst in use.</li>
          <li>Standard handling of RemoteException sucks.</li>
          <li>It is difficult in EJB, in terms of coverage, to test your huge 
amounts of 
          RemoteException handling code.</li>
          <li>Most web-app uses of beans have a single "handler" place where 
pertinent 
          exceptions are already caught.</li>
        </ol>
        <subsection name="1. The container could be programmed to know about 
InvocationException">
          <p>
            A lot of beans coding is 'bean invokes method in bean which invokes 
method in bean'.  In 
            this case there are several places in the invocation stack where 
the container's logic 
            is delegating between beans.  Container could easily handle failing 
connections and take 
            multiple actions: re-establish report, redirect, abend services or 
server.  If there is 
            a configurable policy for such events that may include the invoking 
of methods in, 
            say, 'contingency' beans.
          </p>
        </subsection>
        <subsection name="2. AltRMI has configurable policies that can help 
reestablish connection whilst in use.">
          <p>
            AltRMI has a pluggable architecture for re-establishing connections 
(and reporting timings 
            etc).  Whilst in the middle of an invocation, if the connection is 
lost, AltRMI can try to 
            re-establish the connection and complete the method invocation 
normally.  A delay would of 
            course be encountered, but if administrators are watching the logs, 
then they can determine 
            where failures are happening and what to do long term about it.  
Programmed policies 
            (configured in the container) could be "try perpetually to 
reconnect", "try five times only, 
            one a second", "fail immediately".
          </p>
        </subsection>
        <subsection name="3. Standard handling of RemoteException sucks.">
          <p>
           Referring to the various ways EJB teams handle RemoteException, in 
the thousands of places 
           in a typical J2EE solution where it is thrown, different solutions 
are...<br/>
          </p>         
            <subsection name="3.1. Declare throws RemoteException on every 
applicable method">
              <p>
              That means that it can often arrive back at the container.  The 
container always reports 
              it verbosely.<br/>
            </p>
                </subsection>
                <subsection name="3.2. Have a standard catch block and pass the 
RemoteException to a standard handle 
          method that does something with it.">
            <p>   
               That something can often by turn it into a custom derivative of 
RuntimeException as well 
               as reporting it.  This strategy makes you wonder why it was not 
a derivative of 
               RuntimeException in the first place.<br/>
            </p>
                </subsection>
                <subsection name="3.3. Try the failing method call again, or n 
times.">
            <p>
                Clutters your code with reams of retry logic.  What if it still 
fails?  Combine this 
                with (1) or (2) as well?
              </p>
                </subsection>  
        </subsection>
        <subsection name="4. It is difficult in EJB, in terms of coverage, to 
test your huge amounts of 
        RemoteException handling code">
          <p>
            Your EJB team has developed a huge amount of code for the business 
logic, and consequentually 
            loads of code concerning RemoteException.  Question how do they 
test the "connection failing" 
            logic?  Do they rip out cables while the machine is in use?  No 
that does not yield good 
            coverage.  Do they have test cases and mock beans that throw 
RemoteException?  Yes probably, 
            but that is an artificial connection outage.  However most teams do 
not test more than a 
            single case, and are happy for the same RemoteException handler 
block to be used all over 
            the place.
          </p>      
        </subsection>
        <subsection name="5. Most web-app uses of beans have a single 'handler' 
place where pertinent 
          exceptions are already caught.">
          <p>
            Webapps that use multiple beans (assuming a decent MVC separation 
or a framework like 
            Velocity) already have a place where central exception handling is 
going on.  With 
            AltRMI, you can catch InvocationException where you feel is fit.  
EJB teams that 
            choose to have throws RemoteException on all methods (percolating 
it up the stack) probably 
            also choose to finally handle it centrally. Like so ...
          </p>      
  <source>
  public Template handleRequest(HttpServletRequest req, HttpServletResponse 
resp, Context ctx) {
      Template template = null;
      String templateName = null;
      HttpSession sess = req.getSession();
      sess.setAttribute(ERR_MSG_TAG, "all ok");
      try {
          try {
              // Process the command
              templateName = processRequest(req, resp, ctx);
              // Get the template
              template = getTemplate(templateName);
          } catch (InvocationException aie) {
              template = getTemplate("commfailure.vm");
          }
      } catch (ResourceNotFoundException rnfe) {
          // blah blah
      } catch (ParseErrorException pee) {
          // blah blah
      } catch (Exception e) {
          // blah blah
      }
      return template;
  }
  </source>
        </subsection>    
      </section>
     
    </body>
    
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/monitors.xml
  
  Index: monitors.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
    <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Monitors</title>
      </properties>
    <body>
      <section name="Introduction">
        <p>
          Both the server and client sides of AltRMI can be monitored.  After 
          instantiation, the Server or Factory have a setMonitor() methods.
        </p>
      </section>          
      <section name="Server Monitor">
        <p>    
          The interface for the ServerMonitor is :
        </p>
  <source>
  <![CDATA[
  public interface ServerMonitor {
  
      void closeError(Class clazz, String s, IOException e);
  
      void badConnection(Class clazz, String s, BadConnectionException bce);
  
      void classNotFound(Class clazz, ClassNotFoundException e);
  
      void unexpectedException(Class clazz, String s, Exception e);
  
      void stopServerError(Class clazz, String s, Exception e);
  }
  ]]>
  </source>
        <p>    
          You get to choose from a number of implementations.  NullServerMonitor
          consumes all monitored events.  LogEnabledServerMonitor, 
          CommonsLoggingServerMonitor and Log4JServerMonitor route through to 
the
          appropriate logging framework.  You do not have to tie the 
application 
          you develop (that needs to use AltRMI) to any particular logging 
          framework. If you so desire, you do not need any logging jar in 
          your classpath (or classloader tree for more complex deployments).
        </p>
      </section>          
      <section name="Client Monitor">
        <p>    
          The interface for the ClientMonitor is :
        </p>
  <source>
  <![CDATA[
  public interface ClientMonitor
  {
  
      void methodCalled(Class clazz, String methodSignature, long duration, 
String annotation );
  
      boolean methodLogging();
  
      void serviceSuspended(Class clazz, Request altrmiRequest, int attempt, 
int suggestedWaitMillis );
  
      void serviceAbend(Class clazz, int attempt, IOException cause);
  
      void invocationFailure(Class clazz, String name, InvocationException ie);
  
      void unexpectedClosedConnection(Class clazz, String name, 
ConnectionClosedException cce);
  
      void unexpectedInterruption(Class clazz, String name, 
InterruptedException ie);
  }
  ]]>
  </source>
        <p> 
          The ClientMonitor has a couple of novel feautes over ServerMonitor 
(which just listens).  
          The first is that timings for method calls can be reported on. As 
timing costs time, the
          ClientMonitor reports whether it wants timing at all.  The second is 
that 
          serviceSuspend() and serviceAbend() encourages the implementor to 
join in 
          with whether the pending request will fail or try again.  It does 
this by throwing 
          InvocationException. Different strategies (fail-fast, retry-forever) 
are possible, but
          clearly they affect the way client code works.
        </p>
        <p>    
          As with the ServerMonitor, you get to choose from a number of 
implementations.  
          DumbClientMonitor consumes all monitored events without logging 
anything and 
          fails-fast for the two abend() and suspend() methods.  
DefaultClientMonitor, 
          still logs nothing, but tries for a few attempts to reestablish a 
connection.
        </p>
      </section>       
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/navigation.xml
  
  Index: navigation.xml
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <project>
  
   <title>AltRMI</title>
  
   <body>
  
      <links>
        <item name="Home" href="http://incubator.apache.org/projects/altrmi"/>
        <item name="Apache" href="http://www.apache.org/"/>
      </links>
  
      <menu name="About">
        <item name="Index" href="/index.html"/>
        <item name="Other Features" href="/otherfeatures.html"/>
        <item name="Transports" href="/transports.html"/>
        <item name="FAQ" href="/faq.html"/>
          <!-- <item name="Changes" href="changes.html"/> -->
        <item name="Credits" href="/credits.html"/>
          <!-- <item name="Todo"                 href=""/> -->
      </menu>
  
        <menu name="Modules">
                <item name="Client"             href="/client/index.html"/>
                <item name="Server"             href="/server/index.html"/>
                <item name="Tools"              href="/tools/index.html"/>
        </menu>
        
        <menu name="Tests">
                <item name="Integration Tests"  
href="/integrationtests/index.html"/>
        </menu>
        
        <menu name="Using">
        <item name="Facade Design" href="/facades.html"/>
        <item name="Generating Proxies" href="/generating-proxies.html"/>
          <item name="Publishing" href="publishing.html"/>
          <item name="Client Usage" href="client-usage.html"/>
          <item name="Pingers" href="pingers.html"/>
          <item name="Monitors" href="monitors.html"/>
          <!-- <item name="Tests" href="tests.html"/> -->
      </menu>
        
  
   </body>
  
  </project>
  
  
  
  1.1                  incubator-altrmi/xdocs/otherfeatures.xml
  
  Index: otherfeatures.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
      <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Other Features</title>
      </properties>
    <body>
      <section name="Features">
        <p>    
          There are various features of AltRMI that are either different to RMI 
or are configurable.
        </p>
        <subsection name="Choice of location of generated Proxy class">
          <p>
            Classes providing client side implementation of the transported 
          interface(s) can be either on the client side or the server side (and 
          duly transported) at the time of lookup.  On the server side, the 
proxy classes
            can be generated in advance (Ant Task) or at runtime - javac is 
invoked.
          </p>
        </subsection>
        <subsection name="Choice of castability of generated proxy class.">
          <p>
            To suit remote facilities that are happy with refection and do 
          not need to cast to an interface to use a bean (I am thinking of 
          BeanShell) the proxy class can be generated without specifying
          that it implements the interface(s).
          </p>
        </subsection>
        <subsection name="Suspendable/Resumable service.">
          <p>
            The Server supports suspend() and resume().  With the current 
implementation this
          replies in a timely fashion to the client that the client should try
          later.  The client waits for the notified amount of time and 
seamlessly
          tries the request again.  A server could cycle through suspended and 
back
          to resumed will not affect the client except for the a delay.
          </p>
        </subsection>
        <subsection name="Recovering transport">
          <p>
            AltRMI tries to recover its transports should they fail.  The 
recovery 
          is pluggable in that the developer can choose when/how/if the 
connection
          handler tries to recover the connection.  Any inprogress, but
          disconnected method invocation will attempt to be recoved and just 
return
            as normal, albeit after a longer than normal delay.
          </p>
        </subsection>
        <subsection name="Event API">
          <p>
            For suspensions, abnormal ends of connection etc, there is a 
listener 
          that can be set that will allow actions to be taken.  Abnormally 
          terminated connections will by default try to be reconnected, the 
            listener can decide if, how many, and how often the retries occur.
          </p>
        </subsection>
        <subsection name="Pluggable Transport indenpendant keep-alive concept">
          <p>
            On the client side, there is an API for a pluggable pinger.  While 
the server
          may support timeouts for client connections, the client could choose 
to
            overcome that default policy with a ping concept.
          </p>
        </subsection>
        <subsection name="Unpublishable and republishable API">
          <p>
            The server is able to unpublish a service.  In conjuction with 
          suspend()/resume() a service can be republished, upgraded etc
          whilst in use, or just offlined.
          </p>
        </subsection>
        <subsection name="Startable API for Server">
          <p>
            The server implements and acts upon start() and stop() methods.
          </p>
        </subsection>
        <subsection name="Not just pass by value.">
          <p>
            AltRMI started life as 'pass by value' only.  In now supports 
return 
            types and parameters wrapped in another AltRMI Facade.
          </p>
        </subsection>
        <subsection name="No duplicate instances.">
          <p>
            For Facades, if you call Person p = getPerson("Fred") twice you 
will get 
          the same instance on the client side if it is the same instance on the
            server side.        
          </p>
        </subsection>
        <subsection name="Load balancing server grouping">
          <p>
            In some configurations, the client side can have multiple servers 
it 
            will forward calls to (TODO).
          </p>
        </subsection>
      </section>       
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/pingers.xml
  
  Index: pingers.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
    <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Pingers</title>
      </properties>
  
    <body>
      <section name="Introduction">
        <p>
          Although it may not be necessary for all types of transport, 
          there is a mechanism called a pinger that can be used to keep
          the connection alive. Pingers run on the client side.
        </p>
      </section>          
      <section name="Pinger Interface">
        <p>
          It is possible to write your own or extend the exiting 
          ones if there are different requirements.  The interface for bespoke 
pingers 
          is 'ConnectionPinger'
        </p>    
  <source>
  <![CDATA[
  public interface ConnectionPinger
  {
  
      void setInvocationHandler( ClientInvocationHandler 
altrmiInvocationHandler );
  
      void start();
  
      void stop();
  }
  ]]>
  </source>      
      </section>          
      <section name="Pinger types">
        <p>    
          Here are the types of pinger implemented so far
        </p>
        <subsection name="DefaultConnectionPinger">
          <p>
            This pinger pings every ten seconds, but stops one hundred seconds
            after the last real request.  The 10 &amp; 100 are configurable of 
course.
          </p>
          <p> 
            This pinger is the default and will be used if no other is
            specified.
          </p>        
        </subsection>
        <subsection name="PerpetualPinger">
          <p>
            This pinger pings every ten seconds until the connection is closed.
          </p>
        </subsection>
        <subsection name="NeverConnectionPinger">
          <p>
            This pinger never pings the server.
          </p>
        </subsection>      
      </section>       
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/publishing.xml
  
  Index: publishing.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
   <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Publishing</title>
      </properties>
        
  <body>
      <section name="Introduction">
        <p>
          Publishing is a server responsibility obviously, it is quite straight 
forward.
        </p>
      </section>          
      <section name="Publishing">
        <p>    
          You have to choose your server, publish the implimentation 
(reiterating the interfaces that will
          be pass-by-reference boundaries), then start the server.....
        </p>              
  <source>
  <![CDATA[
          AbstractServer as = new CompleteSocketCustomStreamServer(1235);
          TestInterfaceImpl ti = new TestInterfaceImpl();
          as.publish(ti, "Hello", new 
PublicationDescription(TestInterface.class, TestInterface2.class));
          as.start();
  ]]>
  </source>
        <p>    
         After starting the server client connections will be accepted.
        </p>      
      </section>
    </body>
  </document>
  
  
  
  1.1                  incubator-altrmi/xdocs/site.xml
  
  Index: site.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <site label="AltRMI" href="" xmlns="http://apache.org/forrest/linkmap/1.0";>
  
    <about label="About">
      <index label="Index" href="index.html"/>
      <item href="otherfeatures.html" label="Other Features"/>
      <item href="transports.html" label="Transports"/>    
      <faq label="FAQ" href="faq.html"/>
      <changes label="Changes" href="changes.html"/>
      <todo label="Credits" href="credits.html"/>
      <todo label="Todo" href="todo.html"/>
    </about>
    
    <about label="Using"> 
      <item href="facades.html" label="Facade Design"/>
      <item href="generating-proxies.html" label="Generating proxies"/>
      <item href="publishing.html" label="Publishing"/>
      <item href="client-usage.html" label="Client usage"/>
      <item href="pingers.html" label="Pingers"/>
      <item href="monitors.html" label="Monitors"/>
      <item href="tests.html" label="Tests"/>  
    </about>  
  
    <external-refs>
      <xml.apache.org href="http://xml.apache.org/";>
        <forrest href="forrest/">
          <validation href="validation.html"/>
          <webapp href="your-project.html#webapp"/>
        </forrest>
        <cocoon href="cocoon/"/>
      </xml.apache.org>
    </external-refs>
  
  </site>
  
  
  
  1.1                  incubator-altrmi/xdocs/transports.xml
  
  Index: transports.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
     <properties>
          <author email="[EMAIL PROTECTED]">Paul Hammant</author>
          <title>Transports</title>
      </properties>
    <body>
      <section name="Introduction">
        <p>
          AltRMI has pluggable and reimplementable transports.  They differ in 
terms of speed and layers of transport.
          Some are in VM, others between VMs using sockets and various Java 
concepts.
        </p>
      </section>
      <section name="Supplied Request/Response Transports">
        <p>
          The supplied transports fall into two categories - Intra-JVM and 
Inter-JVM. The Inter-JVM types are for
          bridging a network divide over TCP/IP.  This can also mean two JVMs 
in the same physical machine, using
          local-loop TCP/IP. The Intra-JVM types are for situations where 
normal dynamic proxy will not work.  For
          example when the client and the server both have a definition of the 
same interface in different
          classloaders.  Most Java projects do not involve trees of 
classloaders, but writing frameworks like
          Avalon-Phoenix or or an implementation of the EJB specification will.
        </p>
        <p>
          All of these transports are synchronous too.  That means that an 
invocation across their connection
          will wait until it is completed server side before the next 
invocation is allowed through.
        </p>
  
        <subsection name="Plain Sockets / ObjectStream &amp; CustomStream 
varients">
          <p>
            This transport is a streaming type that uses serialization of 
objects over a TCP/IP connection.  There
            are two variations. The first uses java.io.ObjectInputStream &amp; 
java.io.ObjectOutputStream (AKA
            'ObjectStream', the second uses what we call 'CustomStream'. 
CustomStream came into being because of this
            bug <link 
href="http://developer.java.sun.com/developer/bugParade/bugs/4499841.html";>
            
http://developer.java.sun.com/developer/bugParade/bugs/4499841.html</link>
            which seriously restricts the usefulness of ObjectStream as a 
transport
            (and the same java.io classes for other uses). Custom Stream is 
slower by 20%, but we recommend it's use
            over ObjectStream.  At least until the bug at Sun is fixed (please 
vote for it).
          </p>
        </subsection>
        <subsection name="Over RMI">
          <p>
            This is another transport that bridges two different JVMs using 
TCP/IP.  It is actually the fastest of all the
            TCP/IP using transports. and takes advantage of RMI as it's 
transport while hiding RMI from the AltRMI
            client and server.
          </p>
        </subsection>
        <subsection name="Piped with same VM / ObjectStream &amp; CustomStream 
varients">
          <p>
            In a similar way to the ObjectStream and CustomStream 
implementations of the plain sockets transport, these
            offer transport using a pipe inside the JVM.  Not needed for most 
users of AltRMI these prove useful for
            developers making complex trees of classloaders with high 
separation from each other. As a Pipe is being
            used there is is some opportunity for buffering of invocations.  
This might slow the throughput down but
            this may relieve other parts of a particular design.
          </p>
        </subsection>
        <subsection name="Direct within same VM">
          <p>
            There are 'Direct' and 'DirectMarshalled' transports.  These are 
use useful in the same scenarios as
            the Piped one, but with some small differences.  Principally, there 
is no pipe - the invocation is
            immediately handled on the server side.  With Direct there is also 
the fact that all mutually visible
            classes and interfaces would have to be in a commonly visible 
classloader.  With DirectMarshalled,
            there can be duplicate interfaces and class definitions as in the 
streamed types of transport.
          </p>
        </subsection>
        <subsection name="JNDI">
          <p>
            Many of the basic transport types are accessible client side 
through JNDI.  This makes the client side usage
            more standards compliant, but these is no need to choose it over 
the bespoke AltRMI client usage at all.
          </p>
        </subsection>
      </section>
      <section name="Supplied Callback capable Transports">
        <p>
          All of these transports are asynchronous.  Thais means that an 
invocation across the connection
          does not wait until the reply is ready before it allows another 
request though.  This allows
          two things - excpetionally lengthy requests (that might ordinarily 
affect timeouts) to be performed and
          callbacks (server invoking requests on the client).  There is a small 
(15%) cost to using this transport for
          simple cases, but its benefits outweigh its deficiencies.
        </p>
        <p>
          Whilst the Callback enabled transports are better from the point of 
view of asynchronous behaviour
        </p>
      </section>
      <section name="Future Transports">
        <p>
        </p>
          <ul>
            <li>SOAP - Might require additional undynamic "toWSDL()" step.</li>
          <li>CORBA - Might require additional undynamic "toIDL()" step.</li>
          <li>JMS</li>
          <li>UDP</li>
          <li>Over RMI over IIOP</li>
          <li>Over JMS</li>
          <li>Over RMI over HTTP</li>
          <li>Over HTTP (custom impl)</li>
          <li>TLS enabled versions of many of the above.</li>
          </ul>
  
      </section>
      <section name="Speed">
        <p>
          Counting the number of 'void testSpeed()' invocations in 10 seconds,
          we can guage the differences (Paul's Athlon900/Win2K machine)
  
        </p>
            <subsection name="AltRMI types over TCP/IP">
            <p>
            For remote publication<br/>
            <br/>
            Speed Test type                   Count Relative<br/>
            ------------------------------- ------- --------<br/>
            a) ObjectStream over sockets #2    2702     1.00<br/>
            b) Over RMI                        4359     1.61<br/>
            c) CustomStream over sockets       6069     2.25<br/>
            d) ObjectStream over sockets #1   10088     3.73<br/>
  
              </p>
              </subsection>
            <subsection name="AltRMI types in the same VM">
            <p>
  
            These are useful for complete classloader separation of interface 
&amp; implementation using
            different classloaders. The implementation and 'remote' proxy do 
not need to see the same
              interfaces etc..<br/>
              <br/>
            Speed Test type                   Count Relative<br/>
            ------------------------------- ------- --------<br/>
            e) ObjectStream over Pipe #2      12095     4.48<br/>
            f) Direct Marshalled #3           20759     7.68<br/>
            g) ObjectStream over Pipe #1      61166    22.64<br/>
            h) Direct Unmarshalled #4        2391498   885.08<br/>
  
            #1 Without calling reset() as workaround to the ObjectStream bug
            #2 With calling reset() as workaround to the ObjectStream bug
            #3 Completely separates classloaders of client and server. Requires
               a thread for each though.
            #4 Good as DynamicProxy for separation. Does not separate 
classloaders
               of client and server.
            </p>
            </subsection>
            <subsection name="Non AltRMI types">
            <p>
  
            - In VM, without using AltRMI - for comparison.
            - The inteface, implementation and proxy cannot be separated in 
terms of
              branches of classloader for these three. The same interfaces
              etc must be visible to both implementation and proxy.
              <br/>
            Speed Test type                   Count Relative<br/>
            ------------------------------- ------- --------<br/>
            i) DyanmicProxy #5<br/>
               (copied from Excalibur)     20282070  7506.32<br/>
            j) Hand-coded proxy #5         41214422 15253.30<br/>
            k) No Proxy #5                 42384804 15686.46<br/>
            <br/>
            #4 - For all of these three, the actual timing may slow down the 
test.<br/>
             </p>
             </subsection>
      </section>
       <section name="Secrets of classloading">
        <p>
          There is a feature of classloading that affects the way that the an 
AltRMI using client and server interoperte
          when it comes to resolving classes and interfaces for a given object. 
 As is widely known, the JVM resolves
          depended on classes for a being-instantiated object at runtime. The 
issue concerns a class definition existing
          twice in a tree of classloaders and whther the JVM considers an 
instance of each to be of the same type.
        </p>
        <p>
          Consider a tree of three classloaders - A, B and C.  Consider that A 
is the parent classloader of B &amp; C.
          This means that B can access all the classes mounted by itself and by 
A.  Similarly C can access all the
          classes mounted by itself and A.  Now if A had a singleton that 
stored a single object via
          <strong>void setObject(object o);</strong> and <strong>Object 
getObject();</strong>, and clases in
          B amp; C could invoke those methods freely, the you might consider 
that B has a way of taking to C.  if B
          called (essentially) <strong>A.setObject("Hello")</strong>, then C 
could indeed call <strong>String
          s = A.getObject()</strong> without any problem.  Say a class being 
passed were called 'Thing' and was in the
          classloader of B and duplicated in the classloader of C, but not in A 
at all, then it would not be passable
          by the setter/getter mechanism outlined above.  Why?  The JVM 
considers then different classes because they
          are mounted in different classloaders (even though from the same 
source).  That is a secret
          of classloading (at least as it pertains to RPC in one VM).
        </p>
        <p>
          The issue is relevent to AltRMI mostly if it is being used to connect 
two nodes of a single classloader tree.
          If the transport chosen is 'Direct' then you will get 
ClassCastExceptions thrown by the JVM if you had been
          passed an Object you wanted to cast up to something, and that 
something were represented by a class definition
          in both the server and client nodes of the classloader tree.  If the 
something class were in a mutualy
          visible parent class loader then no issue would be apparent.  IF the 
client and server were in separate VMs,
          then no issue would be apparent, principally because the marchalling 
to serialized form neatly hides the
          two class definitions from the JVM.  This is the clue to the solving 
of the issue for a particular
          client/server (in one JVM) configuration you may be cooking up.  If 
you choose Piped or DirectMarshalled as
          trasnports, then you can have the same class definition in multiple 
classloader nodes.  Of couse, both Piped
          and DirectMarshalled are slower than Direct as transports.  
Configuration choices for the developer/deployer.
        </p>
      </section>
    </body>
  </document>
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to