Java facilities for mobile code

    This sections is based on a number of excellent articles from JavaWorld. They are not only well written turials, but they include amazing demonstrations implemented as Java applets.

    The next two articles present an overview of the internals of the Java Virtual Machine (JVM) and JVM support mechanisms for code mobility.
     

    1. Under the Hood: The lean, mean, virtual machine
    2. The basics of Java class loaders


    We will have only a short look at the next two articles. Further study is left as an exercise for those, who are interested in such details. The first describes the internal format of a Java class file. The second is a description of Java bytecodes.
     

    1. Under the Hood: The Java class file lifestyle
    2. Under the Hood: Bytecode basics
    The following are also very interesting articles that are well worth reading. The first describes how the Java garbage collector works. The second describes new JVM technologies (i.e. incremental garbage collection and dynamic compilation)  that promise to bring Java speed up to, or even to exceed, the speed of native code (obtained by compiling C++ and other languages with static compilers).
     
    1. Java's garbage-collected heap
    2. HotSpot: A new breed of virtual machine

    Count with mobile code

    The last implementation of our Count example uses mobile agents to increment, set and get the counter. As you may remember, we call such agents deglets. In the Mobile Code Toolkit, deglets are specializations of the class Netlet.

    The counter resides on a remote (target) node. The access to the counter is provided by a Virtual Managed Component, which is called CountVMC. Deglets can use this VMC is they know the ontology, which it uses. In here, the ontology is defined by the behavior specified by the Count interface. VMCs constitute a security firewall between mobile agents and node resources.

    Each utility deglet has to be equipped with the information about the target (address) and injected into the network. The injection can be performed by a user-oriented application, or it vcan be sent by a process running on another node. The deglet is migrated by the mobility infrastructure until it arrives at the target node. Here, the requested operation is performed. If the the source address has been specified as well, then it is used to return to the source node. Mobile Agents should be small, so a number of them are used in this example. The SetDeglet can be used to set the value of the counter. The IncrementDeglet will increment the value of the counter. Neither of them needs to return to the source, so they are destroyed after achieving their respictive goals. This behavior is provided by the abstract CountDeglet, which is a super class for all other deglets. The goal of the GetDeglet is to obtain the value of the counter, so it carries both the address of the target and the address of the source hosts. The address of the source node is used to bring the value of the counter to the requesting party.
     


    Count interface

    package CountMCT;

    import mct.users.VMCException;

    public interface Count
    {
      int sum() throws VMCException;
      void sum(int arg) throws VMCException;
      void increment(int val) throws VMCException;
    }

    Count VMC

    package CountMCT;

    import java.util.*;
    import mct.users.VirtualManagedComponent;
    import mct.users.VMCException;

    public class CounterVMC
      extends VirtualManagedComponent
      implements Count
    {
     private int sum;

      public CounterVMC()
      {
       int sum = 0;
      }

      /**
       * Set the value of the counter
       */
      public void sum(int value) throws VMCException
      {
        sum = value;
      }

      /**
       * Get the value of the counter
       */
      public int sum() throws VMCException
      {
        return sum;
      }

      /**
       * Increase the value of the counter by the specified step
       */
      public void increment(int step)  throws VMCException
      {
       sum = sum + step;
      }
    }

    CountDeglet abstract superclass

    /* A deglet to set the counter */

    package CountMCT;

    import java.net.*;

    import mct.users.Netlet;
    import mct.users.VirtualManagedComponent;
    import mct.users.VMCException;
    import mct.users.MobileCode;

    public abstract class CountDeglet extends Netlet
    {
     private CounterVMC counterVMC;
      private int sum;
      private String sourceHost, targetHost;

      public void onInit ()
      {
       sourceHost = (String) getParameter("SourceHost");
        targetHost = (String) getParameter("TargetHost");

        if (targetHost == null)
        {
          System.out.println("\tTarget required.");
          destroy();
        }

       if (sourceHost == null)
       {
          try
          {
           sourceHost = InetAddress.getLocalHost().getHostName();
          putParameter("SourceHost", sourceHost);
         }
         catch (UnknownHostException e)
         {
          System.out.println("\tException: " + e);
         }
       }

        if (atTarget())
          counterVMC = (CounterVMC) getVirtualManagedComponent("CounterVMC", true);
      }

     public void onStart()
     {
        // if the target found, then return directly to the source
        if (atTarget())
          if (sourceHost != null)
          {
            try
            {
               migrate(this, InetAddress.getByName(sourceHost), 3100, true);
            }
            catch (UnknownHostException e)
            {
              System.out.println("\tException: " + e);
            }
          }
          else
          {
            destroy();
          }
      }

      boolean atTarget()
      {
        try
        {
          return targetHost == InetAddress.getLocalHost().getHostName();
        }
        catch (UnknownHostException e)
        {
          System.out.println("\tException: " + e);
          return false;
        }
      }

     boolean atSource()
     {
        try
        {
        return sourceHost == InetAddress.getLocalHost().getHostName();
       }
       catch (UnknownHostException e)
       {
        System.out.println("\tException: " + e);
          return false;
       }
     }
    }

    IncrementDeglet class

    /* A deglet to increase the value of the counter */

    package CountMCT;

    import mct.users.Netlet;
    import mct.users.VirtualManagedComponent;
    import mct.users.VMCException;
    import mct.users.MobileCode;

    public class IncrementDeglet extends CountDeglet
    {
     private CounterVMC counterVMC;
      private int step;

      public void onInit ()
      {
       super.onInit();

        String stepString = (String) getParameter("Step");
       if (stepString == null)
       {
         putParameter("Step",Integer.toString(1));
         step=1;
       }
       else
       {
         step=Integer.parseInt(stepString);
       }
      }

     public void onStart()
     {
        if (counterVMC != null)
       {
         try
         {
          counterVMC.increment(step);
         }
         catch (VMCException ex)
         {
          System.out.println ("\t" + ex);
         }
       }

        super.onStart();
      }
    }

    SetDeglet class

    /* A deglet to set the counter */

    package CountMCT;

    import mct.users.Netlet;
    import mct.users.VirtualManagedComponent;
    import mct.users.VMCException;
    import mct.users.MobileCode;

    public class SetDeglet extends CountDeglet
    {
     private CounterVMC counterVMC;
      private int value;

      public void onInit ()
      {
       super.onInit();

        String valueString = (String) getParameter("Value");
       if (valueString == null)
       {
          destroy();
        }
       else
       {
         value = Integer.parseInt(valueString);
       }
      }

     public void onStart()
     {
       if (counterVMC != null)
       {
         try
         {
          counterVMC.sum(value);
         }
         catch (VMCException ex)
         {
          System.out.println ("\t" + ex);
         }
       }

        if (atSource())
        {
          // Could do something on return
        }

        super.onStart();
      }
    }

    GetDeglet class

    /* A deglet to set the counter */

    package CountMCT;

    import java.net.*;

    import mct.users.Netlet;
    import mct.users.VirtualManagedComponent;
    import mct.users.VMCException;
    import mct.users.MobileCode;

    public class GetDeglet extends CountDeglet
    {
     private CounterVMC counterVMC;
      private int sum;
      private String returnHost, targetHost;

     public void onStart()
     {
        if (counterVMC != null)
        {
          try
          {
            sum = counterVMC.sum();
          }
          catch (VMCException ex)
          {
            System.out.println ("\t" + ex);
          }
        }

        // Could do something with the returned value

        if (atSource())
        {
          String returnValueString = (String) getParameter("Sum");
          if (returnValueString == null)
          {
            System.out.println("\tFailed to obtain the value of the counter.");
          }
          else
          {
            sum = Integer.parseInt(returnValueString);
            System.out.println("\tThe value of the counter is: " + sum);
          }
        }

        super.onStart();
      }

      public int onMigrate()
      {
       putParameter("Sum", Integer.toString(sum));

       return SERIALIZE;
      }
    }