A friend and I have been working on Java Agent DEvelopment Framework (JADE) for a while now. The idea is to enhance security mechanisms in the open source agent-deployment platform. The first step we decided to address was the actual mobility of an agent from one platform (in the sense of a dedicated machine running the JADE middleware) to another one. Turned out that it was much harder than one would imagine — especially given the fact that these agents are supposed to be mobile. Anyway, after around two months of part-time efforts, we got the agent working. Since the whole ordeal involved a lot of missing documentation and bad support, I decided to document the process through this tutorial. So, here it is. Read on to see how you can create an agent on one platform, migrate it to another platform, have it do some computation there and come back to the source.
First, you’re going to need two machines running Ubuntu. (We used Ubuntu 11.10 oneric for this.) If you only have one machine, you can install VirtualBox, setup a Ubuntu instance in a VM and connect it to the host through a virtual interface. I prefer using two adapters, first one set to a NAT setting and another one set to Host-only setting. This way, I get Internet connectivity in the guest as well as host-to-guest simple addressing.
We’re going to use JADE 3.6 along with the JADE Inter-platform Mobility Service (JIPMS) 1.2 for our needs. Download JADE and JIPMS. I used jade-binary package and extracted it in /home/documents/jade. I also extracted the JIPMS and moved the file migration.jar from its lib folder to the lib folder of jade binary. This makes it easier for us to change the classpath later on. We’ll need these files on both machines.
Now we need to setup the machines. Here are the details of the setup on each machine:
Host:
hostname: slave1
IP: 192.168.56.1 (set by VirtualBox automatically)
You can get the IP addresses of each machine through the ifconfig command. Edit /etc/hosts to insert the other machine’s address. My hosts file on slave1 looks like this:
# 127.0.0.1 localhost 127.0.0.1 slave1 192.168.56.101 slave2
Now, we can run jade using the following command:
java -cp lib/jade.jar:lib/migration.jar:lib/iiop.jar:
lib/jadeTools.jar:lib/http.jar:
lib/commons-codec/commons-codec-1.3.jar
jade.Boot
-gui
-platform-id slave1
-host slave1
-services jade.core.mobility.AgentMobilityService\;
jade.core.migration.InterPlatformMobilityService
-accept-foreign-agents true
You will need to use a little common sense about the line breaks and spaces here. I’ve formatted the command for highest readability. (Note the escaped ‘;’ in the services param and the use of full colon instead of the semi-colon in the classpath. This is only required on *nix platforms.) Three switches are important here: platform-id, host and services. First two are self-explanatory. Third tells the IPMS to start the services that take care of the agent migration. We also need to enable the acceptance of foreign agents but I’m sure you already knew that from all the mailing list searches.
Guest:
hostname: slave2
IP: 192.168.56.101 (set by VirtualBox automatically)
The hosts file looks like this:
# 127.0.0.1 localhost 127.0.0.1 slave2 192.168.56.1 slave1
Start jade on slave2 using the following command:
java -cp lib/jade.jar:lib/migration.jar:lib/iiop.jar:
lib/jadeTools.jar:lib/http.jar:
lib/commons-codec/commons-codec-1.3.jar
jade.Boot
-gui
-platform-id slave2
-host slave2
-services jade.core.mobility.AgentMobilityService\;
jade.core.migration.InterPlatformMobilityService
-accept-foreign-agents true
The Agent:
Now, we turn to the actual agent code that does the migration. For this, we can setup eclipse and code from within that. The code for the agent is fairly straight-forward:
package org.csrdu.mobility;
import jade.core.AID;
import jade.core.Agent;
import jade.core.PlatformID;
import jade.core.behaviours.TickerBehaviour;
@SuppressWarnings("serial")
public class MobileAgent extends Agent {
@Override
protected void setup() {
super.setup();
addBehaviour(new MyTickerBehaviour(this, 1000));
System.out.println("Hello World. I am an agent!");
System.out.println("My LocalName: " + getAID().getLocalName());
System.out.println("My Name: " + getAID().getName());
System.out.println("My Address: " + getAID().getAddressesArray()[0]);
}
private class MyTickerBehaviour extends TickerBehaviour {
Agent agent;
// long interval;
int counter;
public MyTickerBehaviour(Agent agent, long interval) {
super(agent, interval);
this.agent = agent;
// this.interval = interval;
}
@Override
protected void onTick() {
if (counter == 3) {
// move out
AID remoteAMS = new AID("ams@slave2", AID.ISGUID);
remoteAMS.addAddresses("http://slave2:7778/acc");
PlatformID destination = new PlatformID(remoteAMS);
agent.doMove(destination);
}
if (counter == 10) {
// move back
AID remoteAMS = new AID("ams@slave1", AID.ISGUID);
remoteAMS.addAddresses("http://slave1:7778/acc");
PlatformID destination = new PlatformID(remoteAMS);
agent.doMove(destination);
}
if (counter < 15)
System.out.println(counter++);
else
agent.doDelete();
}
}
}
For the sake of completion, here’s the arguments that you have to pass when running the agent code from within eclipse.
-container -agents mob:org.csrdu.mobility.MobileAgent -services jade.core.mobility.AgentMobilityService;jade.core.migration.InterPlatformMobilityService
Also, add all the jade and mobility jars to the build path of the project. I’m not sure which ones are needed here so you will have to figure that out on your own.
Caveats:
- If you get this error:
Destination slave2:1099/JADE does not exist or does not support mobility, it most probably means that you (a) you don’t have IPMS running, (b) you didn’t put the -services switch properly (c) there’s a firewall blocking your port 7778 or (d) your hostnames are messed up. In any case, the whole instructions above should work for you. - You will most probably need to change your /etc/hosts file and comment out the line that says ’127.0.0.1 localhost’. It causes JADE to start the ams@slaveN service as http://localhost:7778/acc instead of http://slaveN:7778/acc and that means a lot of missed ACL messages and a lot of headaches. You usually get the dreaded
getContainerID() failed to find agent ams@slave1error because of this. Do this for both the host and the guest. Make sure your JADE GUI looks like the following:

- Finally, if you need detailed logging, you can create the logging config file by the name of logging.properties given below and pass the
-Djava.util.logging.config.file=logging.propertiesparameter when starting JADE. This will give much finer-grained logs. This is standard log4j syntax.
handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler .level=INFO jade.domain.mobility.level=ALL # --- ConsoleHandler --- java.util.logging.ConsoleHandler.level=ALL java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter # --- FileHandler --- java.util.logging.FileHandler.level=ALL java.util.logging.FileHandler.pattern=%h/java%u.log java.util.logging.FileHandler.limit=50000 java.util.logging.FileHandler.count=1 java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter






Can i get your help please. I try several time ,but it does not work I do every things you wrote above but the agent does not move to the remote plateform and there are no errors in the terminate.
i will appreciate your help thank you.
Rafat, can you paste your logs on gist.github.com or pastebin.com and send me the link? I’ll need to see the logs before I can help. Also, please enable the detailed logging as I described at the end of the tutorial so that we can see what’s going on.
Hello there,
I’m having the following error:
run:
Feb 19, 2012 3:23:15 PM jade.core.Runtime beginContainer
Retrieving CommandDispatcher for platform slave1
INFO: ———————————-
This is JADE 4.1.1 – revision 6532 of 2011/11/18 16:21:34
downloaded in Open Source, under LGPL restrictions,
at http://jade.tilab.com/
—————————————-
Feb 19, 2012 3:23:18 PM jade.imtp.leap.LEAPIMTPManager initialize
INFO: Listening for intra-platform commands on address:
- jicp://169.254.107.142:1099
Feb 19, 2012 3:23:19 PM jade.core.BaseService init
INFO: Service jade.core.management.AgentManagement initialized
Feb 19, 2012 3:23:19 PM jade.core.BaseService init
INFO: Service jade.core.messaging.Messaging initialized
Feb 19, 2012 3:23:19 PM jade.core.BaseService init
INFO: Service jade.core.resource.ResourceManagement initialized
Feb 19, 2012 3:23:19 PM jade.core.BaseService init
INFO: Service jade.core.mobility.AgentMobility initialized
Feb 19, 2012 3:23:19 PM jade.core.BaseService init
INFO: Service jade.core.migration.InterPlatformMobility initialized
Feb 19, 2012 3:23:19 PM jade.core.migration.InterPlatformMobilityService init
WARNING: AGENTS_PATH property not set, using C:\Users\Priesh\Documents\NetBeansProjects\MobileAgent5\ directory for jar agents
Feb 19, 2012 3:23:19 PM jade.core.migration.InterPlatformMobilityService init
WARNING: Resource cache is: enabled
Feb 19, 2012 3:23:19 PM jade.core.migration.InterPlatformMobilityService init
WARNING: IPMS: Default transfer protocol is set to: pctp-v1
Feb 19, 2012 3:23:19 PM jade.core.migration.InterPlatformMobilityService init
INFO: jade.core.migration.InterPlatformMobilityService initialized
Feb 19, 2012 3:23:20 PM jade.mtp.http.HTTPServer
INFO: HTTP-MTP Using XML parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
Feb 19, 2012 3:23:20 PM jade.core.messaging.MessagingService boot
INFO: MTP addresses:
http://Priesh-PC:7778/acc
Feb 19, 2012 3:23:20 PM jade.core.migration.protocols.PushTransferProtocol
WARNING: Jar cache is: enabled
Feb 19, 2012 3:23:20 PM jade.core.migration.protocols.PushCacheTransferProtocol
WARNING: Jar cache is: enabled
Feb 19, 2012 3:23:20 PM jade.core.migration.protocols.FragmentedTransferProtocol loadParameters
WARNING: Jar cache is: enabled
Feb 19, 2012 3:23:21 PM jade.core.AgentContainerImpl joinPlatform
INFO: ————————————–
Agent container Main-Container@169.254.107.142 is ready.
——————————————–
Feb 19, 2012 3:23:21 PM jade.tools.ToolAgent init
WARNING: NotificationService not installed. Some tool may not work properly.
Hello World. I am an agent!
My LocalName: m
My Name: m@slave1
My Address: http://Priesh-PC:7778/acc
0
1
2
3
Feb 19, 2012 3:25:59 PM jade.core.migration.MigrationInitiator handleAllResponses
WARNING: MigrationInitiator: Timeout expired.
4
Feb 19, 2012 3:25:59 PM jade.core.migration.InterPlatformMobilityService$ServiceComponent handleInformMigrationResult
WARNING: Migration failure: Aborting migration: Timeout to receive migration response has expired
I have edited the host files on both computers and my settings are as follows:
slave1 (it has ip addess 10.0.0.3)
10.0.0.3 slave1
10.0.0.5 slave2
slave2 (it has ip addess 10.0.0.5)
10.0.0.5 slave2
10.0.0.3 slave1
The code is nearly the same as above and i have passed the following arguments in netbeans
Arguments for slave1
-gui -platform-id slave1 -services jade.core.mobility.AgentMobilityService;jade.core.migration.InterPlatformMobilityService
Arguments for slave2
-gui -platform-id slave2 -services jade.core.mobility.AgentMobilityService;jade.core.migration.InterPlatformMobilityService
jade & jipms are installed on both machines. Btw i have also tried to put 127.0.0.1 instead of the machine ip. i still the same problem where agent is not migrating. Thanks in advance for your help.
A timeout can mean a couple of things: (a) There is no service listening on the remote end (b) there was a firewall issue (c) the remote service somehow rejected the request. We will need the logs on slave2 to find out what the issue is. Please post those logs as well. Also, make sure you see slave1 and slave2 respectively on Jade GUIs (refer to the caveats section above).
Here is the log when running jade with the arguments, that is, when the service is started on slave 2:
Feb 21, 2012 11:40:42 PM jade.core.Runtime beginContainer
INFO: ———————————-
This is JADE 4.1.1 – revision 6532 of 2011/11/18 16:21:34
downloaded in Open Source, under LGPL restrictions,
at http://jade.tilab.com/
—————————————-
Retrieving CommandDispatcher for platform slave2
Feb 21, 2012 11:40:42 PM jade.imtp.leap.LEAPIMTPManager initialize
INFO: Listening for intra-platform commands on address:
- jicp://10.0.0.5:1099
Feb 21, 2012 11:40:42 PM jade.core.BaseService init
INFO: Service jade.core.management.AgentManagement initialized
Feb 21, 2012 11:40:42 PM jade.core.BaseService init
INFO: Service jade.core.messaging.Messaging initialized
Feb 21, 2012 11:40:42 PM jade.core.BaseService init
INFO: Service jade.core.resource.ResourceManagement initialized
Feb 21, 2012 11:40:42 PM jade.core.BaseService init
INFO: Service jade.core.mobility.AgentMobility initialized
Feb 21, 2012 11:40:42 PM jade.core.BaseService init
INFO: Service jade.core.migration.InterPlatformMobility initialized
Feb 21, 2012 11:40:42 PM jade.core.migration.InterPlatformMobilityService init
WARNING: AGENTS_PATH property not set, using C:\Users\Priesh\Documents\NetBeansProjects\MobileAgent5\jarManager\ directory for jar agents
Feb 21, 2012 11:40:42 PM jade.core.migration.InterPlatformMobilityService init
INFO: jade.core.migration.InterPlatformMobilityService initialized
Feb 21, 2012 11:40:42 PM jade.mtp.http.HTTPServer
INFO: HTTP-MTP Using XML parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
Feb 21, 2012 11:40:42 PM jade.core.messaging.MessagingService boot
INFO: MTP addresses:
http://slave2:7778/acc
Feb 21, 2012 11:40:42 PM jade.core.AgentContainerImpl joinPlatform
INFO: ————————————–
Agent container Main-Container@10.0.0.5 is ready.
——————————————–
Btw, i have started the service on both machines and disabled firewall.
Hello Recluze, I have got the agent working. I did not have the same version of jipms on the other device and id didnt work when i use ams@slave2. It works with amm@slave2 though.
Now i want to have the agent update a database on another host. I can do it on my machine by creating an agent and it works fine(intra-platform). How do i make the agent update a database on another host? Is it part of behaviours?
Hi there, i managed to get the database to update. The db update code should be on slave2 itself. Could you tell me how i could send the variables from slave1 to slave2 using agent? For the time being, the variables are hard coded on the db update codes on slave2. I want to send my own variables from slave1 to slave2. How do i do this using jade agents? Thanks.
if i run this code in netbeans means what was the main method & Argument..
Hi frendz,
It is useful. if u ppl present any video tutorial in this blog its very useful for beginners for creating and installing add-on services.
Thanks in advance,
Srinivas….