diff --git a/runtimes/google/ipc/jni/client.go b/runtimes/google/ipc/jni/client.go
index c55adff..a78c0ab 100644
--- a/runtimes/google/ipc/jni/client.go
+++ b/runtimes/google/ipc/jni/client.go
@@ -8,6 +8,7 @@
 	"strings"
 	"time"
 
+	"veyron/runtimes/google/jni/util"
 	"veyron2"
 	"veyron2/ipc"
 )
@@ -34,17 +35,17 @@
 	// Convert Java argument array into []string.
 	argStrs := make([]string, int(C.GetArrayLength(env, C.jarray(jArgs))))
 	for i := 0; i < len(argStrs); i++ {
-		argStrs[i] = goString(env, C.jstring(C.GetObjectArrayElement(env, jArgs, C.jsize(i))))
+		argStrs[i] = util.GoString(env, C.GetObjectArrayElement(env, jArgs, C.jsize(i)))
 	}
 	// Get argument instances that correspond to the provided method.
-	vdlPackagePath := strings.Join(strings.Split(goString(env, jPath), ".")[1:], "/")
+	vdlPackagePath := strings.Join(strings.Split(util.GoString(env, jPath), ".")[1:], "/")
 	getter, err := newArgGetter([]string{vdlPackagePath})
 	if err != nil {
 		return nil, err
 	}
 	mArgs := getter.FindMethod(method, len(argStrs))
 	if mArgs == nil {
-		return nil, fmt.Errorf("couldn't find method %s with %d args in VDL interface at path %q", method, len(argStrs), goString(env, jPath))
+		return nil, fmt.Errorf("couldn't find method %s with %d args in VDL interface at path %q", method, len(argStrs), util.GoString(env, jPath))
 	}
 	argptrs := mArgs.InPtrs()
 	if len(argptrs) != len(argStrs) {
@@ -58,7 +59,7 @@
 		}
 		// Remove the pointer from the argument.  Simply *argptr[i] doesn't work
 		// as argptr[i] is of type interface{}.
-		args[i] = derefOrDie(argptrs[i])
+		args[i] = util.DerefOrDie(argptrs[i])
 	}
 	// Process options.
 	options := []ipc.CallOpt{}
@@ -110,7 +111,7 @@
 	for i, resultptr := range resultptrs {
 		// Remove the pointer from the result.  Simply *resultptr doesn't work
 		// as resultptr is of type interface{}.
-		result := derefOrDie(resultptr)
+		result := util.DerefOrDie(resultptr)
 		var err error
 		jsonResults[i], err = json.Marshal(result)
 		if err != nil {
@@ -121,7 +122,7 @@
 	// Convert to Java array of C.jstring.
 	ret := C.NewObjectArray(env, C.jsize(len(jsonResults)), jStringClass, nil)
 	for i, result := range jsonResults {
-		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(jString(env, string(result))))
+		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(util.JStringPtr(env, string(result))))
 	}
 	return ret, nil
 }
diff --git a/runtimes/google/ipc/jni/dispatcher.go b/runtimes/google/ipc/jni/dispatcher.go
index f8fa818..a913b3b 100644
--- a/runtimes/google/ipc/jni/dispatcher.go
+++ b/runtimes/google/ipc/jni/dispatcher.go
@@ -6,6 +6,7 @@
 	"fmt"
 	"runtime"
 
+	"veyron/runtimes/google/jni/util"
 	"veyron2/ipc"
 	"veyron2/security"
 )
@@ -19,7 +20,7 @@
 // }
 import "C"
 
-func newJNIDispatcher(env *C.JNIEnv, jDispatcher C.jobject) (ipc.Dispatcher, error) {
+func newDispatcher(env *C.JNIEnv, jDispatcher C.jobject) (*dispatcher, error) {
 	// We cannot cache Java environments as they are only valid in the current
 	// thread.  We can, however, cache the Java VM and obtain an environment
 	// from it in whatever thread happens to be running at the time.
@@ -31,35 +32,35 @@
 	// dispatcher created below is garbage-collected (through the finalizer
 	// callback we setup below).
 	jDispatcher = C.NewGlobalRef(env, jDispatcher)
-	d := &jniDispatcher{
-		jVM:   jVM,
-		jDObj: jDispatcher,
+	d := &dispatcher{
+		jVM:         jVM,
+		jDispatcher: jDispatcher,
 	}
-	runtime.SetFinalizer(d, func(d *jniDispatcher) {
+	runtime.SetFinalizer(d, func(d *dispatcher) {
 		var env *C.JNIEnv
 		C.AttachCurrentThread(d.jVM, &env, nil)
 		defer C.DetachCurrentThread(d.jVM)
-		C.DeleteGlobalRef(env, d.jDObj)
+		C.DeleteGlobalRef(env, d.jDispatcher)
 	})
 
 	return d, nil
 }
 
-type jniDispatcher struct {
-	jVM   *C.JavaVM
-	jDObj C.jobject
+type dispatcher struct {
+	jVM         *C.JavaVM
+	jDispatcher C.jobject
 }
 
-func (d *jniDispatcher) Lookup(suffix string) (ipc.Invoker, security.Authorizer, error) {
+func (d *dispatcher) Lookup(suffix string) (ipc.Invoker, security.Authorizer, error) {
 	// Get Java environment.
 	var env *C.JNIEnv
 	C.AttachCurrentThread(d.jVM, &env, nil)
 	defer C.DetachCurrentThread(d.jVM)
 
 	// Call Java dispatcher's lookup() method.
-	lid := jMethodID(env, C.GetObjectClass(env, d.jDObj), "lookup", fmt.Sprintf("(%s)%s", stringSign, objectSign))
-	jObj := C.CallLookupMethod(env, d.jDObj, lid, jString(env, suffix))
-	if err := jExceptionMsg(env); err != nil {
+	lid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, d.jDispatcher), "lookup", fmt.Sprintf("(%s)%s", util.StringSign, util.ObjectSign)))
+	jObj := C.CallLookupMethod(env, d.jDispatcher, lid, C.jstring(util.JStringPtr(env, suffix)))
+	if err := util.JExceptionMsg(env); err != nil {
 		return nil, nil, fmt.Errorf("error invoking Java dispatcher's lookup() method: %v", err)
 	}
 	if jObj == nil {
@@ -67,7 +68,7 @@
 		// handling the object - this is not an error.
 		return nil, nil, nil
 	}
-	i, err := newJNIInvoker(env, d.jVM, jObj)
+	i, err := newInvoker(env, d.jVM, jObj)
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/runtimes/google/ipc/jni/invoker.go b/runtimes/google/ipc/jni/invoker.go
index 5835d86..0c9ba2a 100644
--- a/runtimes/google/ipc/jni/invoker.go
+++ b/runtimes/google/ipc/jni/invoker.go
@@ -7,6 +7,7 @@
 	"fmt"
 	"runtime"
 
+	"veyron/runtimes/google/jni/util"
 	"veyron2/ipc"
 	"veyron2/security"
 	"veyron2/verror"
@@ -33,17 +34,17 @@
 // }
 import "C"
 
-func newJNIInvoker(env *C.JNIEnv, jVM *C.JavaVM, jObj C.jobject) (ipc.Invoker, error) {
+func newInvoker(env *C.JNIEnv, jVM *C.JavaVM, jObj C.jobject) (*invoker, error) {
 	// Create a new Java VDLInvoker object.
-	cid := jMethodID(env, jVDLInvokerClass, "<init>", fmt.Sprintf("(%s)%s", objectSign, voidSign))
+	cid := C.jmethodID(util.JMethodIDPtr(env, jVDLInvokerClass, "<init>", fmt.Sprintf("(%s)%s", util.ObjectSign, util.VoidSign)))
 	jInvoker := C.CallNewInvokerObject(env, jVDLInvokerClass, cid, jObj)
-	if err := jExceptionMsg(env); err != nil {
+	if err := util.JExceptionMsg(env); err != nil {
 		return nil, fmt.Errorf("error creating Java VDLInvoker object: %v", err)
 	}
 	// Fetch the argGetter for the object.
-	pid := jMethodID(env, jVDLInvokerClass, "getImplementedServices", fmt.Sprintf("()%s", arraySign(stringSign)))
+	pid := C.jmethodID(util.JMethodIDPtr(env, jVDLInvokerClass, "getImplementedServices", fmt.Sprintf("()%s", util.ArraySign(util.StringSign))))
 	jPathArray := C.jobjectArray(C.CallGetInterfacePath(env, jInvoker, pid))
-	paths := goStringArray(env, jPathArray)
+	paths := util.GoStringArray(env, jPathArray)
 	getter, err := newArgGetter(paths)
 	if err != nil {
 		return nil, err
@@ -52,12 +53,12 @@
 	// created below is garbage-collected (through the finalizer callback we
 	// setup just below).
 	jInvoker = C.NewGlobalRef(env, jInvoker)
-	i := &jniInvoker{
+	i := &invoker{
 		jVM:       jVM,
 		jInvoker:  jInvoker,
 		argGetter: getter,
 	}
-	runtime.SetFinalizer(i, func(i *jniInvoker) {
+	runtime.SetFinalizer(i, func(i *invoker) {
 		var env *C.JNIEnv
 		C.AttachCurrentThread(i.jVM, &env, nil)
 		defer C.DetachCurrentThread(i.jVM)
@@ -66,13 +67,13 @@
 	return i, nil
 }
 
-type jniInvoker struct {
+type invoker struct {
 	jVM       *C.JavaVM
 	jInvoker  C.jobject
 	argGetter *argGetter
 }
 
-func (i *jniInvoker) Prepare(method string, numArgs int) (argptrs []interface{}, label security.Label, err error) {
+func (i *invoker) Prepare(method string, numArgs int) (argptrs []interface{}, label security.Label, err error) {
 	// NOTE(spetrovic): In the long-term, this method will return an array of
 	// []vom.Value.  This will in turn result in VOM decoding all input
 	// arguments into vom.Value objects, which we shall then de-serialize into
@@ -89,7 +90,7 @@
 	return
 }
 
-func (i *jniInvoker) Invoke(method string, call ipc.ServerCall, argptrs []interface{}) (results []interface{}, err error) {
+func (i *invoker) Invoke(method string, call ipc.ServerCall, argptrs []interface{}) (results []interface{}, err error) {
 	// NOTE(spetrovic): In the long-term, all input arguments will be of
 	// vom.Value type (see comments for Prepare() method above).  Through JNI,
 	// we will call Java functions that transform a serialized vom.Value into
@@ -107,9 +108,9 @@
 		err = fmt.Errorf("couldn't find VDL method %q with %d args", method, len(argptrs))
 	}
 	sCall := newServerCall(call, mArgs)
-	cid := jMethodID(env, jServerCallClass, "<init>", fmt.Sprintf("(%s)%s", longSign, voidSign))
-	jServerCall := C.CallNewServerCallObject(env, jServerCallClass, cid, ptrValue(sCall))
-	goRef(sCall) // unref-ed when jServerCall is garbage-collected
+	cid := C.jmethodID(util.JMethodIDPtr(env, jServerCallClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	jServerCall := C.CallNewServerCallObject(env, jServerCallClass, cid, C.jlong(util.PtrValue(sCall)))
+	util.GoRef(sCall) // unref-ed when jServerCall is garbage-collected
 
 	// Translate input args to JSON.
 	jArgs, err := i.encodeArgs(env, argptrs)
@@ -119,9 +120,9 @@
 	// Invoke the method.
 	const callSign = "Lcom/veyron2/ipc/ServerCall;"
 	const replySign = "Lcom/veyron/runtimes/google/VDLInvoker$InvokeReply;"
-	mid := jMethodID(env, C.GetObjectClass(env, i.jInvoker), "invoke", fmt.Sprintf("(%s%s[%s)%s", stringSign, callSign, stringSign, replySign))
-	jReply := C.CallInvokeMethod(env, i.jInvoker, mid, jString(env, camelCase(method)), jServerCall, jArgs)
-	if err := jExceptionMsg(env); err != nil {
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, i.jInvoker), "invoke", fmt.Sprintf("(%s%s[%s)%s", util.StringSign, callSign, util.StringSign, replySign)))
+	jReply := C.CallInvokeMethod(env, i.jInvoker, mid, C.jstring(util.JStringPtr(env, util.CamelCase(method))), jServerCall, jArgs)
+	if err := util.JExceptionMsg(env); err != nil {
 		return nil, fmt.Errorf("error invoking Java method %q: %v", method, err)
 	}
 	// Decode and return results.
@@ -130,13 +131,13 @@
 
 // encodeArgs JSON-encodes the provided argument pointers, converts them into
 // Java strings, and returns a Java string array response.
-func (*jniInvoker) encodeArgs(env *C.JNIEnv, argptrs []interface{}) (C.jobjectArray, error) {
+func (*invoker) encodeArgs(env *C.JNIEnv, argptrs []interface{}) (C.jobjectArray, error) {
 	// JSON encode.
 	jsonArgs := make([][]byte, len(argptrs))
 	for i, argptr := range argptrs {
 		// Remove the pointer from the argument.  Simply *argptr doesn't work
 		// as argptr is of type interface{}.
-		arg := derefOrDie(argptr)
+		arg := util.DerefOrDie(argptr)
 		var err error
 		jsonArgs[i], err = json.Marshal(arg)
 		if err != nil {
@@ -147,19 +148,19 @@
 	// Convert to Java array of C.jstring.
 	ret := C.NewObjectArray(env, C.jsize(len(argptrs)), jStringClass, nil)
 	for i, arg := range jsonArgs {
-		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(jString(env, string(arg))))
+		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(util.JStringPtr(env, string(arg))))
 	}
 	return ret, nil
 }
 
 // decodeResults JSON-decodes replies stored in the Java reply object and
 // returns an array of Go reply objects.
-func (i *jniInvoker) decodeResults(env *C.JNIEnv, method string, numArgs int, jReply C.jobject) ([]interface{}, error) {
+func (i *invoker) decodeResults(env *C.JNIEnv, method string, numArgs int, jReply C.jobject) ([]interface{}, error) {
 	// Unpack the replies.
-	results := jStringArrayField(env, jReply, "results")
-	hasAppErr := jBoolField(env, jReply, "hasApplicationError")
-	errorID := jStringField(env, jReply, "errorID")
-	errorMsg := jStringField(env, jReply, "errorMsg")
+	results := util.JStringArrayField(env, jReply, "results")
+	hasAppErr := util.JBoolField(env, jReply, "hasApplicationError")
+	errorID := util.JStringField(env, jReply, "errorID")
+	errorMsg := util.JStringField(env, jReply, "errorMsg")
 
 	// Get result instances.
 	mArgs := i.argGetter.FindMethod(method, numArgs)
@@ -189,7 +190,7 @@
 func resultsWithError(resultptrs []interface{}, err error) []interface{} {
 	ret := make([]interface{}, len(resultptrs)+1)
 	for i, resultptr := range resultptrs {
-		ret[i] = derefOrDie(resultptr)
+		ret[i] = util.DerefOrDie(resultptr)
 	}
 	ret[len(resultptrs)] = err
 	return ret
diff --git a/runtimes/google/ipc/jni/jni.go b/runtimes/google/ipc/jni/jni.go
index 204a9f0..36c5b90 100644
--- a/runtimes/google/ipc/jni/jni.go
+++ b/runtimes/google/ipc/jni/jni.go
@@ -3,46 +3,47 @@
 package jni
 
 import (
-	"fmt"
 	"io"
 	"time"
+	"unsafe"
 
+	"veyron/runtimes/google/jni/util"
 	"veyron2"
 	ctx "veyron2/context"
 	"veyron2/ipc"
 	"veyron2/rt"
 )
 
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
 // #include <stdlib.h>
-// #include <jni.h>
 import "C"
 
 var (
-	// Global reference for com.veyron2.ipc.VeyronException class.
-	jVeyronExceptionClass C.jclass
 	// Global reference for com.veyron.runtimes.google.ipc.Runtime$ServerCall class.
 	jServerCallClass C.jclass
 	// Global reference for com.veyron.runtimes.google.ipc.VDLInvoker class.
 	jVDLInvokerClass C.jclass
-	// Global reference for java.lang.Throwable class.
-	jThrowableClass C.jclass
-	// Global reference for java.lang.String class.
-	jStringClass C.jclass
 	// Global reference for java.io.EOFException class.
 	jEOFExceptionClass C.jclass
+	// Global reference for java.lang.String class.
+	jStringClass C.jclass
 )
 
-//export Java_com_veyron_runtimes_google_Runtime_nativeGlobalInit
-func Java_com_veyron_runtimes_google_Runtime_nativeGlobalInit(env *C.JNIEnv, jRuntime C.jclass) {
+// Init initializes the JNI code with the given Java environment. This method
+// must be called from the main Java thread.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java environment is passed in an empty
+// interface and then cast into the package-local environment type.
+func Init(jEnv interface{}) {
+	env := (*C.JNIEnv)(unsafe.Pointer(util.PtrValue(jEnv)))
 	// Cache global references to all Java classes used by the package.  This is
 	// necessary because JNI gets access to the class loader only in the system
 	// thread, so we aren't able to invoke FindClass in other threads.
-	jVeyronExceptionClass = jFindClassOrDie(env, "com/veyron2/ipc/VeyronException")
-	jServerCallClass = jFindClassOrDie(env, "com/veyron/runtimes/google/Runtime$ServerCall")
-	jVDLInvokerClass = jFindClassOrDie(env, "com/veyron/runtimes/google/VDLInvoker")
-	jThrowableClass = jFindClassOrDie(env, "java/lang/Throwable")
-	jStringClass = jFindClassOrDie(env, "java/lang/String")
-	jEOFExceptionClass = jFindClassOrDie(env, "java/io/EOFException")
+	jServerCallClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/Runtime$ServerCall"))
+	jVDLInvokerClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/VDLInvoker"))
+	jEOFExceptionClass = C.jclass(util.JFindClassPtrOrDie(env, "java/io/EOFException"))
+	jStringClass = C.jclass(util.JFindClassPtrOrDie(env, "java/lang/String"))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeInit
@@ -52,204 +53,158 @@
 		var err error
 		r, err = rt.New()
 		if err != nil {
-			jThrowV(env, err)
+			util.JThrowV(env, err)
 		}
 	}
-	goRef(&r)
-	return ptrValue(&r)
+	util.GoRef(&r) // Un-refed when the Java Runtime object is finalized.
+	return C.jlong(util.PtrValue(&r))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeNewClient
 func Java_com_veyron_runtimes_google_Runtime_nativeNewClient(env *C.JNIEnv, jRuntime C.jobject, goRuntimePtr C.jlong, timeoutMillis C.jlong) C.jlong {
-	r := (*veyron2.Runtime)(ptr(goRuntimePtr))
-	if r == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go runtime with pointer: %d", int(goRuntimePtr)))
-		return C.jlong(0)
-	}
+	r := (*veyron2.Runtime)(util.Ptr(goRuntimePtr))
 	options := []ipc.ClientOpt{}
 	if int(timeoutMillis) > 0 {
 		options = append(options, veyron2.CallTimeout(time.Duration(timeoutMillis)*time.Millisecond))
 	}
 	rc, err := (*r).NewClient(options...)
 	if err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return C.jlong(0)
 	}
 	c := newClient(rc)
-	goRef(c)
-	return ptrValue(c)
+	util.GoRef(c) // Un-refed when the Java Client object is finalized.
+	return C.jlong(util.PtrValue(c))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeNewServer
 func Java_com_veyron_runtimes_google_Runtime_nativeNewServer(env *C.JNIEnv, jRuntime C.jobject, goRuntimePtr C.jlong) C.jlong {
-	r := (*veyron2.Runtime)(ptr(goRuntimePtr))
-	if r == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go runtime with pointer: %d", int(goRuntimePtr)))
-		return C.jlong(0)
-	}
+	r := (*veyron2.Runtime)(util.Ptr(goRuntimePtr))
 	s, err := (*r).NewServer()
 	if err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return C.jlong(0)
 	}
-	goRef(&s)
-	return ptrValue(&s)
+	util.GoRef(&s) // Un-refed when the Java Server object is finalized.
+	return C.jlong(util.PtrValue(&s))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeGetClient
 func Java_com_veyron_runtimes_google_Runtime_nativeGetClient(env *C.JNIEnv, jRuntime C.jobject, goRuntimePtr C.jlong) C.jlong {
-	r := (*veyron2.Runtime)(ptr(goRuntimePtr))
-	if r == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go runtime with pointer: %d", int(goRuntimePtr)))
-		return C.jlong(0)
-	}
+	r := (*veyron2.Runtime)(util.Ptr(goRuntimePtr))
 	rc := (*r).Client()
 	c := newClient(rc)
-	goRef(c)
-	return ptrValue(c)
+	util.GoRef(c) // Un-refed when the Java Client object is finalized.
+	return C.jlong(util.PtrValue(c))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeNewContext
 func Java_com_veyron_runtimes_google_Runtime_nativeNewContext(env *C.JNIEnv, jRuntime C.jobject, goRuntimePtr C.jlong) C.jlong {
-	r := (*veyron2.Runtime)(ptr(goRuntimePtr))
-	if r == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go runtime with pointer: %d", int(goRuntimePtr)))
-		return C.jlong(0)
-	}
+	r := (*veyron2.Runtime)(util.Ptr(goRuntimePtr))
 	c := (*r).NewContext()
-	goRef(&c)
-	return ptrValue(&c)
+	util.GoRef(&c) // Un-refed when the Java context object is finalized.
+	return C.jlong(util.PtrValue(&c))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_nativeFinalize
 func Java_com_veyron_runtimes_google_Runtime_nativeFinalize(env *C.JNIEnv, jRuntime C.jobject, goRuntimePtr C.jlong) {
-	r := (*veyron2.Runtime)(ptr(goRuntimePtr))
-	if r != nil {
-		goUnref(r)
-	}
-}
-
-//export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeServe
-func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeServe(env *C.JNIEnv, jServer C.jobject, goServerPtr C.jlong, name C.jstring, dispatcher C.jobject) {
-	s := (*ipc.Server)(ptr(goServerPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go server with pointer: %d", int(goServerPtr)))
-		return
-	}
-	// Create a new Dispatcher
-	d, err := newJNIDispatcher(env, dispatcher)
-	if err != nil {
-		jThrowV(env, err)
-		return
-	}
-	if err := (*s).Serve(goString(env, name), d); err != nil {
-		jThrowV(env, err)
-		return
-	}
+	util.GoUnref((*veyron2.Runtime)(util.Ptr(goRuntimePtr)))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeListen
 func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeListen(env *C.JNIEnv, server C.jobject, goServerPtr C.jlong, protocol C.jstring, address C.jstring) C.jstring {
-	s := (*ipc.Server)(ptr(goServerPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go server with pointer: %d", int(goServerPtr)))
-		return nil
-	}
-	ep, err := (*s).Listen(goString(env, protocol), goString(env, address))
+	s := (*ipc.Server)(util.Ptr(goServerPtr))
+	ep, err := (*s).Listen(util.GoString(env, protocol), util.GoString(env, address))
 	if err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return nil
 	}
-	return jString(env, ep.String())
+	return C.jstring(util.JStringPtr(env, ep.String()))
+}
+
+//export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeServe
+func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeServe(env *C.JNIEnv, jServer C.jobject, goServerPtr C.jlong, name C.jstring, jDispatcher C.jobject) {
+	s := (*ipc.Server)(util.Ptr(goServerPtr))
+	d, err := newDispatcher(env, jDispatcher)
+	if err != nil {
+		util.JThrowV(env, err)
+		return
+	}
+	if err := (*s).Serve(util.GoString(env, name), d); err != nil {
+		util.JThrowV(env, err)
+		return
+	}
+}
+
+//export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeGetPublishedNames
+func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeGetPublishedNames(env *C.JNIEnv, jServer C.jobject, goServerPtr C.jlong) C.jobjectArray {
+	names, err := (*(*ipc.Server)(util.Ptr(goServerPtr))).Published()
+	if err != nil {
+		util.JThrowV(env, err)
+		return nil
+	}
+	ret := C.NewObjectArray(env, C.jsize(len(names)), jStringClass, nil)
+	for i, name := range names {
+		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(util.JStringPtr(env, string(name))))
+	}
+	return ret
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeStop
 func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeStop(env *C.JNIEnv, server C.jobject, goServerPtr C.jlong) {
-	s := (*ipc.Server)(ptr(goServerPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go server with pointer: %d", int(goServerPtr)))
-		return
-	}
+	s := (*ipc.Server)(util.Ptr(goServerPtr))
 	if err := (*s).Stop(); err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return
 	}
 }
 
-//export Java_com_veyron_runtimes_google_Runtime_00024Server_nativeFinalize
-func Java_com_veyron_runtimes_google_Runtime_00024Server_nativeFinalize(env *C.JNIEnv, server C.jobject, goServerPtr C.jlong) {
-	s := (*ipc.Server)(ptr(goServerPtr))
-	if s != nil {
-		goUnref(s)
-	}
+//export Java_com_veyron_runtimes_google_jni_Runtime_00024Server_nativeFinalize
+func Java_com_veyron_runtimes_google_jni_Runtime_00024Server_nativeFinalize(env *C.JNIEnv, server C.jobject, goServerPtr C.jlong) {
+	util.GoUnref((*ipc.Server)(util.Ptr(goServerPtr)))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Client_nativeStartCall
 func Java_com_veyron_runtimes_google_Runtime_00024Client_nativeStartCall(env *C.JNIEnv, jClient C.jobject, goClientPtr C.jlong, jContext C.jobject, name C.jstring, method C.jstring, jsonArgs C.jobjectArray, jPath C.jstring, timeoutMillis C.jlong) C.jlong {
-	c := (*client)(ptr(goClientPtr))
-	if c == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go client with pointer: %d", int(goClientPtr)))
-		return C.jlong(0)
-	}
-	call, err := c.StartCall(env, jContext, goString(env, name), goString(env, method), jsonArgs, jPath, timeoutMillis)
+	c := (*client)(util.Ptr(goClientPtr))
+	call, err := c.StartCall(env, jContext, util.GoString(env, name), util.GoString(env, method), jsonArgs, jPath, timeoutMillis)
 	if err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return C.jlong(0)
 	}
-	goRef(call)
-	return ptrValue(call)
+	util.GoRef(call)
+	return C.jlong(util.PtrValue(call))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Client_nativeClose
 func Java_com_veyron_runtimes_google_Runtime_00024Client_nativeClose(env *C.JNIEnv, jClient C.jobject, goClientPtr C.jlong) {
-	c := (*client)(ptr(goClientPtr))
-	if c == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go client with pointer: %d", int(goClientPtr)))
-		return
-	}
-	c.Close()
+	(*client)(util.Ptr(goClientPtr)).Close()
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Client_nativeFinalize
 func Java_com_veyron_runtimes_google_Runtime_00024Client_nativeFinalize(env *C.JNIEnv, jClient C.jobject, goClientPtr C.jlong) {
-	c := (*client)(ptr(goClientPtr))
-	if c != nil {
-		goUnref(c)
-	}
+	util.GoUnref((*client)(util.Ptr(goClientPtr)))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Context_nativeFinalize
 func Java_com_veyron_runtimes_google_Runtime_00024Context_nativeFinalize(env *C.JNIEnv, jClient C.jobject, goContextPtr C.jlong) {
-	c := (*ctx.T)(ptr(goContextPtr))
-	if c != nil {
-		goUnref(c)
-	}
+	util.GoUnref((*ctx.T)(util.Ptr(goContextPtr)))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Stream_nativeSend
 func Java_com_veyron_runtimes_google_Runtime_00024Stream_nativeSend(env *C.JNIEnv, jStream C.jobject, goStreamPtr C.jlong, jItem C.jstring) {
-	s := (*stream)(ptr(goStreamPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go stream with pointer: %d", int(goStreamPtr)))
-		return
-	}
-	s.Send(env, jItem)
+	(*stream)(util.Ptr(goStreamPtr)).Send(env, jItem)
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024Stream_nativeRecv
 func Java_com_veyron_runtimes_google_Runtime_00024Stream_nativeRecv(env *C.JNIEnv, jStream C.jobject, goStreamPtr C.jlong) C.jstring {
-	s := (*stream)(ptr(goStreamPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go stream with pointer: %d", int(goStreamPtr)))
-		return nil
-	}
-	ret, err := s.Recv(env)
+	ret, err := (*stream)(util.Ptr(goStreamPtr)).Recv(env)
 	if err != nil {
 		if err == io.EOF {
-			jThrow(env, jEOFExceptionClass, err.Error())
+			util.JThrow(env, jEOFExceptionClass, err.Error())
 			return nil
 		}
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return nil
 	}
 	return ret
@@ -257,14 +212,9 @@
 
 //export Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeFinish
 func Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeFinish(env *C.JNIEnv, jClientCall C.jobject, goClientCallPtr C.jlong) C.jobjectArray {
-	c := (*clientCall)(ptr(goClientCallPtr))
-	if c == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go client call with pointer: %d", int(goClientCallPtr)))
-		return nil
-	}
-	ret, err := c.Finish(env)
+	ret, err := (*clientCall)(util.Ptr(goClientCallPtr)).Finish(env)
 	if err != nil {
-		jThrowV(env, err)
+		util.JThrowV(env, err)
 		return nil
 	}
 	return ret
@@ -272,29 +222,24 @@
 
 //export Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeCancel
 func Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeCancel(env *C.JNIEnv, jClientCall C.jobject, goClientCallPtr C.jlong) {
-	c := (*clientCall)(ptr(goClientCallPtr))
-	if c == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go client call with pointer: %d", int(goClientCallPtr)))
-		return
-	}
-	c.Cancel()
+	(*clientCall)(util.Ptr(goClientCallPtr)).Cancel()
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeFinalize
 func Java_com_veyron_runtimes_google_Runtime_00024ClientCall_nativeFinalize(env *C.JNIEnv, jClientCall C.jobject, goClientCallPtr C.jlong) {
-	c := (*clientCall)(ptr(goClientCallPtr))
-	if c != nil {
-		goUnref(c)
-	}
+	util.GoUnref((*clientCall)(util.Ptr(goClientCallPtr)))
+}
+
+//export Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeBlessing
+func Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeBlessing(env *C.JNIEnv, jServerCall C.jobject, goServerCallPtr C.jlong) C.jlong {
+	id := (*serverCall)(util.Ptr(goServerCallPtr)).Blessing()
+	util.GoRef(&id) // Un-refed when the Java PublicID object is finalized.
+	return C.jlong(util.PtrValue(&id))
 }
 
 //export Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeDeadline
 func Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeDeadline(env *C.JNIEnv, jServerCall C.jobject, goServerCallPtr C.jlong) C.jlong {
-	s := (*serverCall)(ptr(goServerCallPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go server call with pointer: %d", int(goServerCallPtr)))
-		return C.jlong(0)
-	}
+	s := (*serverCall)(util.Ptr(goServerCallPtr))
 	var d time.Time
 	if s == nil {
 		// Error, return current time as deadline.
@@ -307,21 +252,9 @@
 
 //export Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeClosed
 func Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeClosed(env *C.JNIEnv, jServerCall C.jobject, goServerCallPtr C.jlong) C.jboolean {
-	s := (*serverCall)(ptr(goServerCallPtr))
-	if s == nil {
-		jThrowV(env, fmt.Errorf("Couldn't find Go server call with pointer: %d", int(goServerCallPtr)))
-		return C.JNI_FALSE
-	}
+	s := (*serverCall)(util.Ptr(goServerCallPtr))
 	if s.IsClosed() {
 		return C.JNI_TRUE
 	}
 	return C.JNI_FALSE
 }
-
-//export Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeFinalize
-func Java_com_veyron_runtimes_google_Runtime_00024ServerCall_nativeFinalize(env *C.JNIEnv, jServerCall C.jobject, goServerCallPtr C.jlong) {
-	s := (*serverCall)(ptr(goServerCallPtr))
-	if s != nil {
-		goUnref(s)
-	}
-}
diff --git a/runtimes/google/ipc/jni/stream.go b/runtimes/google/ipc/jni/stream.go
index 0ef6751..56aa121 100644
--- a/runtimes/google/ipc/jni/stream.go
+++ b/runtimes/google/ipc/jni/stream.go
@@ -6,6 +6,7 @@
 	"encoding/json"
 	"fmt"
 
+	"veyron/runtimes/google/jni/util"
 	"veyron2/ipc"
 )
 
@@ -26,7 +27,7 @@
 }
 
 func (s *stream) Send(env *C.JNIEnv, jItem C.jstring) error {
-	argStr := goString(env, jItem)
+	argStr := util.GoString(env, jItem)
 	argptr := s.mArgs.StreamSendPtr()
 	if argptr == nil {
 		return fmt.Errorf("nil stream input argument, expected a non-nil type for argument %q", argStr)
@@ -34,7 +35,7 @@
 	if err := json.Unmarshal([]byte(argStr), argptr); err != nil {
 		return err
 	}
-	return s.stream.Send(derefOrDie(argptr))
+	return s.stream.Send(util.DerefOrDie(argptr))
 }
 
 func (s *stream) Recv(env *C.JNIEnv) (C.jstring, error) {
@@ -46,9 +47,9 @@
 		return nil, err
 	}
 	// JSON encode the result.
-	result, err := json.Marshal(derefOrDie(argptr))
+	result, err := json.Marshal(util.DerefOrDie(argptr))
 	if err != nil {
 		return nil, err
 	}
-	return jString(env, string(result)), nil
+	return C.jstring(util.JStringPtr(env, string(result))), nil
 }
diff --git a/runtimes/google/ipc/jni/util.go b/runtimes/google/ipc/jni/util.go
deleted file mode 100644
index d87f3bd..0000000
--- a/runtimes/google/ipc/jni/util.go
+++ /dev/null
@@ -1,241 +0,0 @@
-// +build android
-
-package jni
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-	"unsafe"
-
-	"veyron2/verror"
-)
-
-// #cgo LDFLAGS: -ljniwrapper
-// #include <stdlib.h>
-// #include "jni_wrapper.h"
-// // CGO doesn't support variadic functions so we have to hard-code these
-// // functions to match the invoking code. Ugh!
-// static jobject CallNewVeyronExceptionObject(JNIEnv* env, jclass class, jmethodID mid, jstring msg, jstring id) {
-//   return (*env)->NewObject(env, class, mid, msg, id);
-// }
-// static jstring CallGetMessage(JNIEnv* env, jobject obj, jmethodID id) {
-//   return (jstring)(*env)->CallObjectMethod(env, obj, id);
-// }
-import "C"
-
-const (
-	voidSign   = "V"
-	boolSign   = "Z"
-	longSign   = "J"
-	stringSign = "Ljava/lang/String;"
-	objectSign = "Ljava/lang/Object;"
-)
-
-func arraySign(sign string) string {
-	return "[" + sign
-}
-
-// refs stores references to instances of various Go types, namely instances
-// that are referenced only by the Java code.  The only purpose of this store
-// is to prevent Go runtime from garbage collecting those instances.
-var refs = newSafeSet()
-
-// goRef creates a new reference to the value addressed by the provided pointer.
-// The value will remain referenced until it is explicitly unreferenced using
-// goUnref().
-func goRef(valptr interface{}) {
-	if !isPointer(valptr) {
-		panic("must pass pointer value to goRef")
-	}
-	refs.insert(valptr)
-}
-
-// goUnref removes a previously added reference to the value addressed by the
-// provided pointer.  If the value hasn't been ref-ed (a bug?), this unref will
-// be a no-op.
-func goUnref(valptr interface{}) {
-	if !isPointer(valptr) {
-		panic("must pass pointer value to goUnref")
-	}
-	refs.delete(valptr)
-}
-
-// ptrValue returns the value of the pointer as a Java C.jlong type.
-func ptrValue(ptr interface{}) C.jlong {
-	v := reflect.ValueOf(ptr)
-	if v.Kind() != reflect.Ptr {
-		panic("must pass pointer value to ptrValue")
-	}
-	return C.jlong(v.Pointer())
-}
-
-// ptr returns the pointer represented by the provided (Java C.jlong) value.
-func ptr(ptrValue C.jlong) unsafe.Pointer {
-	return unsafe.Pointer(uintptr(ptrValue))
-}
-
-// isPointer returns true iff the provided value is a pointer.
-func isPointer(val interface{}) bool {
-	return reflect.ValueOf(val).Kind() == reflect.Ptr
-}
-
-// goString returns a Go string given the Java string.
-func goString(env *C.JNIEnv, str C.jstring) string {
-	if str == nil {
-		return ""
-	}
-	cString := C.GetStringUTFChars(env, str, nil)
-	defer C.ReleaseStringUTFChars(env, str, cString)
-	return C.GoString(cString)
-}
-
-// jString returns a Java string given the Go string.
-func jString(env *C.JNIEnv, str string) C.jstring {
-	cString := C.CString(str)
-	defer C.free(unsafe.Pointer(cString))
-	return C.NewStringUTF(env, cString)
-}
-
-// goStringArray converts a Java string array to a go string array.
-func goStringArray(env *C.JNIEnv, jStrArray C.jobjectArray) []string {
-	if jStrArray == nil {
-		return nil
-	}
-	length := C.GetArrayLength(env, C.jarray(jStrArray))
-	ret := make([]string, int(length))
-	for i := 0; i < int(length); i++ {
-		ret[i] = goString(env, C.jstring(C.GetObjectArrayElement(env, jStrArray, C.jsize(i))))
-	}
-	return ret
-}
-
-// jThrow throws a new Java exception of the provided type with the given message.
-func jThrow(env *C.JNIEnv, class C.jclass, msg string) {
-	s := C.CString(msg)
-	defer C.free(unsafe.Pointer(s))
-	C.ThrowNew(env, class, s)
-}
-
-// jThrowV throws a new Java VeyronException corresponding to the given error.
-func jThrowV(env *C.JNIEnv, err error) {
-	verr := verror.Convert(err)
-	id := jMethodID(env, jVeyronExceptionClass, "<init>", fmt.Sprintf("(%s%s)%s", stringSign, stringSign, voidSign))
-	obj := C.jthrowable(C.CallNewVeyronExceptionObject(env, jVeyronExceptionClass, id, jString(env, verr.Error()), jString(env, string(verr.ErrorID()))))
-	C.Throw(env, obj)
-}
-
-// jExceptionMsg returns the exception message if an exception occurred, or
-// nil otherwise.
-func jExceptionMsg(env *C.JNIEnv) error {
-	e := C.ExceptionOccurred(env)
-	if e == nil { // no exception
-		return nil
-	}
-	C.ExceptionClear(env)
-	id := jMethodID(env, jThrowableClass, "getMessage", fmt.Sprintf("()%s", stringSign))
-	jMsg := C.CallGetMessage(env, C.jobject(e), id)
-	//return errors.New("blah")
-	return errors.New(goString(env, jMsg))
-}
-
-// camelCase converts ThisString to thisString.
-func camelCase(s string) string {
-	if s == "" {
-		return ""
-	}
-	r, n := utf8.DecodeRuneInString(s)
-	return string(unicode.ToLower(r)) + s[n:]
-}
-
-// jBoolField returns the value of the provided object's boolean field.
-func jBoolField(env *C.JNIEnv, obj C.jobject, field string) bool {
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString(boolSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
-	return C.GetBooleanField(env, obj, fid) != C.JNI_FALSE
-}
-
-// jStringField returns the value of the provided object's String field,
-// as a Go string.
-func jStringField(env *C.JNIEnv, obj C.jobject, field string) string {
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString(stringSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
-	jStr := C.jstring(C.GetObjectField(env, obj, fid))
-	return goString(env, jStr)
-}
-
-// jStringArrayField returns the value of the provided object's String[] field,
-// as a slice of Go strings.
-func jStringArrayField(env *C.JNIEnv, obj C.jobject, field string) []string {
-	cField := C.CString(field)
-	defer C.free(unsafe.Pointer(cField))
-	cSig := C.CString("[" + stringSign)
-	defer C.free(unsafe.Pointer(cSig))
-	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
-	jStrArray := C.jobjectArray(C.GetObjectField(env, obj, fid))
-	return goStringArray(env, jStrArray)
-}
-
-// jMethodID returns the Java method ID for the given method.
-func jMethodID(env *C.JNIEnv, class C.jclass, name, signature string) C.jmethodID {
-	cName := C.CString(name)
-	defer C.free(unsafe.Pointer(cName))
-	cSignature := C.CString(signature)
-	defer C.free(unsafe.Pointer(cSignature))
-	return C.GetMethodID(env, class, cName, cSignature)
-}
-
-// jFindClassOrDie returns the global references to the Java class with the
-// given pathname, or panic-s if the class cannot be found.
-func jFindClassOrDie(env *C.JNIEnv, name string) C.jclass {
-	cName := C.CString(name)
-	defer C.free(unsafe.Pointer(cName))
-	class := C.FindClass(env, cName)
-	if err := jExceptionMsg(env); err != nil || class == nil {
-		panic(fmt.Sprintf("couldn't find class %s: %v", name, err))
-	}
-	return C.jclass(C.NewGlobalRef(env, C.jobject(class)))
-}
-
-// derefOrDie dereferences the provided (pointer) value, or panic-s if the value
-// isn't of pointer type.
-func derefOrDie(i interface{}) interface{} {
-	v := reflect.ValueOf(i)
-	if v.Kind() != reflect.Ptr {
-		panic(fmt.Sprintf("want reflect.Ptr value for %v, have %v", i, v.Kind()))
-	}
-	return v.Elem().Interface()
-}
-
-func newSafeSet() *safeSet {
-	return &safeSet{
-		items: make(map[interface{}]bool),
-	}
-}
-
-// safeSet is a thread-safe set.
-type safeSet struct {
-	lock  sync.Mutex
-	items map[interface{}]bool
-}
-
-func (s *safeSet) insert(item interface{}) {
-	s.lock.Lock()
-	defer s.lock.Unlock()
-	s.items[item] = true
-}
-
-func (s *safeSet) delete(item interface{}) {
-	s.lock.Lock()
-	defer s.lock.Unlock()
-	delete(s.items, item)
-}
diff --git a/runtimes/google/jni/jni.go b/runtimes/google/jni/jni.go
new file mode 100644
index 0000000..4df2de1
--- /dev/null
+++ b/runtimes/google/jni/jni.go
@@ -0,0 +1,48 @@
+// +build android
+
+package main
+
+import (
+	"flag"
+	"log"
+	"unsafe"
+
+	ipc "veyron/runtimes/google/ipc/jni"
+	"veyron/runtimes/google/jni/util"
+	security "veyron/runtimes/google/security/jni"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+import "C"
+
+//export JNI_OnLoad
+func JNI_OnLoad(jVM *C.JavaVM, reserved unsafe.Pointer) C.jint {
+	log.Println("On_Load")
+	var env *C.JNIEnv
+	if C.GetEnv(jVM, &env, C.JNI_VERSION_1_6) != C.JNI_OK {
+		// This should never happen as OnLoad is invoked from the main Java thread.
+		C.AttachCurrentThread(jVM, &env, nil)
+		defer C.DetachCurrentThread(jVM)
+	}
+	log.Println("Here1")
+	util.Init(env)
+	log.Println("Here2")
+	ipc.Init(env)
+	log.Println("Here3")
+	security.Init(env)
+	log.Println("Here4")
+	log.Println("Here4")
+	log.Println("Here4")
+	log.Println("Here4")
+	log.Println("Here4")
+	log.Println("Here4")
+	return C.JNI_VERSION_1_6
+}
+
+func main() {
+	// Send all logging to stderr, so that the output is visible in Android.  Note that if this
+	// flag is removed, the process will likely crash as android requires that all logs are written
+	// into a specific directory.
+	flag.Set("logtostderr", "true")
+}
diff --git a/runtimes/google/jni/util/util.go b/runtimes/google/jni/util/util.go
new file mode 100644
index 0000000..85e73a7
--- /dev/null
+++ b/runtimes/google/jni/util/util.go
@@ -0,0 +1,427 @@
+// +build android
+
+// Package util provides various JNI utilities shared across our JNI code.
+package util
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+	"unsafe"
+
+	"veyron2/verror"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include <stdlib.h>
+// #include "jni_wrapper.h"
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jobject CallNewVeyronExceptionObject(JNIEnv* env, jclass class, jmethodID mid, jstring msg, jstring id) {
+//   return (*env)->NewObject(env, class, mid, msg, id);
+// }
+// static jstring CallGetExceptionMessage(JNIEnv* env, jobject obj, jmethodID id) {
+//   return (jstring)(*env)->CallObjectMethod(env, obj, id);
+// }
+import "C"
+
+const (
+	// VoidSign denotes a signature of a Java void type.
+	VoidSign = "V"
+	// ByteSign denotes a signature of a Java byte type.
+	ByteSign = "B"
+	// BoolSign denotes a signature of a Java boolean type.
+	BoolSign = "Z"
+	// IntSign denotes a signature of a Java int type.
+	IntSign = "I"
+	// LongSign denotes a signature of a Java long type.
+	LongSign = "J"
+	// StringSign denotes a signature of a Java String type.
+	StringSign = "Ljava/lang/String;"
+	// ObjectSign denotes a signature of a Java Object type.
+	ObjectSign = "Ljava/lang/Object;"
+)
+
+// ArraySign returns the array signature, given the underlying array type.
+func ArraySign(sign string) string {
+	return "[" + sign
+}
+
+var (
+	// Global reference for com.veyron2.ipc.VeyronException class.
+	jVeyronExceptionClass C.jclass
+	// Global reference for java.lang.Throwable class.
+	jThrowableClass C.jclass
+	// Global reference for java.lang.String class.
+	jStringClass C.jclass
+)
+
+// Init initializes the JNI code with the given Java environment.  This method
+// must be invoked before any other method in this package and must be called
+// from the main Java thread (e.g., On_Load()).
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func Init(jEnv interface{}) {
+	env := getEnv(jEnv)
+	jVeyronExceptionClass = C.jclass(JFindClassPtrOrDie(env, "com/veyron2/ipc/VeyronException"))
+	jThrowableClass = C.jclass(JFindClassPtrOrDie(env, "java/lang/Throwable"))
+	jStringClass = C.jclass(JFindClassPtrOrDie(env, "java/lang/String"))
+}
+
+// GoRef creates a new reference to the value addressed by the provided pointer.
+// The value will remain referenced until it is explicitly unreferenced using
+// goUnref().
+func GoRef(valptr interface{}) {
+	if !IsPointer(valptr) {
+		panic("must pass pointer value to goRef")
+	}
+	refs.insert(valptr)
+}
+
+// GoUnref removes a previously added reference to the value addressed by the
+// provided pointer.  If the value hasn't been ref-ed (a bug?), this unref will
+// be a no-op.
+func GoUnref(valptr interface{}) {
+	if !IsPointer(valptr) {
+		panic("must pass pointer value to goUnref")
+	}
+	refs.delete(valptr)
+}
+
+// IsPointer returns true iff the provided value is a pointer.
+func IsPointer(val interface{}) bool {
+	return reflect.ValueOf(val).Kind() == reflect.Ptr
+}
+
+// DerefOrDie dereferences the provided (pointer) value, or panic-s if the value
+// isn't of pointer type.
+func DerefOrDie(i interface{}) interface{} {
+	v := reflect.ValueOf(i)
+	if v.Kind() != reflect.Ptr {
+		panic(fmt.Sprintf("want reflect.Ptr value for %v, have %v", i, v.Kind()))
+	}
+	return v.Elem().Interface()
+}
+
+// Ptr returns the value of the provided Java pointer (of type C.jlong) as an
+// unsafe.Pointer.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func Ptr(jPtr interface{}) unsafe.Pointer {
+	v := reflect.ValueOf(jPtr)
+	return unsafe.Pointer(uintptr(v.Int()))
+}
+
+// PtrValue returns the value of the pointer as a uintptr.
+func PtrValue(ptr interface{}) uintptr {
+	v := reflect.ValueOf(ptr)
+	if v.Kind() != reflect.Ptr && v.Kind() != reflect.UnsafePointer {
+		panic("must pass pointer value to PtrValue")
+	}
+	return v.Pointer()
+}
+
+// CamelCase converts ThisString to thisString.
+func CamelCase(s string) string {
+	if s == "" {
+		return ""
+	}
+	r, n := utf8.DecodeRuneInString(s)
+	return string(unicode.ToLower(r)) + s[n:]
+}
+
+// GoString returns a Go string given the Java string.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func GoString(jEnv, jStr interface{}) string {
+	env := getEnv(jEnv)
+	str := getString(jStr)
+	if str == nil {
+		return ""
+	}
+	cString := C.GetStringUTFChars(env, str, nil)
+	defer C.ReleaseStringUTFChars(env, str, cString)
+	return C.GoString(cString)
+}
+
+// JString returns a Java string given the Go string.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JStringPtr(jEnv interface{}, str string) unsafe.Pointer {
+	env := getEnv(jEnv)
+	cString := C.CString(str)
+	defer C.free(unsafe.Pointer(cString))
+	return unsafe.Pointer(C.NewStringUTF(env, cString))
+}
+
+// JThrow throws a new Java exception of the provided type with the given message.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JThrow(jEnv, jClass interface{}, msg string) {
+	env := getEnv(jEnv)
+	class := getClass(jClass)
+	s := C.CString(msg)
+	defer C.free(unsafe.Pointer(s))
+	C.ThrowNew(env, class, s)
+}
+
+// JThrowV throws a new Java VeyronException corresponding to the given error.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JThrowV(jEnv interface{}, err error) {
+	env := getEnv(jEnv)
+	verr := verror.Convert(err)
+	id := C.jmethodID(JMethodIDPtr(env, jVeyronExceptionClass, "<init>", fmt.Sprintf("(%s%s)%s", StringSign, StringSign, VoidSign)))
+	obj := C.jthrowable(C.CallNewVeyronExceptionObject(env, jVeyronExceptionClass, id, C.jstring(JStringPtr(env, verr.Error())), C.jstring(JStringPtr(env, string(verr.ErrorID())))))
+	C.Throw(env, obj)
+}
+
+// JExceptionMsg returns the exception message if an exception occurred, or
+// nil otherwise.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JExceptionMsg(jEnv interface{}) error {
+	env := getEnv(jEnv)
+	e := C.ExceptionOccurred(env)
+	if e == nil { // no exception
+		return nil
+	}
+	C.ExceptionClear(env)
+	id := C.jmethodID(JMethodIDPtr(env, jThrowableClass, "getMessage", fmt.Sprintf("()%s", StringSign)))
+	jMsg := C.CallGetExceptionMessage(env, C.jobject(e), id)
+	return errors.New(GoString(env, jMsg))
+}
+
+// JBoolField returns the value of the provided Java object's boolean field.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JBoolField(jEnv, jObj interface{}, field string) bool {
+	env := getEnv(jEnv)
+	obj := getObject(jObj)
+	cField := C.CString(field)
+	defer C.free(unsafe.Pointer(cField))
+	cSig := C.CString(BoolSign)
+	defer C.free(unsafe.Pointer(cSig))
+	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	return C.GetBooleanField(env, obj, fid) != C.JNI_FALSE
+}
+
+// JIntField returns the value of the provided Java object's int field.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JIntField(jEnv, jObj interface{}, field string) int {
+	env := getEnv(jEnv)
+	obj := getObject(jObj)
+	cField := C.CString(field)
+	defer C.free(unsafe.Pointer(cField))
+	cSig := C.CString(IntSign)
+	defer C.free(unsafe.Pointer(cSig))
+	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	return int(C.GetIntField(env, obj, fid))
+}
+
+// JStringField returns the value of the provided Java object's String field,
+// as a Go string.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JStringField(jEnv, jObj interface{}, field string) string {
+	env := getEnv(jEnv)
+	obj := getObject(jObj)
+	cField := C.CString(field)
+	defer C.free(unsafe.Pointer(cField))
+	cSig := C.CString(StringSign)
+	defer C.free(unsafe.Pointer(cSig))
+	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	jStr := C.jstring(C.GetObjectField(env, obj, fid))
+	return GoString(env, jStr)
+}
+
+// JStringArrayField returns the value of the provided object's String[] field,
+// as a slice of Go strings.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JStringArrayField(jEnv, jObj interface{}, field string) []string {
+	env := getEnv(jEnv)
+	obj := getObject(jObj)
+	cField := C.CString(field)
+	defer C.free(unsafe.Pointer(cField))
+	cSig := C.CString("[" + StringSign)
+	defer C.free(unsafe.Pointer(cSig))
+	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	jStrArray := C.jobjectArray(C.GetObjectField(env, obj, fid))
+	return GoStringArray(env, jStrArray)
+}
+
+// JByteArrayField returns the value of the provided object's byte[] field as a
+// Go byte slice.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JByteArrayField(jEnv, jObj interface{}, field string) []byte {
+	env := getEnv(jEnv)
+	obj := getObject(jObj)
+	cField := C.CString(field)
+	defer C.free(unsafe.Pointer(cField))
+	cSig := C.CString("[" + StringSign)
+	defer C.free(unsafe.Pointer(cSig))
+	fid := C.GetFieldID(env, C.GetObjectClass(env, obj), cField, cSig)
+	arr := C.jbyteArray(C.GetObjectField(env, obj, fid))
+	if arr == nil {
+		return nil
+	}
+	return GoByteArray(env, arr)
+}
+
+// JStringArray converts the provided slice of Go strings into a Java array of strings.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JStringArrayPtr(jEnv interface{}, strs []string) unsafe.Pointer {
+	env := getEnv(jEnv)
+	ret := C.NewObjectArray(env, C.jsize(len(strs)), jStringClass, nil)
+	for i, str := range strs {
+		C.SetObjectArrayElement(env, ret, C.jsize(i), C.jobject(JStringPtr(env, str)))
+	}
+	return unsafe.Pointer(ret)
+}
+
+// GoStringArray converts a Java string array to a Go string array.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func GoStringArray(jEnv, jStrArray interface{}) []string {
+	env := getEnv(jEnv)
+	jArr := getObjectArray(jStrArray)
+	if jArr == nil {
+		return nil
+	}
+	length := C.GetArrayLength(env, C.jarray(jArr))
+	ret := make([]string, int(length))
+	for i := 0; i < int(length); i++ {
+		ret[i] = GoString(env, C.jstring(C.GetObjectArrayElement(env, jArr, C.jsize(i))))
+	}
+	return ret
+}
+
+// JByteArray converts the provided Go byte slice into a Java byte array.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JByteArrayPtr(jEnv interface{}, bytes []byte) unsafe.Pointer {
+	env := getEnv(jEnv)
+	ret := C.NewByteArray(env, C.jsize(len(bytes)))
+	C.SetByteArrayRegion(env, ret, 0, C.jsize(len(bytes)), (*C.jbyte)(unsafe.Pointer(&bytes[0])))
+	return unsafe.Pointer(ret)
+}
+
+// GoByteArray converts the provided Java byte array into a Go byte slice.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func GoByteArray(jEnv, jArr interface{}) (ret []byte) {
+	env := getEnv(jEnv)
+	arr := getByteArray(jArr)
+	length := int(C.GetArrayLength(env, C.jarray(arr)))
+	ret = make([]byte, length)
+	bytes := C.GetByteArrayElements(env, arr, nil)
+	for i := 0; i < length; i++ {
+		ret[i] = byte(*bytes)
+		bytes = (*C.jbyte)(unsafe.Pointer(uintptr(unsafe.Pointer(bytes)) + unsafe.Sizeof(*bytes)))
+	}
+	return
+}
+
+// JMethodID returns the Java method ID for the given method.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JMethodIDPtr(jEnv, jClass interface{}, name, signature string) unsafe.Pointer {
+	env := getEnv(jEnv)
+	class := getClass(jClass)
+	cName := C.CString(name)
+	defer C.free(unsafe.Pointer(cName))
+	cSignature := C.CString(signature)
+	defer C.free(unsafe.Pointer(cSignature))
+	return unsafe.Pointer(C.GetMethodID(env, class, cName, cSignature))
+}
+
+// JFindClassOrDie returns the global references to the Java class with the
+// given pathname, or panic-s if the class cannot be found.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func JFindClassPtrOrDie(jEnv interface{}, name string) unsafe.Pointer {
+	env := getEnv(jEnv)
+	cName := C.CString(name)
+	defer C.free(unsafe.Pointer(cName))
+	class := C.FindClass(env, cName)
+	if err := JExceptionMsg(env); err != nil || class == nil {
+		panic(fmt.Sprintf("couldn't find class %s: %v", name, err))
+	}
+	return unsafe.Pointer(C.NewGlobalRef(env, C.jobject(class)))
+}
+
+// refs stores references to instances of various Go types, namely instances
+// that are referenced only by the Java code.  The only purpose of this store
+// is to prevent Go runtime from garbage collecting those instances.
+var refs = newSafeSet()
+
+// newSafeSet returns a new instance of a thread-safe set.
+func newSafeSet() *safeSet {
+	return &safeSet{
+		items: make(map[interface{}]bool),
+	}
+}
+
+// safeSet is a thread-safe set.
+type safeSet struct {
+	lock  sync.Mutex
+	items map[interface{}]bool
+}
+
+func (s *safeSet) insert(item interface{}) {
+	s.lock.Lock()
+	defer s.lock.Unlock()
+	s.items[item] = true
+}
+
+func (s *safeSet) delete(item interface{}) {
+	s.lock.Lock()
+	defer s.lock.Unlock()
+	delete(s.items, item)
+}
+
+// Various functions that cast CGO types from various other packages into this
+// package's types.
+func getEnv(jEnv interface{}) *C.JNIEnv {
+	return (*C.JNIEnv)(unsafe.Pointer(PtrValue(jEnv)))
+}
+func getByteArray(jByteArray interface{}) C.jbyteArray {
+	return C.jbyteArray(unsafe.Pointer(PtrValue(jByteArray)))
+}
+func getObject(jObj interface{}) C.jobject {
+	return C.jobject(unsafe.Pointer(PtrValue(jObj)))
+}
+func getClass(jClass interface{}) C.jclass {
+	return C.jclass(unsafe.Pointer(PtrValue(jClass)))
+}
+func getString(jString interface{}) C.jstring {
+	return C.jstring(unsafe.Pointer(PtrValue(jString)))
+}
+func getObjectArray(jArray interface{}) C.jobjectArray {
+	return C.jobjectArray(unsafe.Pointer(PtrValue(jArray)))
+}
diff --git a/runtimes/google/security/jni/authorizer.go b/runtimes/google/security/jni/authorizer.go
new file mode 100644
index 0000000..9a00b91
--- /dev/null
+++ b/runtimes/google/security/jni/authorizer.go
@@ -0,0 +1,82 @@
+// +build android
+
+package jni
+
+import (
+	"fmt"
+	"runtime"
+	"unsafe"
+
+	"veyron/runtimes/google/jni/util"
+	"veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jobject CallAuthorizerNewContextObject(JNIEnv* env, jclass class, jmethodID id, jlong goContextPtr) {
+// 	return (*env)->NewObject(env, class, id, goContextPtr);
+// }
+// static void CallAuthorizerAuthorizeMethod(JNIEnv* env, jobject obj, jmethodID id, jobject context) {
+// 	(*env)->CallObjectMethod(env, obj, id, context);
+// }
+import "C"
+
+// NewAuthorizer returns a new security.Authorizer given the provided Java authorizer.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java types are passed in an empty interface
+// and then cast into their package local types.
+func NewAuthorizer(jEnv, jAuthPtr interface{}) security.Authorizer {
+	env := (*C.JNIEnv)(unsafe.Pointer(util.PtrValue(jEnv)))
+	jAuth := C.jobject(unsafe.Pointer(util.PtrValue(jAuthPtr)))
+	// We cannot cache Java environments as they are only valid in the current
+	// thread.  We can, however, cache the Java VM and obtain an environment
+	// from it in whatever thread happens to be running at the time.
+	var jVM *C.JavaVM
+	if status := C.GetJavaVM(env, &jVM); status != 0 {
+		panic("couldn't get Java VM from the (Java) environment")
+	}
+	// Reference Java dispatcher; it will be de-referenced when the go
+	// dispatcher created below is garbage-collected (through the finalizer
+	// callback we setup below).
+	jAuth = C.NewGlobalRef(env, jAuth)
+	a := &authorizer{
+		jVM:   jVM,
+		jAuth: jAuth,
+	}
+	runtime.SetFinalizer(a, func(a *authorizer) {
+		var env *C.JNIEnv
+		C.AttachCurrentThread(a.jVM, &env, nil)
+		defer C.DetachCurrentThread(a.jVM)
+		C.DeleteGlobalRef(env, a.jAuth)
+	})
+	return a
+}
+
+type authorizer struct {
+	jVM   *C.JavaVM
+	jAuth C.jobject
+}
+
+func (a *authorizer) Authorize(context security.Context) error {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(a.jVM, &env, nil)
+	defer C.DetachCurrentThread(a.jVM)
+	// Create a Java context.
+	util.GoRef(&context) // Un-refed when the Java Context object is finalized.
+	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	jContext := C.CallAuthorizerNewContextObject(env, jContextImplClass, cid, C.jlong(util.PtrValue(&context)))
+	// Run Java Authorizer.
+	contextSign := "Lcom/veyron2/security/Context;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, a.jAuth), "authorize", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
+	if mid == nil {
+		return fmt.Errorf("Srdjan's error")
+	}
+	return nil
+	C.CallAuthorizerAuthorizeMethod(env, a.jAuth, mid, jContext)
+	if err := util.JExceptionMsg(env); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/runtimes/google/security/jni/caveat.go b/runtimes/google/security/jni/caveat.go
new file mode 100644
index 0000000..e3901dc
--- /dev/null
+++ b/runtimes/google/security/jni/caveat.go
@@ -0,0 +1,67 @@
+// +build android
+
+package jni
+
+import (
+	"fmt"
+	"runtime"
+
+	"veyron/runtimes/google/jni/util"
+	"veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+//
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jobject CallCaveatNewContextObject(JNIEnv* env, jclass class, jmethodID id, jlong goContextPtr) {
+// 	return (*env)->NewObject(env, class, id, goContextPtr);
+// }
+// static void CallCaveatValidateMethod(JNIEnv* env, jobject obj, jmethodID id, jobject context) {
+// 	return (*env)->CallVoidMethod(env, obj, id, context);
+// }
+import "C"
+
+func newCaveat(env *C.JNIEnv, jCaveat C.jobject) *caveat {
+	// We cannot cache Java environments as they are only valid in the current
+	// thread.  We can, however, cache the Java VM and obtain an environment
+	// from it in whatever thread happens to be running at the time.
+	var jVM *C.JavaVM
+	if status := C.GetJavaVM(env, &jVM); status != 0 {
+		panic("couldn't get Java VM from the (Java) environment")
+	}
+	// Reference Java service caveat; it will be de-referenced when the go
+	// service caveat created below is garbage-collected (through the finalizer
+	// callback we setup just below).
+	jCaveat = C.NewGlobalRef(env, jCaveat)
+	c := &caveat{
+		jVM:     jVM,
+		jCaveat: jCaveat,
+	}
+	runtime.SetFinalizer(c, func(c *caveat) {
+		var env *C.JNIEnv
+		C.AttachCurrentThread(c.jVM, &env, nil)
+		defer C.DetachCurrentThread(c.jVM)
+		C.DeleteGlobalRef(env, c.jCaveat)
+	})
+	return c
+}
+
+type caveat struct {
+	jVM     *C.JavaVM
+	jCaveat C.jobject
+}
+
+func (c *caveat) Validate(context security.Context) error {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	util.GoRef(&context) // un-refed when the Java Context object is finalized.
+	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	jContext := C.CallCaveatNewContextObject(env, jContextClass, cid, C.jlong(util.PtrValue(&context)))
+	contextSign := "Lcom/veyron2/security/Context;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jCaveat), "validate", fmt.Sprintf("(%s)%s", contextSign, util.VoidSign)))
+	C.CallCaveatValidateMethod(env, c.jCaveat, mid, jContext)
+	return util.JExceptionMsg(env)
+}
diff --git a/runtimes/google/security/jni/context.go b/runtimes/google/security/jni/context.go
new file mode 100644
index 0000000..57e6a31
--- /dev/null
+++ b/runtimes/google/security/jni/context.go
@@ -0,0 +1,144 @@
+// +build android
+
+package jni
+
+import (
+	"fmt"
+	"runtime"
+
+	"veyron/runtimes/google/jni/util"
+	inaming "veyron/runtimes/google/naming"
+	"veyron2/naming"
+	"veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+//
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jstring CallContextStringMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (jstring)(*env)->CallObjectMethod(env, obj, id);
+// }
+// static jint CallContextIntMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (*env)->CallIntMethod(env, obj, id);
+// }
+// static jobject CallContextPublicIDMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (*env)->CallObjectMethod(env, obj, id);
+// }
+import "C"
+
+func newContext(env *C.JNIEnv, jContext C.jobject) *context {
+	// We cannot cache Java environments as they are only valid in the current
+	// thread.  We can, however, cache the Java VM and obtain an environment
+	// from it in whatever thread happens to be running at the time.
+	var jVM *C.JavaVM
+	if status := C.GetJavaVM(env, &jVM); status != 0 {
+		panic("couldn't get Java VM from the (Java) environment")
+	}
+	// Reference Java context; it will be de-referenced when the go context
+	// created below is garbage-collected (through the finalizer callback we
+	// setup just below).
+	jContext = C.NewGlobalRef(env, jContext)
+	c := &context{
+		jVM:      jVM,
+		jContext: jContext,
+	}
+	runtime.SetFinalizer(c, func(c *context) {
+		var env *C.JNIEnv
+		C.AttachCurrentThread(c.jVM, &env, nil)
+		defer C.DetachCurrentThread(c.jVM)
+		C.DeleteGlobalRef(env, c.jContext)
+	})
+	return c
+}
+
+type context struct {
+	jVM      *C.JavaVM
+	jContext C.jobject
+}
+
+func (c *context) Method() string {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "method", fmt.Sprintf("()%s", util.StringSign)))
+	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
+}
+
+func (c *context) Name() string {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "name", fmt.Sprintf("()%s", util.StringSign)))
+	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
+}
+
+func (c *context) Suffix() string {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "suffix", fmt.Sprintf("()%s", util.StringSign)))
+	return util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
+}
+
+func (c *context) Label() security.Label {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "label", fmt.Sprintf("()%s", util.IntSign)))
+	return security.Label(C.CallContextIntMethod(env, c.jContext, mid))
+}
+
+func (c *context) CaveatDischarges() security.CaveatDischargeMap {
+	// TODO(spetrovic): implement this method.
+	return nil
+}
+
+func (c *context) LocalID() security.PublicID {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	publicIDSign := "Lcom/veyron2/security/PublicID;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "localID", fmt.Sprintf("()%s", publicIDSign)))
+	jID := C.CallContextPublicIDMethod(env, c.jContext, mid)
+	return newPublicID(env, jID)
+}
+
+func (c *context) RemoteID() security.PublicID {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	publicIDSign := "Lcom/veyron2/security/PublicID;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "remoteID", fmt.Sprintf("()%s", publicIDSign)))
+	jID := C.CallContextPublicIDMethod(env, c.jContext, mid)
+	return newPublicID(env, jID)
+}
+
+func (c *context) LocalEndpoint() naming.Endpoint {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "localEndpoint", fmt.Sprintf("()%s", util.StringSign)))
+	// TODO(spetrovic): create a Java Endpoint interface.
+	epStr := util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
+	ep, err := inaming.NewEndpoint(epStr)
+	if err != nil {
+		panic("Couldn't parse endpoint string: " + epStr)
+	}
+	return ep
+}
+
+func (c *context) RemoteEndpoint() naming.Endpoint {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(c.jVM, &env, nil)
+	defer C.DetachCurrentThread(c.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, c.jContext), "remoteEndpoint", fmt.Sprintf("()%s", util.StringSign)))
+	// TODO(spetrovic): create a Java Endpoint interface.
+	epStr := util.GoString(env, C.CallContextStringMethod(env, c.jContext, mid))
+	ep, err := inaming.NewEndpoint(epStr)
+	if err != nil {
+		panic("Couldn't parse endpoint string: " + epStr)
+	}
+	return ep
+}
diff --git a/runtimes/google/security/jni/crypto_util.go b/runtimes/google/security/jni/crypto_util.go
new file mode 100644
index 0000000..a2c8c93
--- /dev/null
+++ b/runtimes/google/security/jni/crypto_util.go
@@ -0,0 +1,95 @@
+package jni
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"fmt"
+)
+
+var (
+	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
+	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
+	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
+	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
+	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
+)
+
+func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
+	switch curve {
+	case elliptic.P224():
+		return oidNamedCurveP224, true
+	case elliptic.P256():
+		return oidNamedCurveP256, true
+	case elliptic.P384():
+		return oidNamedCurveP384, true
+	case elliptic.P521():
+		return oidNamedCurveP521, true
+	}
+	return nil, false
+}
+
+// marshalPKCS8PrivateKey marshals the provided ECDSA private key into the
+// PKCS#8 private key format.
+func marshalPKCS8PrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
+	oid, ok := oidFromNamedCurve(key.PublicKey.Curve)
+	if !ok {
+		return nil, fmt.Errorf("illegal curve")
+	}
+	paramBytes, err := asn1.Marshal(oid)
+	if err != nil {
+		return nil, err
+	}
+	var algo pkix.AlgorithmIdentifier
+	algo.Algorithm = oidPublicKeyECDSA
+	algo.Parameters.FullBytes = paramBytes
+
+	privBytes, err := x509.MarshalECPrivateKey(key)
+	if err != nil {
+		return nil, err
+	}
+	pkcs8 := struct {
+		Version    int
+		Algo       pkix.AlgorithmIdentifier
+		PrivateKey []byte
+	}{
+		Version:    1,
+		Algo:       algo,
+		PrivateKey: privBytes,
+	}
+	return asn1.Marshal(pkcs8)
+}
+
+// parsePKCS8PrivateKey parses the provided private key in the PKCS#8 format.
+func parsePKCS8PrivateKey(data []byte) (*ecdsa.PrivateKey, error) {
+	key, err := x509.ParsePKCS8PrivateKey(data)
+	if err != nil {
+		return nil, err
+	}
+	eckey, ok := key.(*ecdsa.PrivateKey)
+	if !ok {
+		return nil, fmt.Errorf("not an ECDSA private key")
+	}
+	return eckey, nil
+}
+
+// marshalPKIXPublicKey marshals the provided ECDSA public key into the
+// DER-encoded PKIX format.
+func marshalPKIXPublicKey(key *ecdsa.PublicKey) ([]byte, error) {
+	return x509.MarshalPKIXPublicKey(key)
+}
+
+// parsePKIXPublicKey parses the provided DER encoded public key.
+func parsePKIXPublicKey(data []byte) (*ecdsa.PublicKey, error) {
+	key, err := x509.ParsePKIXPublicKey(data)
+	if err != nil {
+		return nil, err
+	}
+	eckey, ok := key.(*ecdsa.PublicKey)
+	if !ok {
+		return nil, fmt.Errorf("not an ECDSA public key")
+	}
+	return eckey, nil
+}
diff --git a/runtimes/google/security/jni/crypto_util_test.go b/runtimes/google/security/jni/crypto_util_test.go
new file mode 100644
index 0000000..aca9c05
--- /dev/null
+++ b/runtimes/google/security/jni/crypto_util_test.go
@@ -0,0 +1,46 @@
+package jni
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"reflect"
+	"testing"
+)
+
+func TestCryptoUtilPublicKeyCoder(t *testing.T) {
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("couldn't generate private key: %v", err)
+	}
+	pub := &priv.PublicKey
+	data, err := marshalPKIXPublicKey(pub)
+	if err != nil {
+		t.Fatalf("couldn't marshal public key: %v", err)
+	}
+	pubNew, err := parsePKIXPublicKey(data)
+	if err != nil {
+		t.Fatalf("couldn't parse public key: %v", err)
+	}
+	if !reflect.DeepEqual(pub, pubNew) {
+		t.Fatalf("public keys don't match")
+	}
+}
+
+func TestCryptoUtilPrivateKeyCoder(t *testing.T) {
+	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("couldn't generate private key: %v", err)
+	}
+	data, err := marshalPKCS8PrivateKey(priv)
+	if err != nil {
+		t.Fatalf("couldn't marshal private key: %v", err)
+	}
+	privNew, err := parsePKCS8PrivateKey(data)
+	if err != nil {
+		t.Fatalf("couldn't parse private key: %v", err)
+	}
+	if !reflect.DeepEqual(priv, privNew) {
+		t.Fatalf("private keys don't match")
+	}
+}
diff --git a/runtimes/google/security/jni/jni.go b/runtimes/google/security/jni/jni.go
new file mode 100644
index 0000000..7f89560
--- /dev/null
+++ b/runtimes/google/security/jni/jni.go
@@ -0,0 +1,256 @@
+// +build android
+
+package jni
+
+import (
+	"encoding/asn1"
+	"fmt"
+	"time"
+	"unsafe"
+
+	"veyron/runtimes/google/jni/util"
+	isecurity "veyron/runtimes/google/security"
+	"veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+//
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jobject CallNewECPublicKeyInfoObject(JNIEnv* env, jclass class, jmethodID id, jbyteArray keyX, jbyteArray keyY, jbyteArray encodedKey, jint fieldBitSize) {
+//   return (*env)->NewObject(env, class, id, keyX, keyY, encodedKey, fieldBitSize);
+// }
+// static jobject CallNewCaveatObject(JNIEnv* env, jclass class, jmethodID id, jlong nativePtr) {
+//   return (*env)->NewObject(env, class, id, nativePtr);
+// }
+// static jobject CallNewServiceCaveatObject(JNIEnv* env, jclass class, jmethodID id, jstring service, jobject caveat) {
+//   return (*env)->NewObject(env, class, id, service, caveat);
+// }
+import "C"
+
+var (
+	// Global reference for com.veyron.runtimes.google.security.PublicID class.
+	jPublicIDImplClass C.jclass
+	// Global reference for com.veyron.runtimes.google.security.PublicID$ECPublicKeyInfo class.
+	jECPublicKeyInfoClass C.jclass
+	// Global reference for com.veyron.runtimes.google.security.Caveat class.
+	jCaveatImplClass C.jclass
+	// Global reference for com.veyron.runtimes.google.security.Context class.
+	jContextImplClass C.jclass
+	// Global reference for com.veyron2.security.Context class.
+	jContextClass C.jclass
+	// Global reference for com.veyron2.security.Caveat class.
+	jCaveatClass C.jclass
+	// Global reference for com.veyron2.security.ServiceCaveat class.
+	jServiceCaveatClass C.jclass
+)
+
+// Init initializes the JNI code with the given Java evironment. This method
+// must be called from the main Java thread.
+// NOTE: Because CGO creates package-local types and because this method may be
+// invoked from a different package, Java environment is passed in an empty
+// interface and then cast into the package-local environment type.
+func Init(jEnv interface{}) {
+	env := (*C.JNIEnv)(unsafe.Pointer(util.PtrValue(jEnv)))
+	// Cache global references to all Java classes used by the package.  This is
+	// necessary because JNI gets access to the class loader only in the system
+	// thread, so we aren't able to invoke FindClass in other threads.
+	jPublicIDImplClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/security/PublicID"))
+	jECPublicKeyInfoClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/security/PublicID$ECPublicKeyInfo"))
+	jCaveatImplClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/security/Caveat"))
+	jContextClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron2/security/Context"))
+	jContextImplClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron/runtimes/google/security/Context"))
+	jCaveatClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron2/security/Caveat"))
+	jServiceCaveatClass = C.jclass(util.JFindClassPtrOrDie(env, "com/veyron2/security/ServiceCaveat"))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativeNames
+func Java_com_veyron_runtimes_google_security_PublicID_nativeNames(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong) C.jobjectArray {
+	names := (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).Names()
+	return C.jobjectArray(util.JStringArrayPtr(env, names))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativeMatch
+func Java_com_veyron_runtimes_google_security_PublicID_nativeMatch(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong, jPattern C.jstring) C.jboolean {
+	if (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).Match(security.PrincipalPattern(util.GoString(env, jPattern))) {
+		return C.JNI_TRUE
+	}
+	return C.JNI_FALSE
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativePublicKey
+func Java_com_veyron_runtimes_google_security_PublicID_nativePublicKey(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong) C.jobject {
+	key := (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).PublicKey()
+	encoded, err := marshalPKIXPublicKey(key)
+	if err != nil {
+		util.JThrowV(env, err)
+		return C.jobject(nil)
+	}
+	cid := C.jmethodID(util.JMethodIDPtr(env, jECPublicKeyInfoClass, "<init>", fmt.Sprintf("([%s[%s[%s%s)%s", util.ByteSign, util.ByteSign, util.ByteSign, util.IntSign, util.VoidSign)))
+	return C.CallNewECPublicKeyInfoObject(env, jECPublicKeyInfoClass, cid, C.jbyteArray(util.JByteArrayPtr(env, key.X.Bytes())), C.jbyteArray(util.JByteArrayPtr(env, key.Y.Bytes())), C.jbyteArray(util.JByteArrayPtr(env, encoded)), C.jint(key.Params().BitSize))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativeAuthorize
+func Java_com_veyron_runtimes_google_security_PublicID_nativeAuthorize(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong, jContext C.jobject) C.jlong {
+	id, err := (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).Authorize(newContext(env, jContext))
+	if err != nil {
+		util.JThrowV(env, err)
+		return C.jlong(0)
+	}
+	util.GoRef(&id) // Un-refed when the Java PublicID is finalized.
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativeThirdPartyCaveats
+func Java_com_veyron_runtimes_google_security_PublicID_nativeThirdPartyCaveats(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong) C.jobjectArray {
+	sCaveats := (*(*security.PublicID)(util.Ptr(goPublicIDPtr))).ThirdPartyCaveats()
+	caveatSign := "Lcom/veyron2/security/Caveat;"
+	jServiceCaveats := C.NewObjectArray(env, C.jsize(len(sCaveats)), jServiceCaveatClass, nil)
+	for i, sCaveat := range sCaveats {
+		util.GoRef(&sCaveat) // Un-refed when the Java Caveat object is finalized.
+		cid := C.jmethodID(util.JMethodIDPtr(env, jCaveatImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+		jCaveat := C.CallNewCaveatObject(env, jCaveatImplClass, cid, C.jlong(util.PtrValue(&sCaveat)))
+		scid := C.jmethodID(util.JMethodIDPtr(env, jServiceCaveatClass, "<init>", fmt.Sprintf("(%s%s)%s", util.StringSign, caveatSign, util.VoidSign)))
+		jServiceCaveat := C.CallNewServiceCaveatObject(env, jServiceCaveatClass, scid, C.jstring(util.JStringPtr(env, string(sCaveat.Service))), jCaveat)
+		C.SetObjectArrayElement(env, jServiceCaveats, C.jsize(i), jServiceCaveat)
+	}
+	return jServiceCaveats
+}
+
+//export Java_com_veyron_runtimes_google_security_PublicID_nativeFinalize
+func Java_com_veyron_runtimes_google_security_PublicID_nativeFinalize(env *C.JNIEnv, jPublicID C.jobject, goPublicIDPtr C.jlong) {
+	util.GoUnref((*security.PublicID)(util.Ptr(goPublicIDPtr)))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativeCreate
+func Java_com_veyron_runtimes_google_security_PrivateID_nativeCreate(env *C.JNIEnv, jPrivateIDClass C.jclass, name C.jstring) C.jlong {
+	id, err := isecurity.NewPrivateID(util.GoString(env, name))
+	if err != nil {
+		util.JThrowV(env, err)
+		return C.jlong(0)
+	}
+	util.GoRef(&id) // Un-refed when the Java PrivateID is finalized.
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativePublicID
+func Java_com_veyron_runtimes_google_security_PrivateID_nativePublicID(env *C.JNIEnv, jPrivateID C.jobject, goPrivateIDPtr C.jlong) C.jlong {
+	id := (*(*security.PrivateID)(util.Ptr(goPrivateIDPtr))).PublicID()
+	util.GoRef(&id) // Un-refed when the Java PublicID is finalized.
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativeSign
+func Java_com_veyron_runtimes_google_security_PrivateID_nativeSign(env *C.JNIEnv, jPrivateID C.jobject, goPrivateIDPtr C.jlong, msg C.jbyteArray) C.jbyteArray {
+	s, err := (*(*security.PrivateID)(util.Ptr(goPrivateIDPtr))).Sign(util.GoByteArray(env, msg))
+	if err != nil {
+		util.JThrowV(env, err)
+		return nil
+	}
+	data, err := asn1.Marshal(s)
+	if err != nil {
+		util.JThrowV(env, err)
+		return nil
+	}
+	return C.jbyteArray(util.JByteArrayPtr(env, data))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativeBless
+func Java_com_veyron_runtimes_google_security_PrivateID_nativeBless(env *C.JNIEnv, jPrivateID C.jobject, goPrivateIDPtr C.jlong, jPublicID C.jobject, name C.jstring, jDurationMS C.jlong, jServiceCaveats C.jobjectArray) C.jlong {
+	blessee := newPublicID(env, jPublicID)
+	duration := time.Duration(jDurationMS) * time.Millisecond
+	length := int(C.GetArrayLength(env, C.jarray(jServiceCaveats)))
+	caveats := make([]security.ServiceCaveat, length)
+	for i := 0; i < length; i++ {
+		jServiceCaveat := C.GetObjectArrayElement(env, jServiceCaveats, C.jsize(i))
+		caveats[i] = security.ServiceCaveat{
+			Service: security.PrincipalPattern(util.JStringField(env, jServiceCaveat, "service")),
+			Caveat:  newCaveat(env, jServiceCaveat),
+		}
+	}
+	id, err := (*(*security.PrivateID)(util.Ptr(goPrivateIDPtr))).Bless(blessee, util.GoString(env, name), duration, caveats)
+	if err != nil {
+		util.JThrowV(env, err)
+		return C.jlong(0)
+	}
+	util.GoRef(&id) // Un-refed when the Java PublicID is finalized
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativeDerive
+func Java_com_veyron_runtimes_google_security_PrivateID_nativeDerive(env *C.JNIEnv, jPrivateID C.jobject, goPrivateIDPtr C.jlong, jPublicID C.jobject) C.jlong {
+	id, err := (*(*security.PrivateID)(util.Ptr(goPrivateIDPtr))).Derive(newPublicID(env, jPublicID))
+	if err != nil {
+		util.JThrowV(env, err)
+		return C.jlong(0)
+	}
+	util.GoRef(&id) // Un-refed when the Java PrivateID is finalized.
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_PrivateID_nativeFinalize
+func Java_com_veyron_runtimes_google_security_PrivateID_nativeFinalize(env *C.JNIEnv, jPrivateID C.jobject, goPrivateIDPtr C.jlong) {
+	util.GoUnref((*security.PrivateID)(util.Ptr(goPrivateIDPtr)))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeMethod
+func Java_com_veyron_runtimes_google_security_Context_nativeMethod(env *C.JNIEnv, jContext C.jobject, goContextPtr C.jlong) C.jstring {
+	return C.jstring(util.JStringPtr(env, (*(*security.Context)(util.Ptr(goContextPtr))).Method()))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeName
+func Java_com_veyron_runtimes_google_security_Context_nativeName(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jstring {
+	return C.jstring(util.JStringPtr(env, (*(*security.Context)(util.Ptr(goContextPtr))).Name()))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeSuffix
+func Java_com_veyron_runtimes_google_security_Context_nativeSuffix(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jstring {
+	return C.jstring(util.JStringPtr(env, (*(*security.Context)(util.Ptr(goContextPtr))).Suffix()))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeLabel
+func Java_com_veyron_runtimes_google_security_Context_nativeLabel(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jint {
+	return C.jint((*(*security.Context)(util.Ptr(goContextPtr))).Label())
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeLocalID
+func Java_com_veyron_runtimes_google_security_Context_nativeLocalID(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jlong {
+	id := (*(*security.Context)(util.Ptr(goContextPtr))).LocalID()
+	util.GoRef(&id) // Un-refed when the Java PublicID object is finalized.
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeRemoteID
+func Java_com_veyron_runtimes_google_security_Context_nativeRemoteID(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jlong {
+	id := (*(*security.Context)(util.Ptr(goContextPtr))).RemoteID()
+	util.GoRef(&id)
+	return C.jlong(util.PtrValue(&id))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeLocalEndpoint
+func Java_com_veyron_runtimes_google_security_Context_nativeLocalEndpoint(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jstring {
+	return C.jstring(util.JStringPtr(env, (*(*security.Context)(util.Ptr(goContextPtr))).LocalEndpoint().String()))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeRemoteEndpoint
+func Java_com_veyron_runtimes_google_security_Context_nativeRemoteEndpoint(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) C.jstring {
+	return C.jstring(util.JStringPtr(env, (*(*security.Context)(util.Ptr(goContextPtr))).RemoteEndpoint().String()))
+}
+
+//export Java_com_veyron_runtimes_google_security_Context_nativeFinalize
+func Java_com_veyron_runtimes_google_security_Context_nativeFinalize(env *C.JNIEnv, jServerCall C.jobject, goContextPtr C.jlong) {
+	util.GoUnref((*security.Context)(util.Ptr(goContextPtr)))
+}
+
+//export Java_com_veyron_runtimes_google_security_Caveat_nativeValidate
+func Java_com_veyron_runtimes_google_security_Caveat_nativeValidate(env *C.JNIEnv, jServerCall C.jobject, goCaveatPtr C.jlong, jContext C.jobject) {
+	if err := (*(*security.Caveat)(util.Ptr(goCaveatPtr))).Validate(newContext(env, jContext)); err != nil {
+		util.JThrowV(env, err)
+	}
+}
+
+//export Java_com_veyron_runtimes_google_security_Caveat_nativeFinalize
+func Java_com_veyron_runtimes_google_security_Caveat_nativeFinalize(env *C.JNIEnv, jServerCall C.jobject, goCaveatPtr C.jlong) {
+	util.GoUnref((*security.Caveat)(util.Ptr(goCaveatPtr)))
+}
diff --git a/runtimes/google/security/jni/publicid.go b/runtimes/google/security/jni/publicid.go
new file mode 100644
index 0000000..dd4e778
--- /dev/null
+++ b/runtimes/google/security/jni/publicid.go
@@ -0,0 +1,165 @@
+// +build android
+
+package jni
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"fmt"
+	"math/big"
+	"runtime"
+
+	"veyron/runtimes/google/jni/util"
+	"veyron2/security"
+)
+
+// #cgo LDFLAGS: -ljniwrapper
+// #include "jni_wrapper.h"
+//
+// // CGO doesn't support variadic functions so we have to hard-code these
+// // functions to match the invoking code. Ugh!
+// static jobjectArray CallPublicIDNamesMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (jobjectArray)(*env)->CallObjectMethod(env, obj, id);
+// }
+// static jboolean CallPublicIDMatchMethod(JNIEnv* env, jobject obj, jmethodID id, jstring pattern) {
+// 	return (*env)->CallBooleanMethod(env, obj, id, pattern);
+// }
+// static jobject CallPublicIDPublicKeyMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (*env)->CallObjectMethod(env, obj, id);
+// }
+// static jobject CallPublicIDAuthorizeMethod(JNIEnv* env, jobject obj, jmethodID id, jobject context) {
+// 	return (*env)->CallObjectMethod(env, obj, id, context);
+// }
+// static jobjectArray CallPublicIDThirdPartyCaveatsMethod(JNIEnv* env, jobject obj, jmethodID id) {
+// 	return (jobjectArray)(*env)->CallObjectMethod(env, obj, id);
+// }
+// static jobject CallPublicIDNewContextObject(JNIEnv* env, jclass class, jmethodID id, jlong goContextPtr) {
+// 	return (*env)->NewObject(env, class, id, goContextPtr);
+// }
+// static jobject CallPublicIDGetKeyInfoMethod(JNIEnv* env, jclass class, jmethodID id, jobject key) {
+// 	return (*env)->CallStaticObjectMethod(env, class, id, key);
+// }
+import "C"
+
+func newPublicID(env *C.JNIEnv, jPublicID C.jobject) *publicID {
+	// We cannot cache Java environments as they are only valid in the current
+	// thread.  We can, however, cache the Java VM and obtain an environment
+	// from it in whatever thread happens to be running at the time.
+	var jVM *C.JavaVM
+	if status := C.GetJavaVM(env, &jVM); status != 0 {
+		panic("couldn't get Java VM from the (Java) environment")
+	}
+	// Reference Java public id; it will be de-referenced when the go public id
+	// created below is garbage-collected (through the finalizer callback we
+	// setup just below).
+	jPublicID = C.NewGlobalRef(env, jPublicID)
+	id := &publicID{
+		jVM:       jVM,
+		jPublicID: jPublicID,
+	}
+	runtime.SetFinalizer(id, func(id *publicID) {
+		var env *C.JNIEnv
+		C.AttachCurrentThread(id.jVM, &env, nil)
+		defer C.DetachCurrentThread(id.jVM)
+		C.DeleteGlobalRef(env, id.jPublicID)
+	})
+	return id
+}
+
+type publicID struct {
+	jVM       *C.JavaVM
+	jPublicID C.jobject
+}
+
+func (id *publicID) Names() []string {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(id.jVM, &env, nil)
+	defer C.DetachCurrentThread(id.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "names", fmt.Sprintf("()[%s", util.StringSign)))
+	names := C.CallPublicIDNamesMethod(env, id.jPublicID, mid)
+	ret := make([]string, int(C.GetArrayLength(env, C.jarray(names))))
+	for i := 0; i < len(ret); i++ {
+		ret[i] = util.GoString(env, C.GetObjectArrayElement(env, names, C.jsize(i)))
+	}
+	return ret
+}
+
+func (id *publicID) Match(pattern security.PrincipalPattern) bool {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(id.jVM, &env, nil)
+	defer C.DetachCurrentThread(id.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "match", fmt.Sprintf("(%s)%s", util.StringSign, util.BoolSign)))
+	return C.CallPublicIDMatchMethod(env, id.jPublicID, mid, C.jstring(util.JStringPtr(env, string(pattern)))) == C.JNI_TRUE
+}
+
+func (id *publicID) PublicKey() *ecdsa.PublicKey {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(id.jVM, &env, nil)
+	defer C.DetachCurrentThread(id.jVM)
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "publicKey", fmt.Sprintf("()%s", util.ObjectSign)))
+	jPublicKey := C.CallPublicIDPublicKeyMethod(env, id.jPublicID, mid)
+	return newPublicKey(env, jPublicKey)
+}
+
+func (id *publicID) Authorize(context security.Context) (security.PublicID, error) {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(id.jVM, &env, nil)
+	defer C.DetachCurrentThread(id.jVM)
+	util.GoRef(&context) // un-refed when the Java Context object is finalized.
+	contextSign := "Lcom/veyron2/security/Context;"
+	publicIDSign := "Lcom/veyron2/security/PublicID;"
+	cid := C.jmethodID(util.JMethodIDPtr(env, jContextImplClass, "<init>", fmt.Sprintf("(%s)%s", util.LongSign, util.VoidSign)))
+	jContext := C.CallPublicIDNewContextObject(env, jContextImplClass, cid, C.jlong(util.PtrValue(&context)))
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "authorize", fmt.Sprintf("(%s)%s", contextSign, publicIDSign)))
+	jPublicID := C.CallPublicIDAuthorizeMethod(env, id.jPublicID, mid, jContext)
+	if err := util.JExceptionMsg(env); err != nil {
+		return nil, err
+	}
+	return newPublicID(env, jPublicID), nil
+}
+
+func (id *publicID) ThirdPartyCaveats() []security.ServiceCaveat {
+	var env *C.JNIEnv
+	C.AttachCurrentThread(id.jVM, &env, nil)
+	defer C.DetachCurrentThread(id.jVM)
+	serviceCaveatSign := "Lcom/veyron2/security/ServiceCaveat;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, C.GetObjectClass(env, id.jPublicID), "thirdPartyCaveats", fmt.Sprintf("()[%s", serviceCaveatSign)))
+	jServiceCaveats := C.CallPublicIDThirdPartyCaveatsMethod(env, id.jPublicID, mid)
+	length := int(C.GetArrayLength(env, C.jarray(jServiceCaveats)))
+	sCaveats := make([]security.ServiceCaveat, length)
+	for i := 0; i < length; i++ {
+		jServiceCaveat := C.GetObjectArrayElement(env, jServiceCaveats, C.jsize(i))
+		sCaveats[i] = security.ServiceCaveat{
+			Service: security.PrincipalPattern(util.JStringField(env, jServiceCaveat, "service")),
+			Caveat:  newCaveat(env, jServiceCaveat),
+		}
+	}
+	return sCaveats
+}
+
+func newPublicKey(env *C.JNIEnv, jPublicKey C.jobject) *ecdsa.PublicKey {
+	keySign := "Ljava/security/interfaces/ECPublicKey;"
+	keyInfoSign := "Lcom/veyron/runtimes/google/security/JNIPublicID$ECPublicKeyInfo;"
+	mid := C.jmethodID(util.JMethodIDPtr(env, jPublicIDImplClass, "getKeyInfo", fmt.Sprintf("(%s)%s", keySign, keyInfoSign)))
+	jKeyInfo := C.CallPublicIDGetKeyInfoMethod(env, jPublicIDImplClass, mid, jPublicKey)
+	keyX := new(big.Int).SetBytes(util.JByteArrayField(env, jKeyInfo, "keyX"))
+	keyY := new(big.Int).SetBytes(util.JByteArrayField(env, jKeyInfo, "keyY"))
+	var curve elliptic.Curve
+	switch util.JIntField(env, jKeyInfo, "curveFieldBitSize") {
+	case 224:
+		curve = elliptic.P224()
+	case 256:
+		curve = elliptic.P256()
+	case 384:
+		curve = elliptic.P384()
+	case 521:
+		curve = elliptic.P521()
+	default: // Unknown curve
+		return nil
+	}
+	return &ecdsa.PublicKey{
+		Curve: curve,
+		X:     keyX,
+		Y:     keyY,
+	}
+}
diff --git a/services/mgmt/node/impl/const.go b/services/mgmt/node/impl/const.go
index 5615eee..c3c3d7b 100644
--- a/services/mgmt/node/impl/const.go
+++ b/services/mgmt/node/impl/const.go
@@ -1,6 +1,9 @@
 package impl
 
 const (
+	// BinaryEnv is the name of the environment variable that holds the
+	// object name used for obtaining the node manager binary.
+	BinaryEnv = "VEYRON_NM_BINARY"
 	// PreviousEnv is the name of the environment variable that holds
 	// the path to the workspace that contains the previous version of
 	// the node manager.
diff --git a/services/mgmt/node/impl/invoker.go b/services/mgmt/node/impl/invoker.go
index 9e4f19c..a0badb6 100644
--- a/services/mgmt/node/impl/invoker.go
+++ b/services/mgmt/node/impl/invoker.go
@@ -384,6 +384,7 @@
 		return errOperationFailed
 	}
 	output := "#!/bin/bash\n"
+	output += BinaryEnv + "=" + envelope.Binary + " "
 	output += PreviousEnv + "=" + filepath.Dir(path) + " "
 	output += strings.Join(envelope.Env, " ") + " "
 	output += filepath.Join(workspace, "noded") + " "
diff --git a/services/mgmt/node/noded/main.go b/services/mgmt/node/noded/main.go
index f40f457..9deb603 100644
--- a/services/mgmt/node/noded/main.go
+++ b/services/mgmt/node/noded/main.go
@@ -17,6 +17,15 @@
 	"veyron2/vlog"
 )
 
+func generateEnvelope() *application.Envelope {
+	return &application.Envelope{
+		Args:   os.Args,
+		Binary: os.Getenv(impl.BinaryEnv),
+		Env:    os.Environ(),
+		Title:  application.NodeManagerTitle,
+	}
+}
+
 func main() {
 	// TODO(rthellend): Remove the address and protocol flags when the config manager is working.
 	var address, protocol, publishAs string
@@ -38,7 +47,7 @@
 	if err != nil {
 		vlog.Fatalf("Listen(%v, %v) failed: %v", protocol, address, err)
 	}
-	suffix, envelope := "", &application.Envelope{}
+	suffix, envelope := "", generateEnvelope()
 	name := naming.MakeTerminal(naming.JoinAddressName(endpoint.String(), suffix))
 	vlog.VI(0).Infof("Node manager name: %v", name)
 	// TODO(jsimsa): Replace <PreviousEnv> with a command-line flag when
