Appcelerator Titanium KrollDict fails to sanitize JSONObject.NULL values

If you’re developing an Appcelerator Titanium module for Android it’s possible that you’ll run into this exception (see bottom of post for full exception trace):

!!! Unable to convert unknown Java object class 'org.json.JSONObject$1' to Js value !!!

It took me a long time to track down the cause of this error, but essentially the issue is in the JNI layer, which passes native Java objects to the Javascript layer does not know how to handle a JSONObject.NULL value. The Titanium wrapper object KrollDict attempts to convert all non-native Java objects into native ones. JSONObject becomes a simple Map, JSONArray becomes an ArrayList and so on. However, the constructor fails to account for instances of the JSONObject.NULL object, which is not a simple primitive.

An easy work around would be to ensure the JSON objects that you’re passing around never have any true JSON null values in them. You can replace them with empty strings, or simply remove the key from the object altogether. This is ultimately the fix we went with. However, a simple two-line patch should solve this issue in the core Titanium code:

From 57868ea5b822468563d4a1be2adb901cce383f11 Mon Sep 17 00:00:00 2001
From: Tristan Waddington <tristan.waddington@gmail.com>
Date: Mon, 4 Jun 2012 14:24:15 -0700
Subject: [PATCH] Update the 'fromJSON' method of 'KrollDict' to map the
 'JSONObject.NULL' Object to a real Java null
 representation.
 
---
 android/titanium/src/java/org/appcelerator/kroll/KrollDict.java |    2 ++
 1 file changed, 2 insertions(+)
 
diff --git a/android/titanium/src/java/org/appcelerator/kroll/KrollDict.java b/android/titanium/src/java/org/appcelerator/kroll/KrollDict.java
index da29217..96017d6 100644
--- a/android/titanium/src/java/org/appcelerator/kroll/KrollDict.java
+++ b/android/titanium/src/java/org/appcelerator/kroll/KrollDict.java
@@ -56,6 +56,8 @@ public static Object fromJSON(Object value) {
 					values[i] = fromJSON(array.get(i));
 				}
 				return values;
+			} else if (value == JSONObject.NULL) {
+				return null;
 			}
 		} catch (JSONException e) {
 			Log.e(TAG, "Error parsing JSON", e);
-- 
1.7.10

I submitted a pull request to the titanium_mobile repository on GitHub, but all contributors are required to sign a Contributor License Agreement (CLA). Not a big deal, but I don’t expect to ever submit another patch to this project, so I’m not inclined to spend a day getting their dev environment bootstrapped and sign my life away for a two-line bug fix (yes, I wrote a passive-aggressive blog post instead).

Unfortunately, they don’t even seem interested in accepting the patch as a simple bug report so someone else can fix it:

If you’re trying to build a platform that’s meant to be developer focused, willful disinterest is not the best response. If you’re curious, here’s the raw patch file and the full exception:

Including ActionBarSherlock as a Git submodule

If you’re using the ActionBarSherlock library in your Android project you can easily stay up to date by including it as git submodule.

$ cd /path/to/project
 
# Initialize the submodule 
$ git submodule add https://github.com/JakeWharton/ActionBarSherlock
 
# Commit your changes
$ git commit -am "Added ActionBarSherlock submodule."
 
# Ignore local changes in the submodule directory
$ git status --ignore-submodules=dirty

To ignore changes to the submodule directory (in case permission or other changes are required) you can add the following to your .gitmodules file:

[submodule "ActionBarSherlock"]
	path = ActionBarSherlock
	url = https://github.com/JakeWharton/ActionBarSherlock
        ignore = dirty

Installing Jenkins on an Ubuntu Amazon EC2 instance

Note: This post was written over four years ago and may no longer work correctly. This post will remain published for posterity.

This tutorial assumes you have already created an Amazon EC2 instance and are able to ssh to it. In our case, we used the Quick Launch Wizard to spin up a 32-bit instance of Ubuntu Server Cloud Guest 11.10 (Oneiric Ocelot).

Once you have a running EC2 instance you’ll need to modify the instance’s security group to open up ports 22, 80 and 443.

The first thing I did was update the EC2 timezone to our local timezone:

$ sudo ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime

Install any version control systems you might like to use:

$ sudo apt-get install git

Then pretty much just follow the installation instructions from the Jenkins Wiki. I’ve copied the actual steps here for posterity.

Installing Jenkins:

$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ &gt; /etc/apt/sources.list.d/jenkins.list'
$ sudo aptitude update
 
# Note this will install the openjdk dependencies automatically!
$ sudo aptitude install jenkins

Setting up an Apache Proxy for port 80 -> 8080:

$ sudo aptitude install apache2
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http
$ sudo a2enmod vhost_alias
$ sudo a2dissite default
$ touch /etc/apache2/sites-available/jenkins

Use your favorite editor to update /etc/apache2/sites-available/jenkins with the following virtual host configuration:

<VirtualHost *:80>
	ServerAdmin webmaster@localhost
	ServerName ci.company.com
	ServerAlias ci
	ProxyRequests Off
	<Proxy *>
		Order deny,allow
		Allow from all
	</Proxy>
	ProxyPreserveHost on
	ProxyPass / http://localhost:8080/
</VirtualHost>

Enable the new jenkins virtual host and restart apache:

$ sudo a2ensite jenkins
$ sudo apache2ctl restart

Jenkins should now be live and accessible from port 80! Now you can begin configuring Jenkins to your liking. I’ll follow-up with a post highlighting our Jenkins configuration. For now, here are the plugins we’ve chosen to install:

  • Green Balls
  • Post build task
  • Instant Messaging Plugin
  • IRC Plugin
  • Rake plugin
  • Git Plugin
  • Github Plugin
  • GitHub API Plugin
  • Github OAuth Plugin

Delete Branch From Remote Git Repo [Assembla]

Update: GitHub has an excellent tutorial on removing sensitive data from your GitHub repository.

We’ve just started using Git and Assembla at our office for version control and ticket tracking. Having never used any sort of version control before, this has been an interesting experience. It’s been a joy to work with so far, but there have definitely been some hurdles to overcome.

One issue we had was how to delete a branch that we had created that we no longer wanted to maintain. We had been playing around and had created several branches that we would not be maintaining. The important thing to remember is that both your local and remote repositories are two separate entities. So the branch must be deleted from all repositories to completely be rid of it.

Remote Branch

$ git push remotename :branchname

The key here being the colon preceding the branch name. The format being:

$ git push <repository> <refspec>

Where <refspec> is written:

<src>:<dst>

Pushing an empty <src> allows you to delete the <dst> ref from the remote repository.

Local Branch

$ git branch -D branchname

I stumbled upon the solution in this Assembla forum post.

We’re also starting to accumulate a fair amount of information on our staff wiki. You’re welcome to take a look if you’re into that sort of thing.