I my name is Vidar and I am trying to use JADE for the message flow in robocode. It is more of a project, just to find out how this works. The problem is that it is not possible to send information from a JADE agent to a robocode agent. When the robocode agent starts it creates its JADE agent counterpart. It is no problem to send objects to the JADE agent from robocode using putO2AObject, but trying to communicate from JADE to robocode seems to be impossible. I have sent an argument object when creating the JADE agent. But when trying to parse the object into its original form it protests.
Agent container Container-2@VIDARLTNEW is ready.
.Hallo! Soldier-agent SoldierRobot (2)@VIDARLTNEW:1099/JADE is ready.
*** Uncaught Exception for agent SoldierRobot (2) ***
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contr
act
at exercise.Soldier.setup(Soldier.java:26)
at jade.core.Agent$ActiveLifeCycle.init(Agent.java:1452)
at jade.core.Agent.run(Agent.java:1398)
at java.lang.Thread.run(Unknown Source)
ERROR: Agent SoldierRobot (2) died without being properly terminated !!!
Code from class Soldier (JADE agent): ***********
public class Soldier extends Agent{
privatestaticfinallongserialVersionUID=1L;privateContractcontract;// Put Agent initializations hereprotectedvoidsetup(){// Printout a welcome messageSystem.out.println("Hallo!Soldier-agent"+getAID().getName()+"isready.");// Initial valuesObjectargs[]=getArguments();contract=(Contract)args[0];********************THISISTHEPROBLEM**********************// Accept objects through the object-to-agent communication// channel, with a maximum size of 10 queued objectssetEnabledO2ACommunication(true,10);// Register the soldier-hiring service in the yellow pagesDFAgentDescriptiondfd=newDFAgentDescription();dfd.setName(getAID());ServiceDescriptionsd=newServiceDescription();sd.setType("soldier-available");sd.setName("JADE-soldier-trading");dfd.addServices(sd);try{DFService.register(this,dfd);}catch(FIPAExceptionfe){fe.printStackTrace();}addBehaviour(newOfferRequestsServer());addBehaviour(newOfferAcceptedServer());addBehaviour(newRobotMessageServer());}etc.
Code from class SoldierRobot: ***********
public class SoldierRobot extends TeamRobot {
// Variables for JADE controlprivatejade.core.Runtimert;privatejade.wrapper.ContainerControllercc;privatejade.wrapper.AgentControllerac;privateContractcontract;publicvoidrun(){// Start JADE AGENT herestartJADE();// Setup Robot here while(true){ahead(100);setTurnRadarRight(360);turnLeft(45);execute();}}publicvoidstartJADE(){rt=jade.core.Runtime.instance();jade.core.Profilep=newjade.core.ProfileImpl();cc=rt.createAgentContainer(p);contract=newContract();try{ac=cc.createNewAgent(getName(),"exercise.Soldier",newObject[]{contract});*******contractissenttoJADEhere********ac.start();}catch(StaleProxyExceptione){// TODO Auto-generated catch blocke.printStackTrace();}}
Hope someone can help me!
Vidar Engmo
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is really hard to tell, especially when I cannot see how the Contract is declared. Anyways, I guess the problem (without knowing for sure) that the problem lies in:
Object args[] = getArguments();
If this is arguments like the ones for e.g. 'public static void main(String[] args)', then your 'args' will be Strings, not Contracts. Then you are allowed to assign the define args[] as Objects with the line above, as String are Objects.
But when we get to this line:
contract = (Contract)args[0];
.. then it will be a problem, as it does not make sense to typecast a String to a Contract.
The solution for your problem might be to serialize your Contract object into a string, e.g. using ByteArrayOutputStream and ObjectOutputStream (for outputting the Contract), and then put this into your String for arg[0]. Then you replace your 'contract = (Contract)args[0];' with a "decoder" using the oposite technique for translating a string into a Contract using ByteArrayInputStream and ObjectInputStream.
So in short. If your args infact are Strings (you should check this), then you should code your Contract object to a String for the arg[0], and then decode the String to a Contract on the other side.
Hope this makes sense?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The whole point was to send a reference to a object. So that the Robocode and the JADE agent could share a memory space. I have tried setting up a test. This test works fine. No changes in Soldier.java.. And it works, I can use it as a refernce and both classes kan change the variables within. So what happens, in the real case the object is turned into a string, and in the test case it is not.
Now I understand what you are trying to do. I am not sure if you receive a String as arg[0] from the Robocode agent you listed in your previous message, as you received this error message:
*** Uncaught Exception for agent SoldierRobot (2) ***
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contract at exercise
This tells you that you try to typecast exercise.Contract into exercise.Contract which cannot be done. Atually, this should be possible to do. Perhaps the Contract needs to implement java.io.Serializable?
Also, as this is a problem with JADE, I would get help from the JADE developers, and ask them why to get the:
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contract at exercise
.. when you are typecasting between the same class?
Have you tried to clean and rebuild your stuff? It might be a trivial building/runtime problem?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi Vidar,
Did you manage to develop a competitive JADE agent for robocode?
I am asking because I also aim to start such a small project...
Thank you,
Nikos
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I my name is Vidar and I am trying to use JADE for the message flow in robocode. It is more of a project, just to find out how this works. The problem is that it is not possible to send information from a JADE agent to a robocode agent. When the robocode agent starts it creates its JADE agent counterpart. It is no problem to send objects to the JADE agent from robocode using putO2AObject, but trying to communicate from JADE to robocode seems to be impossible. I have sent an argument object when creating the JADE agent. But when trying to parse the object into its original form it protests.
Agent container Container-2@VIDARLTNEW is ready.
.Hallo! Soldier-agent SoldierRobot (2)@VIDARLTNEW:1099/JADE is ready.
*** Uncaught Exception for agent SoldierRobot (2) ***
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contr
act
at exercise.Soldier.setup(Soldier.java:26)
at jade.core.Agent$ActiveLifeCycle.init(Agent.java:1452)
at jade.core.Agent.run(Agent.java:1398)
at java.lang.Thread.run(Unknown Source)
ERROR: Agent SoldierRobot (2) died without being properly terminated !!!
Code from class Soldier (JADE agent): ***********
public class Soldier extends Agent{
Code from class SoldierRobot: ***********
public class SoldierRobot extends TeamRobot {
Hope someone can help me!
Vidar Engmo
Hi Vidar,
It is really hard to tell, especially when I cannot see how the Contract is declared. Anyways, I guess the problem (without knowing for sure) that the problem lies in:
Object args[] = getArguments();
If this is arguments like the ones for e.g. 'public static void main(String[] args)', then your 'args' will be Strings, not Contracts. Then you are allowed to assign the define args[] as Objects with the line above, as String are Objects.
But when we get to this line:
contract = (Contract)args[0];
.. then it will be a problem, as it does not make sense to typecast a String to a Contract.
The solution for your problem might be to serialize your Contract object into a string, e.g. using ByteArrayOutputStream and ObjectOutputStream (for outputting the Contract), and then put this into your String for arg[0]. Then you replace your 'contract = (Contract)args[0];' with a "decoder" using the oposite technique for translating a string into a Contract using ByteArrayInputStream and ObjectInputStream.
So in short. If your args infact are Strings (you should check this), then you should code your Contract object to a String for the arg[0], and then decode the String to a Contract on the other side.
Hope this makes sense?
The whole point was to send a reference to a object. So that the Robocode and the JADE agent could share a memory space. I have tried setting up a test. This test works fine. No changes in Soldier.java.. And it works, I can use it as a refernce and both classes kan change the variables within. So what happens, in the real case the object is turned into a string, and in the test case it is not.
TEST CODE ************
public class Mytest02 {
}
**** Contract code *******
public class Contract {
}
Now I understand what you are trying to do. I am not sure if you receive a String as arg[0] from the Robocode agent you listed in your previous message, as you received this error message:
*** Uncaught Exception for agent SoldierRobot (2) ***
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contract at exercise
This tells you that you try to typecast exercise.Contract into exercise.Contract which cannot be done. Atually, this should be possible to do. Perhaps the Contract needs to implement java.io.Serializable?
Also, as this is a problem with JADE, I would get help from the JADE developers, and ask them why to get the:
java.lang.ClassCastException: exercise.Contract cannot be cast to exercise.Contract at exercise
.. when you are typecasting between the same class?
Have you tried to clean and rebuild your stuff? It might be a trivial building/runtime problem?
Hi Vidar,
Did you manage to develop a competitive JADE agent for robocode?
I am asking because I also aim to start such a small project...
Thank you,
Nikos