Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mucode/abstractions/MuAgent.java


1   /* mucode - A lightweight and flexible mobile code toolkit
2    * Copyright (C) 2000, Gian Pietro Picco
3    *  
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *  
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   * Lesser General Public License for more details.
13   * 
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not, write to the Free Software
16   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   */
18  package mucode.abstractions;
19  
20  import mucode.util.*;
21  import mucode.*;
22  import java.io.*;
23  import java.net.*;
24  
25  /** Provides a <i>"mobile agent"</i> abstraction. <br>
26   *
27   * Migration is obtained by invoking the {@link #go go} method as in
28   * <code>myAgent.go("myhost:2000")</code>. After migration, the agent is
29   * removed from the source host.<BR>
30   * 
31   * Only <a href="">weak mobility</a> is provided, in that the <a
32   * href="">execution state</a> of the agent (i.e., its instruction pointer and
33   * call stack) is not preserved across migration---a limitation coming from
34   * the Java VM.  However, the <a href="">data state</a> of the agent, i.e.,
35   * the values of its object fields, is preserved. <p>
36   *
37   * The agent can determine, from time to time, which classes should be shipped
38   * at destination along with it. This is accomplished by the
39   * <code>classNames</code> parameter in {@link #go(String, String[], String,
40   * boolean)}. The methods provided by {@link ClassInspector} and {@link
41   * java.lang.Class} may be useful in determining such classes.<br> The method
42   * {@link #go(String)} provides a simplified version of the previous method,
43   * where the agent is shipped along with its complete class closure (excluding
44   * classes that are ubiquitous in the <i>&micro;</i>Server hosting the
45   * agent). <p>
46   * 
47   * The only requirement imposed on subclasses of this class is that they
48   * <u>must implement a public, parameterless constructor</u>, the reason being
49   * that the agent class serves both as a root and a handler class for the
50   * group that is being shipped and reconstructed being the scenes. <p>
51   * 
52   * The mobile agent abstraction provided by this class is more powerful than
53   * the ones found in the majority of current mobile agent systems, in that the
54   * amount of code to be transferred at destination is completely under the
55   * control of the programmer. Still, it is just <i>one</i> example of the many
56   * flavors of mobile agent one could build on top of the fundamental
57   * primitives provided by the {@link mucode} package.
58   *
59   * @author <a href="mailto:picco@elet.polimi.it">Gian Pietro Picco</a>
60   * @version 1.0
61   * @see Thread
62   * @see GroupHandler
63   * @see MuServer */
64  public abstract class MuAgent extends Thread 
65    implements GroupHandler, Serializable {
66    private transient MuServer server = null;
67    private static final String AGENTLABEL = "_MuAgent_";
68  
69    /** Creates a new agent and binds it to a <i>&micro;</i>Server, that will
70        handle agent migration upon invocation of the {@link #go go} method. */
71    public MuAgent(MuServer server) { this.server = server; }
72  
73    /** (<u>This constructor should never be used by the programmer</u>.) The
74        * public, parameterless constructor that must be implemented by a root
75        * or handler class. In this case, subclasses of <code>MuAgent</code>
76        * actually represent both. */
77    public MuAgent() { super(); } 
78  
79    /** Determines the migration of the agent. The execution state is discarded,
80     * while the data state is preserved and restored at the destination
81     * <i>&micro;</i>Server. Since this method is <code>public</code>, any
82     * object is allowed to determine the migration of this agent.<BR>
83     *
84     * @param destination the address of the target <code>MuServer</code> object,
85     * specified as <code>hostname:port</code>.
86     * @param classNames the names of the classes needed by the agent at
87     * destination, that will be loaded in its private class space.
88     * @param dynLink the address of a <i>&micro;</i>Server from which classes
89     * not shipped along with the <code>Runnable</code>object can be retrieved
90     * through dynamic linking. If <code>null</code>, remote dynamic linking is
91     * prevented.
92     * @param synch if <code>true</code>, the operation is blocking for the
93     * caller, that is suspended until a return value is received after the
94     * thread is restarted on the target <i>&micro;</i>Server. Otherwise, the
95     * method returns immediately after group transmission is completed.
96     * @exception NotSerializableException if some of the fields of the agent
97     * are not serializable, i.e., they do not implement the {@link
98     * java.io.Serializable} interface.
99     * @exception IOException if the symbolic name given as
100    * destination cannot be resolved in a proper IP address, or some problem
101    * occurs with connection or serialization.  
102    * @exception ClassNotFoundException if some of the classes referenced
103    * by the group cannot be resolved.  */
104   public final void go(String destination, String[] classNames, 
105                        String dynLink, boolean synch) 
106     throws IOException, ClassNotFoundException {
107 
108     // This guarantees that the server grabs automatically the server where it
109     // has been created, when and if it gets launched using rSpawnThread.
110     if (server == null) server = MuServer.getServer(this);
111 
112     // Determines the agent's classname.
113     String agentClassName = this.getClass().getName();
114     // Requests a new group to the agent server.
115     Group group = server.createGroup(agentClassName, agentClassName);
116     // Add the agent to the group, identified by the system-defined label.
117     group.addObject(AGENTLABEL, this);    
118     // Add the class closure
119     group.addClasses(classNames);
120     group.setDynamicLinkSource(dynLink);
121     group.setSynchronousTransfer(synch);
122     // The group containing the agent's code and state is sent at destination.
123     group.ship(destination);
124     // The agent thread is stopped and eventually removed from the server.
125     this.stop();
126   }
127 
128   
129   /**
130    * Same as {@link #go(String, String[], String, boolean)} but with
131    * <code>classNames</code> containing the full class closure of the agent
132    * class, remote dynamic linking disabled, and asynchronous transfer.
133    *
134    * @param destination the address of the target <code>MuServer</code>
135    * object, specified as <code>hostname:port</code>. */
136   public final void go(String destination)    
137     throws IOException, ClassNotFoundException {
138     // This guarantees that the server grabs automatically the server where it
139     // has been created, when and if it gets launched using rSpawnThread.
140     if (server == null) server = MuServer.getServer(this);
141 
142     go(destination, 
143        ClassInspector.getClassClosure(this.getClass().getName(), 
144                                       server, ClassInspector.FULLCLOSURE),
145        null, false);
146   }
147 
148   /** Provides specialized handling of the group containing the object, as
149    * defined by <code>GroupHandler</code>. 
150    *
151    * @param group the group to be handled. It is passed to the method directly
152    * by the <i>&micro;</i>Server thread running on the host.
153    * @return in this case, the agent's thread to be restarted. 
154    * @exception MuCodeException may be thrown within the method to signal
155    * abnormal conditions, and can contain internal exceptions. 
156    */
157   public final Thread unpack(Group group) throws MuCodeException {
158     MuAgent agent = (MuAgent) group.getObject(AGENTLABEL);
159     agent.server = group.getServer();
160     return agent;
161   }
162 
163   /** Must be redefined by the programmer with the behavior of the agent. */
164   public abstract void run();
165 }
166