Manufacturers: Keep VM Namespaces Clean, M'kay?

When an Android application starts up in a new process, one of the first things that happens is that a bunch of classes become available to the application. Courtesy of some Dalvik VM magic, those classes are memory-mapped into our new process, so all running applications can share the same read-only copy of those class definitions.

In stock Android, these classes include your expected Android framework classes (e.g., android.*), third-party packages that are exposed in the SDK (e.g., org.apache.*), and some third-party packages that are used by the Android framework but, for whatever reason, are not exposed in the SDK proper.

The most notorious of this latter group also happens to be my all-time-favorite open source project name: the Legion of the Bouncy Castle (BC). BC provides the javax.crypto implementation used by Android. However, there are other classes and methods in BC outside the javax.crypto interfaces. These are not part of the Android SDK. In fact, as I understand it, Android does not have a complete implementation of BC, though I may be wrong about that.

If a developer attempts to include the BC JAR in her project, it may not work properly. The reason is that, unlike desktop or server Java, developers have no control over the classpath on Android. The net is that the firmware always wins. You try to use the BC classes from the JAR, and it even compiles, but at runtime it crashes with a VerifyError or other problems, because you are actually using the built-in BC implementation at runtime, not the one from the JAR.

This is frustrating to developers. The principle workaround is to migrate the code into some new package, whether using jarjar or by hand. In fact, the BC situation got so bad that somebody went and created Spongy Castle, a clone of BC in an org.spongycastle package, just to allow developers to have a complete and clean BC implementation that they can use.

However, AFAIK, no new packages have been added by the core Android team that cause this effect. So, we have the handful that, like BC, cause grief, but it is a manageable and fixed roster.

This is important. Any new such package that would be added might break a bunch of existing apps that are using code from that package already via their own JARs. In this respect, not only are classes and methods part of a public API, but so are the “white spaces” — the things that are not included are also part of the public API, insofar as backwards- and forwards- compatibilty is concerned.

Alas, not all device manufacturers think of things like this.

HTC appears to have bundled GSON into some of their devices, such as the Desire HD, MyTouch 4G, and Desire Z. Rather than only use GSON in some of their own apps as a JAR, they appear to be loading it into all VMs for all applications, breaking those apps that have their own (incompatible) copy of GSON.

Now, this problem was first reported a bit over a year ago, and with luck HTC has stopped this practice. With further luck, no other manufacturer will try doing this. With yet further luck, HTC will eventually update these devices to a new firmware where they have fixed this problem.

If a manufacturer really needs to add third-party code to the VM classes, it is incumbent upon the manufacturer to use jarjar or the equivalent and rename the code, to maintain compatibilty with other Android devices.

Want an expert opinion on your Android app architecture decisions? Perhaps Mark Murphy can help!