Wednesday, July 29, 2009

XMPP on Android using Smack

I just went through the experience of running XMPP on Android, using the excellent Smack library. I take very little credit for getting it working, and just wanted to document my research in one place. The end result: XMPP running on Android SDK 1.5, using Smack 3.0.4 (svn revision 10869), including full support for bundled extensions. Note that at the time of writing, Smack 3.1.0 is available, but 3.0.4 was sufficient for my needs.

The first useful post I found was from Davanum Srinivas, found here. I had mixed results, and looked for a more source-level approach.

Reading through the comments, I found a link to Peter Neubauer's post here. The smackdiff file was exactly what I was looking for.

To apply the patch and build your own .jar, you'll need three tools installed: svn, diff, and ant. Looking at the .diff, the patch is against revision 10869 of the smack repository: http://svn.igniterealtime.org/svn/repos/smack/trunk. I checked out the source and applied the patch like this:

$ svn co -r 10869 \
     http://svn.igniterealtime.org/svn/repos/smack/trunk smack-android
$ cd smack-android/source
$ patch -p0 -i /path/to/smack.diff
$ cd ../build
$ ant
$ cd ../target

If all went well, you should see smack.jar and smackx.jar, and a few others. These .jar's should work on android, but there's one more catch. My application is using the MultiUserChat extension. The smack extensions are loaded based on a file in smack.jar's META-INF directory. So, when I build my .apk, I simply copied the contents of both smack.jar/META-INF and smackx.jar/META-INF into my apk's META-INF, and everything worked!

Note that one important function of the patch is to remove SSL from Smack, so SSL will not work on this build.

An issue I have not yet worked through is how to automatically import the files from this META-INF directory. I am using Maven to build my .apk (using maven-android-plugin) and have not yet found the best practice for copying these files, so if you have ideas, please post them.

Many thanks to Peter Neubauer and the Smack/Android teams for their work!

20 comments:

  1. Thanks for pointing this out, will certainly look into using the extension fix, as I use the patched smack right now in the Android client for www.linkedprocess.org.

    ReplyDelete
  2. Ben,

    Thanks for the step by step instruction post. I am also thinking of using MUC. I wonder if you have your app published yet. If it is I want to check it out. Are you also planning to use jingle? It seems that google voice is a different creature and there is room for jingle in android.

    win

    ReplyDelete
  3. With a Java project I'm able to connect to gmail but when using this patch in the android emulator I'm getting: E/AndroidRuntime( 454): java.lang.IllegalStateException: Not connected to server.

    Do I need to do anything special to make it work in the emulator?

    Thanks

    ReplyDelete
  4. Not that I'm aware of.. I've been using Smack both in the emulator and on a few devices with no problem. Are you sure you can connect to other servers? Also make sure you're using Smack correctly. You need to open the connection before issuing a login, for example.

    ReplyDelete
  5. Ben, will there eventually be a way to enable SSL again? What are the limitations that preclude Android from supporting SSL? Is a difference in implementation from what the Smack API source code expects or is the implementation missing?

    ReplyDelete
  6. Ben, or anyone, can you send me the smack.jar with patch applied. I am having trouble understanding how to apply patch. thanks

    ReplyDelete
  7. Hi, did you get a NullPointer exception while trying to join/unjoin/join again to the same chat room? (using Android 2.1 sdk and the smack library with the patch)

    I got the following:

    Caused by: java.lang.NullPointerException
    at org.jivesoftware.smackx.muc.MultiUserChat$1.connectionCreated(MultiUserChat.java:84)
    at org.jivesoftware.smack.XMPPConnection.initConnection(XMPPConnection.java:957)
    at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:904)
    at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1415)

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. When I tried to login to talk.google.com, my application crashed.I think it should be the problem of SSL connection. Can you email me the patched smack jars without SSL certificates ? cuz I am not a linux user, I am not familiar with Linux. nilaile8@gmail.com
    THX
    P.S: I am using smack 3.1.0

    ReplyDelete
  10. Thanks for the great post! I'm also among those struggling to get Smack to work on Android. I'd appreciate it if you could send a copy of your smack.jar to mobilekid7@googlemail.com. Thank you!

    ReplyDelete
  11. Yet another programmer struggling to get smack working on Android, please post the patched smack.jar to jmuna@avantiplc.com

    ReplyDelete
  12. can I also get the same patched smack.jar please
    striker0207@gmail.com
    thanks in advance

    ReplyDelete
  13. I need the proxy feature to run into emulator, so I cant use the fixed jar... I hope this will be solved!!

    ReplyDelete
  14. Thanks for this great post! I followed your instructions but am still getting "Keystore" errors:

    05-26 20:31:03.801: WARN/System.err(402): java.security.KeyStoreException: KeyStore jks implementation not found
    05-26 20:31:03.811: WARN/System.err(402): at java.security.KeyStore.getInstance(KeyStore.java:142)
    05-26 20:31:03.811: WARN/System.err(402): at org.jivesoftware.smack.ServerTrustManager.(ServerTrustManager.java:61)
    05-26 20:31:03.811: WARN/System.err(402): at org.jivesoftware.smack.XMPPConnection.proceedTLSReceived(XMPPConnection.java:1246)
    05-26 20:31:03.811: WARN/System.err(402): at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:313)
    05-26 20:31:03.821: WARN/System.err(402): at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:44)
    05-26 20:31:03.821: WARN/System.err(402): at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:76)
    05-26 20:31:15.712: WARN/System.err(402): java.io.EOFException: no more data available - expected end tag to close start tag from line 1, parser stopped on END_TAG seen ...... @1:784
    05-26 20:31:15.722: WARN/System.err(402): at org.xmlpull.mxp1.MXParser.fillBuf(MXParser.java:3035)
    05-26 20:31:15.722: WARN/System.err(402): at org.xmlpull.mxp1.MXParser.more(MXParser.java:3046)
    05-26 20:31:15.722: WARN/System.err(402): at org.xmlpull.mxp1.MXParser.nextImpl(MXParser.java:1144)
    05-26 20:31:15.732: WARN/System.err(402): at org.xmlpull.mxp1.MXParser.next(MXParser.java:1093)
    05-26 20:31:15.732: WARN/System.err(402): at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:368)
    05-26 20:31:15.732: WARN/System.err(402): at org.jivesoftware.smack.PacketReader.access$000(PacketReader.java:44)
    05-26 20:31:15.742: WARN/System.err(402): at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:76)
    ....

    Have you seen this?
    Thanks!
    shiri

    ReplyDelete
  15. Hey could you please upload the patch smack jar file. Thank you

    ReplyDelete
  16. Please upload the smack.jar file...thx :-)

    ReplyDelete
  17. Shiri,

    I'm seeing the same JKS error. I can build and run fine with the smack.jar provided with Davanum's example, but file sharing is throwing an exception. I need to be able to build/debug my own source in order to track this down.

    Anyone had any luck with this? I did a fresh checkout of the appropriate version, patched it, etc. but no go.

    Bill

    ReplyDelete
  18. I'm also struggling with getting the smack working on android. I would be grateful if you send a copy of your smack.jar to lakshi.av@gmail.com

    Thanking you in advance

    ReplyDelete
  19. for all people , here is a patched version of smack working on Android

    http://code.google.com/p/asmack/

    ReplyDelete
  20. how to delete messag from inbox like hangout delete how it possible using java code.

    ReplyDelete