Oct 28

Writing a gTalk (Jabber/XMPP) client in Java

Tag: Java, ProgrammingAbhijeet Maharana @ 12:17 am

Screenshot

From its Wikipedia entry, “Extensible Messaging and Presence Protocol (XMPP) is an open, XML-inspired protocol for near-real-time, extensible instant messaging (IM) and presence information (a.k.a. buddy lists). It is the core protocol of the Jabber Instant Messaging and Presence technology. The protocol is built to be extensible and other features such as Voice over IP and file transfer signaling have been added.”

There are a large number of XMPP server and client implementations and code libraries. We will use the Smack open source Java library to implement a simple client that can connect to any Jabber service. Google’s messaging service uses the same protocol and we will use it for the example.

Create a folder for your project. Create a “lib” subfolder.
Download the Smack library and extract the following files to the lib folder:

smack.jar

  • smackx.jar (for the extensions)
  • smackx-debug.jar (for the enhanced debugger)
    Debugger screenshots: 1 | 2 | 3 | 4

    As of this writing, the Smack API is in version 3.0.4 (build date: June 12, 2006). Create ChatClient.java and use the code snippets below for the methods of this class. You can also download the project files from the link at the end of this post.

    The code below shows how to connect to the gTalk service:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // import org.jivesoftware.smack.ConnectionConfiguration;
    // import org.jivesoftware.smack.XMPPConnection;
     
    ConnectionConfiguration config = 
    	new ConnectionConfiguration("talk.google.com", 
    					5222, 
    					"gmail.com");
    connection = new XMPPConnection(config);
    connection.connect();
    connection.login(your_username, your_password);


    “talk.google.com” is the host. 5222 is the port number and “gmail.com” is the service name. Although they are different here but usually, the service name is same as the hostname. Let us now get hold of the buddy list:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    // import org.jivesoftware.smack.Roster;
    // import org.jivesoftware.smack.RosterEntry;
     
    Roster roster = connection.getRoster();
    Collection<RosterEntry> entries = roster.getEntries();
     
    System.out.println("\n\n" + entries.size() + " buddy(ies):");
    for(RosterEntry r:entries)
    {
    	System.out.println(r.getUser());
    }


    We can also send a message to a buddy by using the Chat class:

    1
    2
    3
    4
    
    //import org.jivesoftware.smack.Chat;
     
    Chat chat = connection.getChatManager().createChat(to, this);
    chat.sendMessage(message);

    The first argument is quite obvious. The second argument is an instance of a class that implements the org.jivesoftware.smack.MessageListener interface. This listener receives incoming chat messages and calls the interface method

    1
    
     public void processMessage(Chat chat, Message message)

    to process the message. We can now disconnect from the messenger service:

    1
    
    connection.disconnect();

    Thus, we have a bare-bones Jabber client. The complete program looks like this. You can download the project with instructions on compiling and running it. It has a hard-coded username and password which will have to be changed. You will also need to enter the email address of your gTalk buddy before sending any message. The person you are trying to communicate with should already be in your buddy list.

  • 22 Responses to “Writing a gTalk (Jabber/XMPP) client in Java”

    1. chaitanya says:

      Hi Abhijeet

      I got the following error while running this program.

      In fact, I am getting this error from some other implementation also. Where could it went wrong?

      Exception in thread “main” Could not connect to talk.google.com:5222.: remote-server-timeout(504) Could not connect to talk.google.com:5222.
      — caused by: java.net.UnknownHostException: talk.google.com
      at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:823)
      at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1276)
      at ChatClient1.login(ChatClient1.java:25)
      at ChatClient1.main(ChatClient1.java:71)
      Nested Exception:
      java.net.UnknownHostException: talk.google.com
      at java.net.PlainSocketImpl.connect(Unknown Source)
      at java.net.SocksSocketImpl.connect(Unknown Source)
      at java.net.Socket.connect(Unknown Source)
      at java.net.Socket.connect(Unknown Source)
      at java.net.Socket.(Unknown Source)
      at java.net.Socket.(Unknown Source)
      at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:815)
      at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1276)
      at ChatClient1.login(ChatClient1.java:25)
      at ChatClient1.main(ChatClient1.java:71)

    2. Abhijeet Maharana says:

      Hi Chaitanya,
      Even though it doesn’t seem to be a problem with the program, I ran it again and was able to chat just fine.
      Problem seems to be with your internet connectivity. Are you able to ping talk.google.com?

    3. Abhijeet Maharana says:

      Chaitanya (via mail):
      =============

      Hi Abhi

      I am not able to resolve it.

      I am not able to connect to talk.google.com through my program.

      One reason could be I m trying from office as I don’t have net connection as of now at home.

      Still have to try.

      If you know the reason please let me know.

      Thank you,
      Chaitanya

    4. Abhijeet Maharana says:

      Can you ping talk.google.com from the command line?
      You are trying from office … then it could also be a proxy server issue.

      If you are using IE, go to Tools >> Internet Options >> Connections >> LAN Settings. See if there is a proxy server specified there. If not, there might be an automatic configuration script specified. Take a look at that script and see if you can figure out the proxy server being used.

      Also, check that talk.google.com is not blocked from your office. Some companies have their internal messaging solutions and block others.

    5. chaitanya says:

      Hi Abhi

      talk.google.com is accessible. It is not blocked yet :-)) from my office.( Infosys- bangalore)

      It is some proxy server issue. I will explore and let u know.

      Unfortunately, getting Net at my home is getting delayed to try these kinda things.

      Thank you,
      Chaitanya

    6. SMACK API - need help w sample ChatClient - BlackBerryForums.com : Your Number One BlackBerry Community says:

      [...] if you guys have all the necessary info itll go smoother.. Trying to load the sample from … Abhijeet Maharana » Writing a gTalk (Jabber/XMPP) client in Java getting the following errors… generics are not supported in -source 1.3 (try -source 1.5 to [...]

    7. James Murphy says:

      Hello, im trying to test this on a BlackBerry handheld. Have you any experience with J2ME or the
      BlackBerry JDE 4.3.0(BB JDE) ? I have posted the 2 errors im recieving from the BB JDE to the
      BlackBerry Forums.. http://www.blackberryforums.com/developer-forum/127332-smack-api-need-help-w-sample-chatclient.html

    8. Abhijeet Maharana says:

      Hi James,
      My *pure guess* below since I have no experience with Blackberry.

      Options:
      1. Try passing “-source 1.5″ parameter. You will need to look up the documentation for rapc.exe to figure out how to do that.

      2. Don’t use generics and for-each loop.

      public void displayBuddyList()
      {
      	Roster roster = connection.getRoster();
      	Collection entries = roster.getEntries();
       
      	System.out.println("\n\n" + entries.size() + " buddy(ies):");
      	Iterator i = entries.iterator();
       
      	while(i.hasNext())
      	{
      		RosterEntry r = (RosterEntry) i.next();
      		System.out.println(r.getUser());
      	}
      }

      Above code is not tested. You may need to fix minor issues.

      Do let me know if this fixes your issue.

    9. James Murphy says:

      Thanks, Ill check that out today.

      What are generics? and how do i addin the smack api libraries? I understand you dont have any experience
      with the BlackBerry JDE but, how would one addin the smack api using another IDE? I tried copying the .jar’s
      to the /bin folder to no avail. Thanks for your assistance.

      If you curious, I can assist you in loading the BlackBerry JDE and also a BlackBerry simulator handheld and
      you would be on your way to developing apps for blackberry. I have many many samples.. then, hopefully
      you could take me under your wing. I could use a mentor. :)

    10. Abhijeet Maharana says:

      Generics enable compile-time type checking for collections making them safer to use. http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html

      Most IDEs have something under project properties to add jars to the class path. Eclipse has a “build path” feature and once you add your jar here, it is passed to the compiler and runtime when the project is launched.

      Many thanks for the generous offer. I could definitely use some help if and when I start exploring blackberry development. I think I should start using a blackberry now! And I would rather have it the other way round: you as my mentor! If you use twitter, I am available at http://twitter.com/maharana

      Regards.

    11. James Murphy says:

      Consider this.. I have nearly zero experience with Java. I can get you up to speed with the BlackBerry
      JDE and then ill have to hand over the mentorship. ;)

    12. James Murphy says:

      I will give you the links for getting started with BlackBerry Dev using the BlackBerry JDE 4.3.0

      Download BlackBerry JDE 4.3.0 from http://na.blackberry.com/eng/developers/downloads/jde.jsp

      Download simulators and the BlackBerry Email and MDS Services Simulator Package 4.1.4,
      I use the 4.2.2 versions of the simulator. I prefer the 8300 series BlackBerry handhelds,
      http://na.blackberry.com/eng/developers/downloads/simulators.jsp

      once all this is loaded then make sure you have C:\Program Files\Research In Motion\BlackBerry JDE 4.3.0\bin
      in your path. Once you are this far we can continue with the training. :)

    13. James Murphy says:

      BTW I found an option to import .JAR files into a project. That must be it..

    14. Abhijeet Maharana says:

      I did try to download the Eclipse plugin. 200+ MB with a weird download method. I couldn’t use a download manager and it broke mid way :( Will try again tonight. Or go with the smaller JDE download. Good that you found that option. Let me know if you are able to get the chat client working.

    15. James Murphy says:

      I just use the BB JDE. I made the changes you suggested and im still getting exceptions, in strange places..

      Like ‘missing symbol’ on collections.. ect. ill post some output later..

    16. James Murphy says:

      here is the code..

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      
      import java.util.*;
      import java.io.*;
       
      import org.jivesoftware.smack.Chat;
      import org.jivesoftware.smack.packet.Message;
      import org.jivesoftware.smack.ConnectionConfiguration;
      import org.jivesoftware.smack.MessageListener;
      import org.jivesoftware.smack.Roster;
      import org.jivesoftware.smack.RosterEntry;
      import org.jivesoftware.smack.XMPPConnection;
      import org.jivesoftware.smack.XMPPException;
       
      public class ChatClient implements MessageListener
      {
           XMPPConnection connection;
       
             public void login(String userName, String password) throws XMPPException
             {
          	   ConnectionConfiguration config = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
                 connection = new XMPPConnection(config);
       
                 connection.connect();
                 connection.login(userName, password);
             }
       
             public void sendMessage(String message, String to) throws XMPPException
             {
          	   Chat chat = connection.getChatManager().createChat(to, this);
          	   chat.sendMessage(message);
             }
       
             public void displayBuddyList()
             {
          	   Roster roster = connection.getRoster();
          	   Collection entries = roster.getEntries();
       
          	   System.out.println("\n\n" + entries.size() + " buddy(ies):");
          	   Iterator i = entries.iterator();
       
          	   while(i.hasNext())
          	   {
          		   RosterEntry r = (RosterEntry) i.next();
          		   System.out.println(r.getUser());
          	   }
             }
       
             public void disconnect()
             {
          	   connection.disconnect();
             }
       
             public void processMessage(Chat chat, Message message) 
             {
          	   if(message.getType() == Message.Type.chat)
          		   System.out.println(chat.getParticipant() + " says: " + message.getBody());
             }
       
             public static void main(String args[]) throws XMPPException, IOException
             {
          	   // declare variables
                 ChatClient c = new ChatClient();
                 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                 String msg;
       
                 // turn on the enhanced debugger
                 XMPPConnection.DEBUG_ENABLED = true;
       
                 // provide your login information here
                 c.login("madnesstestuser", "password");
       
       
                 c.displayBuddyList();
                 System.out.println("-----");
                 System.out.println("Enter your message in the console.");
                 System.out.println("All messages will be sent to abhijeet.maharana");
                 System.out.println("-----\n");
       
                 while( !(msg=br.readLine()).equals("bye"))
                 {
              	   // your buddy's gmail address goes here
                     c.sendMessage(msg, "abhijeet.maharana@gmail.com");
                 }
       
                 c.disconnect();
                 System.exit(0);
             }
      }
    17. James Murphy says:

      here is the output..

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      
      Building ChatClient
      C:\Program Files\Research In Motion\BlackBerry JDE 4.3.0\bin\rapc.exe  -quiet import="..\..\..\..\..\Program Files\Research In Motion\BlackBerry JDE 4.3.0\lib\net_rim_api.jar";ChatClient\lib\smack.jar codename=ChatClient\ChatClient ChatClient\ChatClient.rapc warnkey=0x52424200;0x52435200;0x52525400 "C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java"
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:37: cannot find symbol
      symbol  : class Collection
      location: class ChatClient
              Collection entries = roster.getEntries();
              ^
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:40: cannot find symbol
      symbol  : class Iterator
      location: class ChatClient
        Iterator i = entries.iterator();
        ^
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:56: cannot access java.lang.Enum
      file java\lang\Enum.class not found
                    if(message.getType() == Message.Type.chat)
                                         ^
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:64: cannot find symbol
      symbol  : class BufferedReader
      location: class ChatClient
                     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                     ^
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:64: cannot find symbol
      symbol  : class BufferedReader
      location: class ChatClient
                     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                                             ^
      C:\Documents and Settings\jmu\Desktop\jbmJDE\JBM\ChatClient\CC\ChatClient.java:64: cannot find symbol
      symbol  : variable in
      location: class java.lang.System
                     BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
                                                                                        ^
      6 errors
      Error!: Error: java compiler failed: javac -source 1.3 -target 1.1 -g -O -d C:\DOCUME~1\jmu\LOCALS~1\Temp\rapc_555d6fe7.dir -bootcla ...
      Error while building project
    18. Abhijeet Maharana says:

      Can’t really be of any help here. Most likely, the runtime is different with a different API. But, I am merely *guessing* here. The blackberry forum will be a better place as you will get some definitive answers there.

      Regards,
      Abhijeet.

    19. kpbird says:

      Can I Transfer file using this library ?

    20. Abhijeet Maharana says:

      Hi,
      I did a quick search of the igniterealtime forums and came across this: http://www.igniterealtime.org/community/message/118501#118501

    21. Adriel Blog - Let’s share our passion » XMPP services says:

      [...] There are also Java based libraries that can be used for the custom Java client development such as http://abhijeetmaharana.com/blog/2007/10/28/writing-a-gtalk-jabberxmpp-client/ [...]

    22. Daniel says:

      I read similar article also named a gTalk (Jabber/XMPP) client in Java | Abhijeet Maharana, and it was completely different. Personally, I agree with you more, because this article makes a little bit more sense for me

    Leave a Reply