A GSOC 2014 project idea: Allow Smack to target Android and JavaSE

Version 13

    Summary: Smack should target Android and Java SE, therefore making aSmack obsolete. In order to achieve this goal, components of Smack need to be abstracted so that they can be impleted with Java SE APIs and their Android counterpart (if any). This abstraction also requires a modular build system.

    Used Technologies: Java, Gradle, Android, XMPP, Groovy

    Prerequisites: Knowledge of Java. Helpful: XMPP enthusiast and interest in designing elaborate build systems

     

    The aSmack build system ports Smack, a Java XMPP client library, to Android. While it is great to have a open source XMPP library for Android, maintaining aSmack is error prone, costly and time intensive job, because of the porting process.

     

    It would be ideal if only one codebase and build system could be used for Java *and* Android deployments of Smack. A single codebase allows for improvements and bug fixes to be available for both worlds. This would be a significant advantage compared to the current situation where patches have to be exchanged between aSmack and Smack.

     

    You need to identify the code parts that can be used on both, Java and Android. This is likely the majority of all Smack Code. Then we need to deal with the specifics of the target platform. For Smack this is in particular the XML parser and the SASL mechanisms, but also the zLib compression code and DNS SRV lookup related code (dnsjava).

     

    You will be provided with a git repository containing the current state of Smack. The first task would be to migrate the build system of Smack to gradle. At this stage you have to design a DSL for Smack's gradle build, similar to the one used by the Android's Gradle build tools [2,3]: SmackTarget + SmackFlavor = SmackVariant, where SmackTarget = (JavaSE|Android) and SmackFlavor = (minimal|default|experimental). A flavor is defined as SmackModule set. A gradle DSL defining SmackModules could look like this:

     

    SmackModules {

      disco {

        description "XEP-0030: Service Discovery"

      }

      caps {

        description "XEP-0115: EntityCapabilities"

        requires disco

      }

      muc {

        description "XEP-0045: Multi-User Chat"

        requires disco

      }

      pubsub {

         descritption "XEP-0060: Publish-Subscribe"

         requires disco

      }

      pep

        description "XEP-0163: Personal Eventing Protocol"

        requires pubsub, disco

      }

      bosh {

        description "XEP-0124: Bidirectional-streams Over Synchronous HTTP"

        dependencies {

            classpath 'com.kenai.jbosh:0.7.0'

        }

      }

    }

     

    Then, after Smack can be build with gradle, this system needs to get modularized. This includes:

    - Create a common interface for XML pull parsing that can be implemented by the various available parsers: Java StAX, XML PullParser 3, MX Parser on Android.

    - Research how SASL auth mechanisms, in particular SCRAM and the legacy DIGEST-MD5, can be used on Android with minimal dependencies on 3rd party libraries. aSmack uses Apache Harmony code for this at  the moment and therefore depends on harmony whereas only a small subset of the harmony code is actually used.

    - Create two build targets for a standard Java library and an Android library. The Android library needs to depend on dnsjava and Java7 compression.

     

    The gradle modules should define dependencies. For example the Java7 StAX parser requires at least Java7 or it needs to be supplied as jar, the dnsjava resolver code requires the dnsjava library. But there should also exist dependencies on other Smack modules. For example the Smack module for XEP-280 Message Carbons requires the module for XEP-297 Stanza Forwarding which requires the module for XEP-30 Service Discovery and also recommends to enable the module for XEP-203 Delayed Delivery. Just like the module for XEP-30 Service Discovery should recommend also the usage of the module XEP-115 Entity Capabilities.

     

    After this stage is finished, it should be possible to build Smack for Android and for Java.

     

    Now some code improvement can be done:

    - Smack currently logs errors (e.g. Exceptions) directly to stderr. Since this is not good practice, the log system should be configurable with pre-defined Log mechanisms for Java and Android (android.util.Log) deployments. Or simply use java.util.logging, since it's available on Android and Java.

    - The test suite of Smack should get reviewed. The unit tests are in good shape and are an essential part of ensuring the quality of Smack. The situation of the integration tests is different. Most of them are successful against an Openfire instance. The others should get temporary disabled until fixed.

    - In order to generate XML, Smack currently uses simple string concatenation. It would be ideal if a more robust way could be found, because it certain situations it's possible that the resulting XML code is not properly escaped. This can often be fixed by warping the String in a call to StringUtils.escapeForXML(). But this approach is error prone and not clean. A more reliable method would maybe invoke something like org.xmlpull.v1.XmlSerializer. But since Smack aims to be fast, it should be evaluated if a handwritten Serializer may be the better approach.

    - It would also be nice if we had a minimal Android XMPP Client application for testing purposes.

    - Merge the BOSH code [1] back as extra module.

     

    Finally, the resulting libraries should get deployed to maven central.

     

    Discussion about this GSOC project proposal: http://community.igniterealtime.org/thread/51292

     

    Footnotes:

    [1] http://fisheye.igniterealtime.org/browse/smack/branches/bosh/smack-bosh/src/main /java/org/jivesoftware/smack

    [2] http://tools.android.com/tech-docs/new-build-system

    [3] https://android.googlesource.com/platform/tools/build/+/master