v.io/x/jni: support for android lifecycle changes

MultiPart: 2/2

Change-Id: I11412492302888fc61428b17d75e812b876514f6
diff --git a/impl/google/discovery/jni.go b/impl/google/discovery/jni.go
index deaf818..0a6d9d5 100644
--- a/impl/google/discovery/jni.go
+++ b/impl/google/discovery/jni.go
@@ -152,7 +152,7 @@
 	jVisibility := jutil.Object(uintptr(unsafe.Pointer(jVisibilityObj)))
 	jStartCallback := jutil.Object(uintptr(unsafe.Pointer(jStartCallbackObj)))
 	jDoneCallback := jutil.Object(uintptr(unsafe.Pointer(jDoneCallbackObj)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.CallbackOnFailure(env, jStartCallback, err)
 		return
@@ -186,7 +186,7 @@
 //export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeScan
 func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeScan(jenv *C.JNIEnv, jDiscovery C.jobject, goDiscoveryPtr C.jlong, jContext C.jobject, jQuery C.jstring) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/impl/google/namespace/jni.go b/impl/google/namespace/jni.go
index ccfc2da..e6ad0f1 100644
--- a/impl/google/namespace/jni.go
+++ b/impl/google/namespace/jni.go
@@ -59,7 +59,7 @@
 }
 
 func globArgs(env jutil.Env, jContext C.jobject, jPattern C.jstring, jOptions C.jobject) (context *context.T, pattern string, opts []naming.NamespaceOpt, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -115,7 +115,7 @@
 }
 
 func mountArgs(env jutil.Env, jContext C.jobject, jName, jServer C.jstring, jDuration, jOptions C.jobject) (context *context.T, name, server string, duration time.Duration, options []naming.NamespaceOpt, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -147,7 +147,7 @@
 func unmountArgs(env jutil.Env, jName, jServer C.jstring, jContext, jOptions C.jobject) (name, server string, context *context.T, options []naming.NamespaceOpt, err error) {
 	name = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
 	server = jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jServer))))
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -171,7 +171,7 @@
 }
 
 func deleteArgs(env jutil.Env, jContext, jOptions C.jobject, jName C.jstring, jDeleteSubtree C.jboolean) (context *context.T, options []naming.NamespaceOpt, name string, deleteSubtree bool, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -200,7 +200,7 @@
 }
 
 func resolveArgs(env jutil.Env, jName C.jstring, jContext, jOptions C.jobject) (context *context.T, name string, options []naming.NamespaceOpt, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -244,7 +244,7 @@
 }
 
 func resolveToMountTableArgs(env jutil.Env, jContext, jOptions C.jobject, jName C.jstring) (context *context.T, options []naming.NamespaceOpt, name string, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -291,7 +291,7 @@
 func Java_io_v_impl_google_namespace_NamespaceImpl_nativeFlushCacheEntry(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jName C.jstring) C.jboolean {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
-	context, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return C.JNI_FALSE
@@ -320,7 +320,7 @@
 }
 
 func setPermissionsArgs(env jutil.Env, jContext, jPermissions C.jobject, jName, jVersion C.jstring, jOptions C.jobject) (context *context.T, permissions access.Permissions, name, version string, options []naming.NamespaceOpt, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
@@ -350,7 +350,7 @@
 }
 
 func getPermissionsArgs(env jutil.Env, jContext C.jobject, jName C.jstring, jOptions C.jobject) (context *context.T, name string, options []naming.NamespaceOpt, err error) {
-	context, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err = jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		return
 	}
diff --git a/impl/google/rpc/invoker.go b/impl/google/rpc/invoker.go
index a0885bb..e488c9f 100644
--- a/impl/google/rpc/invoker.go
+++ b/impl/google/rpc/invoker.go
@@ -89,7 +89,7 @@
 
 func (i *invoker) Invoke(ctx *context.T, call rpc.StreamServerCall, method string, argptrs []interface{}) (results []interface{}, err error) {
 	env, freeFunc := jutil.GetEnv()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		freeFunc()
 		return nil, err
@@ -135,7 +135,7 @@
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
 
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -163,7 +163,7 @@
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
 
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return signature.Method{}, err
 	}
diff --git a/impl/google/rpc/jni.go b/impl/google/rpc/jni.go
index d365100..e5e5c03 100644
--- a/impl/google/rpc/jni.go
+++ b/impl/google/rpc/jni.go
@@ -221,16 +221,6 @@
 	return C.jobject(unsafe.Pointer(jStatus))
 }
 
-//export Java_io_v_impl_google_rpc_ServerImpl_nativeStop
-func Java_io_v_impl_google_rpc_ServerImpl_nativeStop(jenv *C.JNIEnv, jServer C.jobject, goPtr C.jlong) {
-	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	s := (*rpc.Server)(jutil.NativePtr(goPtr))
-	if err := (*s).Stop(); err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-}
-
 //export Java_io_v_impl_google_rpc_ServerImpl_nativeFinalize
 func Java_io_v_impl_google_rpc_ServerImpl_nativeFinalize(jenv *C.JNIEnv, jServer C.jobject, goPtr C.jlong) {
 	jutil.GoUnref(jutil.NativePtr(goPtr))
@@ -281,7 +271,7 @@
 	name := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jName))))
 	method := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jMethod))))
 	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
-	context, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	context, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.CallbackOnFailure(env, jCallback, err)
 		return
diff --git a/impl/google/rpc/protocols/bt/bt_android.go b/impl/google/rpc/protocols/bt/bt_android.go
index b6f07eb..275cc12 100644
--- a/impl/google/rpc/protocols/bt/bt_android.go
+++ b/impl/google/rpc/protocols/bt/bt_android.go
@@ -47,7 +47,7 @@
 
 func (btProtocol) Dial(ctx *context.T, protocol, address string, timeout time.Duration) (flow.Conn, error) {
 	env, freeFunc := jutil.GetEnv()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		freeFunc()
 		return nil, err
@@ -69,7 +69,7 @@
 func (btProtocol) Listen(ctx *context.T, protocol, address string) (flow.Listener, error) {
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return nil, err
 	}
diff --git a/impl/google/rt/jni.go b/impl/google/rt/jni.go
index 30ebd89..90c1855 100644
--- a/impl/google/rt/jni.go
+++ b/impl/google/rt/jni.go
@@ -52,7 +52,7 @@
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	ctx, shutdownFunc := v23.Init()
 	ctx = context.WithValue(ctx, shutdownKey{}, shutdownFunc)
-	jCtx, err := jcontext.JavaContext(env, ctx)
+	jCtx, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -63,7 +63,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeShutdown
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeShutdown(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 	}
@@ -76,7 +76,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNewClient
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNewClient(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject, jOptions C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -87,7 +87,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -98,7 +98,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetClient
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetClient(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -115,7 +115,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNewServer
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNewServer(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject, jName C.jstring, jDispatcher C.jobject, jLameDuck C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -141,7 +141,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -158,7 +158,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithPrincipal
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithPrincipal(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject, jPrincipal C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -173,7 +173,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -184,7 +184,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetPrincipal
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetPrincipal(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -201,7 +201,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNamespace
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithNamespace(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject, jRoots C.jobjectArray) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -217,7 +217,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -228,7 +228,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetNamespace
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetNamespace(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -245,7 +245,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithListenSpec
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeWithListenSpec(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject, jSpec C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, cancel, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -256,7 +256,7 @@
 		return nil
 	}
 	newCtx := v23.WithListenSpec(ctx, spec)
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -267,7 +267,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetListenSpec
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetListenSpec(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -284,7 +284,7 @@
 //export Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetDiscovery
 func Java_io_v_impl_google_rt_VRuntimeImpl_nativeGetDiscovery(jenv *C.JNIEnv, jRuntime C.jclass, jContext C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/impl/google/services/groups/jni.go b/impl/google/services/groups/jni.go
index a08b2c3..16e9708 100644
--- a/impl/google/services/groups/jni.go
+++ b/impl/google/services/groups/jni.go
@@ -78,7 +78,7 @@
 	}
 
 	// Start the server.
-	ctx, err := jcontext.GoContext(env, jCtx)
+	ctx, cancel, err := jcontext.GoContext(env, jCtx)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -93,7 +93,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/impl/google/services/mounttable/jni.go b/impl/google/services/mounttable/jni.go
index 1cbec41..85723af 100644
--- a/impl/google/services/mounttable/jni.go
+++ b/impl/google/services/mounttable/jni.go
@@ -115,7 +115,7 @@
 	}
 
 	// Start the mounttable server.
-	ctx, err := jcontext.GoContext(env, jCtx)
+	ctx, cancel, err := jcontext.GoContext(env, jCtx)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -130,7 +130,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/impl/google/services/syncbase/jni.go b/impl/google/services/syncbase/jni.go
index 2179e9e..7bab0f0 100644
--- a/impl/google/services/syncbase/jni.go
+++ b/impl/google/services/syncbase/jni.go
@@ -88,7 +88,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	ctx, err := jcontext.GoContext(env, jCtx)
+	ctx, cancel, err := jcontext.GoContext(env, jCtx)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -114,7 +114,7 @@
 		jutil.JThrowV(env, err)
 		return nil
 	}
-	jNewCtx, err := jcontext.JavaContext(env, newCtx)
+	jNewCtx, err := jcontext.JavaContext(env, newCtx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/jni.go b/jni.go
index 2c01ec1..515c840 100644
--- a/jni.go
+++ b/jni.go
@@ -20,8 +20,8 @@
 // #include "jni.h"
 import "C"
 
-//export Java_io_v_v23_V_nativeInitGlobal
-func Java_io_v_v23_V_nativeInitGlobal(jenv *C.JNIEnv, jVClass C.jclass) {
+//export Java_io_v_v23_V_nativeInitGlobalShared
+func Java_io_v_v23_V_nativeInitGlobalShared(jenv *C.JNIEnv, jVClass C.jclass) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	// Ignore all args except for the first one.
 	if len(os.Args) > 1 {
diff --git a/jni_android.go b/jni_android.go
index fadfa0e..d853f68 100644
--- a/jni_android.go
+++ b/jni_android.go
@@ -20,8 +20,8 @@
 // #include "jni.h"
 import "C"
 
-//export Java_io_v_android_v23_V_nativeInitAndroid
-func Java_io_v_android_v23_V_nativeInitAndroid(jenv *C.JNIEnv, jVClass C.jclass, jAndroidContext C.jobject, jOptions C.jobject) {
+//export Java_io_v_android_v23_V_nativeInitGlobalAndroid
+func Java_io_v_android_v23_V_nativeInitGlobalAndroid(jenv *C.JNIEnv, jVClass C.jclass, jAndroidContext C.jobject, jOptions C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	jOpts := jutil.Object(uintptr(unsafe.Pointer(jOptions)))
 
diff --git a/jni_java.go b/jni_java.go
index 8fd18ac..677982d 100644
--- a/jni_java.go
+++ b/jni_java.go
@@ -18,8 +18,8 @@
 // #include "jni.h"
 import "C"
 
-//export Java_io_v_v23_V_nativeInitJava
-func Java_io_v_v23_V_nativeInitJava(jenv *C.JNIEnv, jVClass C.jclass, jOptions C.jobject) {
+//export Java_io_v_v23_V_nativeInitGlobalJava
+func Java_io_v_v23_V_nativeInitGlobalJava(jenv *C.JNIEnv, jVClass C.jclass, jOptions C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	jOpts := jutil.Object(uintptr(unsafe.Pointer(jOptions)))
 
diff --git a/libs/discovery/plugin.go b/libs/discovery/plugin.go
index 65fcb48..c3825ed 100644
--- a/libs/discovery/plugin.go
+++ b/libs/discovery/plugin.go
@@ -62,7 +62,7 @@
 func (p *plugin) Advertise(ctx *context.T, ad discovery.Advertisement, done func()) error {
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return err
 	}
@@ -81,7 +81,7 @@
 func (p *plugin) Scan(ctx *context.T, serviceUuid discovery.Uuid, ch chan<- discovery.Advertisement, done func()) error {
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return err
 	}
diff --git a/v23/context/jni.go b/v23/context/jni.go
index 045099c..7dbd4e1 100644
--- a/v23/context/jni.go
+++ b/v23/context/jni.go
@@ -7,6 +7,7 @@
 package context
 
 import (
+	"errors"
 	"unsafe"
 
 	"v.io/v23/context"
@@ -21,10 +22,6 @@
 	classSign = jutil.ClassSign("java.lang.Class")
 	// Global reference for io.v.v23.context.VContext class.
 	jVContextClass jutil.Class
-	// Global reference for io.v.v23.context.CancelableVContext class.
-	jCancelableVContextClass jutil.Class
-	// Global reference for java.jutil.concurrent.CountDownLatch class.
-	jCountDownLatchClass jutil.Class
 )
 
 // Init initializes the JNI code with the given Java environment. This method
@@ -38,14 +35,6 @@
 	if err != nil {
 		return err
 	}
-	jCancelableVContextClass, err = jutil.JFindClass(env, "io/v/v23/context/CancelableVContext")
-	if err != nil {
-		return err
-	}
-	jCountDownLatchClass, err = jutil.JFindClass(env, "java/util/concurrent/CountDownLatch")
-	if err != nil {
-		return err
-	}
 	return nil
 }
 
@@ -53,7 +42,7 @@
 func Java_io_v_v23_context_VContext_nativeCreate(jenv *C.JNIEnv, jVContext C.jclass) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	ctx, _ := context.RootContext()
-	jContext, err := JavaContext(env, ctx)
+	jContext, err := JavaContext(env, ctx, nil)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -61,6 +50,19 @@
 	return C.jobject(unsafe.Pointer(jContext))
 }
 
+//export Java_io_v_v23_context_VContext_nativeCancel
+func Java_io_v_v23_context_VContext_nativeCancel(jenv *C.JNIEnv, jVContext C.jobject, goCancelPtr C.jlong) {
+	(*(*context.CancelFunc)(jutil.NativePtr(goCancelPtr)))()
+}
+
+//export Java_io_v_v23_context_VContext_nativeIsCanceled
+func Java_io_v_v23_context_VContext_nativeIsCanceled(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong) C.jboolean {
+	if (*(*context.T)(jutil.NativePtr(goPtr))).Err() == nil {
+		return C.JNI_FALSE
+	}
+	return C.JNI_TRUE
+}
+
 //export Java_io_v_v23_context_VContext_nativeDeadline
 func Java_io_v_v23_context_VContext_nativeDeadline(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
@@ -77,15 +79,18 @@
 }
 
 //export Java_io_v_v23_context_VContext_nativeDone
-func Java_io_v_v23_context_VContext_nativeDone(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong) C.jobject {
+func Java_io_v_v23_context_VContext_nativeDone(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong, jCallbackObj C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
+	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
 	c := (*(*context.T)(jutil.NativePtr(goPtr))).Done()
-	jCounter, err := JavaCountDownLatch(env, c)
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return nil
+	if c == nil {
+		jutil.CallbackOnFailure(env, jCallback, errors.New("Context isn't cancelable"))
+		return
 	}
-	return C.jobject(unsafe.Pointer(jCounter))
+	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
+		<-c
+		return jutil.NullObject, nil
+	})
 }
 
 //export Java_io_v_v23_context_VContext_nativeValue
@@ -105,7 +110,7 @@
 func Java_io_v_v23_context_VContext_nativeWithCancel(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	ctx, cancelFunc := context.WithCancel((*context.T)(jutil.NativePtr(goPtr)))
-	jCtx, err := JavaCancelableContext(env, ctx, cancelFunc)
+	jCtx, err := JavaContext(env, ctx, cancelFunc)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -122,7 +127,7 @@
 		return nil
 	}
 	ctx, cancelFunc := context.WithDeadline((*context.T)(jutil.NativePtr(goPtr)), deadline)
-	jCtx, err := JavaCancelableContext(env, ctx, cancelFunc)
+	jCtx, err := JavaContext(env, ctx, cancelFunc)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -139,7 +144,7 @@
 		return nil
 	}
 	ctx, cancelFunc := context.WithTimeout((*context.T)(jutil.NativePtr(goPtr)), timeout)
-	jCtx, err := JavaCancelableContext(env, ctx, cancelFunc)
+	jCtx, err := JavaContext(env, ctx, cancelFunc)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -148,7 +153,7 @@
 }
 
 //export Java_io_v_v23_context_VContext_nativeWithValue
-func Java_io_v_v23_context_VContext_nativeWithValue(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong, jKey C.jobject, jValue C.jobject) C.jobject {
+func Java_io_v_v23_context_VContext_nativeWithValue(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong, goCancelPtr C.jlong, jKey C.jobject, jValue C.jobject) C.jobject {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	key, err := GoContextKey(env, jutil.Object(uintptr(unsafe.Pointer(jKey))))
 	if err != nil {
@@ -161,7 +166,11 @@
 		return nil
 	}
 	ctx := context.WithValue((*context.T)(jutil.NativePtr(goPtr)), key, value)
-	jCtx, err := JavaContext(env, ctx)
+	var cancel context.CancelFunc
+	if goCancelPtr != 0 {
+		cancel = (*(*context.CancelFunc)(jutil.NativePtr(goCancelPtr)))
+	}
+	jCtx, err := JavaContext(env, ctx, cancel)
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -170,18 +179,10 @@
 }
 
 //export Java_io_v_v23_context_VContext_nativeFinalize
-func Java_io_v_v23_context_VContext_nativeFinalize(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong) {
+func Java_io_v_v23_context_VContext_nativeFinalize(jenv *C.JNIEnv, jVContext C.jobject, goPtr C.jlong, goCancelPtr C.jlong) {
 	jutil.GoUnref(jutil.NativePtr(goPtr))
-}
-
-//export Java_io_v_v23_context_CancelableVContext_nativeCancel
-func Java_io_v_v23_context_CancelableVContext_nativeCancel(jenv *C.JNIEnv, jCancelableVContext C.jobject, goCancelPtr C.jlong) {
 	if goCancelPtr != 0 {
-		(*(*context.CancelFunc)(jutil.NativePtr(goCancelPtr)))()
+		jutil.GoUnref(jutil.NativePtr(goCancelPtr))
 	}
-}
 
-//export Java_io_v_v23_context_CancelableVContext_nativeFinalize
-func Java_io_v_v23_context_CancelableVContext_nativeFinalize(jenv *C.JNIEnv, jCancelableVContext C.jobject, goCancelPtr C.jlong) {
-	jutil.GoUnref(jutil.NativePtr(goCancelPtr))
 }
diff --git a/v23/context/util.go b/v23/context/util.go
index 7ea511b..c2d93e4 100644
--- a/v23/context/util.go
+++ b/v23/context/util.go
@@ -8,7 +8,6 @@
 
 import (
 	"fmt"
-	"log"
 	"runtime"
 
 	"v.io/v23/context"
@@ -25,65 +24,43 @@
 }
 
 // JavaContext converts the provided Go Context into a Java VContext.
-func JavaContext(env jutil.Env, ctx *context.T) (jutil.Object, error) {
-	jCtx, err := jutil.NewObject(env, jVContextClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(ctx)))
+// If the provided cancel function is nil, Java VContext won't be
+// cancelable.
+func JavaContext(env jutil.Env, ctx *context.T, cancel context.CancelFunc) (jutil.Object, error) {
+	var cancelPtr int64
+	if cancel != nil {
+		cancelPtr = int64(jutil.PtrValue(&cancel))
+	}
+	jCtx, err := jutil.NewObject(env, jVContextClass, []jutil.Sign{jutil.LongSign, jutil.LongSign}, int64(jutil.PtrValue(ctx)), cancelPtr)
 	if err != nil {
 		return jutil.NullObject, err
 	}
 	jutil.GoRef(ctx) // Un-refed when the Java context object is finalized.
+	if cancel != nil {
+		jutil.GoRef(&cancel)
+	}
 	return jCtx, err
 }
 
-// JavaCancelableContext converts the provided Go Context and its associated cancel function
-// into a Java CancelableVContext.
-func JavaCancelableContext(env jutil.Env, ctx *context.T, cancel context.CancelFunc) (jutil.Object, error) {
-	if cancel == nil {
-		return jutil.NullObject, fmt.Errorf("Cannot create CancelableVContext with nil cancel function")
-	}
-	jCtx, err := jutil.NewObject(env, jCancelableVContextClass, []jutil.Sign{jutil.LongSign, jutil.LongSign}, int64(jutil.PtrValue(ctx)), int64(jutil.PtrValue(&cancel)))
-	if err != nil {
-		return jutil.NullObject, err
-	}
-	jutil.GoRef(ctx)     // Un-refed when the Java context object is finalized.
-	jutil.GoRef(&cancel) // Un-refed when the Java context object is finalized.
-	return jCtx, err
-}
-
-// GoContext converts the provided Java VContext into a Go context.
-func GoContext(env jutil.Env, jContext jutil.Object) (*context.T, error) {
+// GoContext converts the provided Java VContext into a Go context and
+// a cancel function (if any) that can be used to cancel the context.
+func GoContext(env jutil.Env, jContext jutil.Object) (*context.T, context.CancelFunc, error) {
 	if jContext.IsNull() {
-		return nil, nil
+		return nil, nil, nil
 	}
 	goCtxPtr, err := jutil.CallLongMethod(env, jContext, "nativePtr", nil)
 	if err != nil {
-		return nil, err
+		return nil, nil, err
 	}
-	return (*context.T)(jutil.NativePtr(goCtxPtr)), nil
-}
-
-// JavaCountDownLatch creates a Java CountDownLatch object with an initial count
-// of one that counts down (to zero) the moment the value is sent on the
-// provided Go channel or if the channel gets closed.
-func JavaCountDownLatch(env jutil.Env, c <-chan struct{}) (jutil.Object, error) {
-	if c == nil {
-		return jutil.NullObject, nil
-	}
-	jLatch, err := jutil.NewObject(env, jCountDownLatchClass, []jutil.Sign{jutil.IntSign}, int(1))
+	goCancelPtr, err := jutil.CallLongMethod(env, jContext, "nativeCancelPtr", nil)
 	if err != nil {
-		return jutil.NullObject, err
+		return nil, nil, err
 	}
-	// Reference Java CountDownLatch; it will be de-referenced when the goroutine below exits.
-	jLatchGlobal := jutil.NewGlobalRef(env, jLatch)
-	go func() {
-		<-c
-		env, freeFunc := jutil.GetEnv()
-		defer freeFunc()
-		if err := jutil.CallVoidMethod(env, jLatchGlobal, "countDown", nil); err != nil {
-			log.Printf("Error decrementing CountDownLatch: %v", err)
-		}
-		jutil.DeleteGlobalRef(env, jLatchGlobal)
-	}()
-	return jLatch, nil
+	var cancel context.CancelFunc
+	if goCancelPtr != 0 {
+		cancel = *(*context.CancelFunc)(jutil.NativePtr(goCancelPtr))
+	}
+	return (*context.T)(jutil.NativePtr(goCtxPtr)), cancel, nil
 }
 
 // GoContextKey creates a Go Context key given the Java Context key.  The
diff --git a/v23/security/access/jni.go b/v23/security/access/jni.go
index 15219d4..0cd9955 100644
--- a/v23/security/access/jni.go
+++ b/v23/security/access/jni.go
@@ -70,7 +70,7 @@
 //export Java_io_v_v23_security_access_AccessList_nativeAuthorize
 func Java_io_v_v23_security_access_AccessList_nativeAuthorize(jenv *C.JNIEnv, jAccessList C.jobject, goPtr C.jlong, jCtx C.jobject, jCall C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return
@@ -120,7 +120,7 @@
 //export Java_io_v_v23_security_access_PermissionsAuthorizer_nativeAuthorize
 func Java_io_v_v23_security_access_PermissionsAuthorizer_nativeAuthorize(jenv *C.JNIEnv, jPermissionsAuthorizer C.jobject, goPtr C.jlong, jContext C.jobject, jCall C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return
diff --git a/v23/security/authorizer.go b/v23/security/authorizer.go
index 6a11f86..eb21f2a 100644
--- a/v23/security/authorizer.go
+++ b/v23/security/authorizer.go
@@ -46,7 +46,7 @@
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
 
-	jCtx, err := jcontext.JavaContext(env, ctx)
+	jCtx, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		return err
 	}
diff --git a/v23/security/call.go b/v23/security/call.go
index 229e5f2..9d7dd60 100644
--- a/v23/security/call.go
+++ b/v23/security/call.go
@@ -192,7 +192,7 @@
 	if err != nil {
 		log.Printf("Couldn't get Java Vanadium context: %v", err)
 	}
-	ctx, err := jcontext.GoContext(env, jCtx)
+	ctx, _, err := jcontext.GoContext(env, jCtx)
 	if err != nil {
 		log.Printf("Couldn't convert Java Vanadium context to Go: %v", err)
 	}
diff --git a/v23/security/caveats.go b/v23/security/caveats.go
index d49b0b5..2ecf8a1 100644
--- a/v23/security/caveats.go
+++ b/v23/security/caveats.go
@@ -29,7 +29,7 @@
 func caveatValidator(context *context.T, call security.Call, sets [][]security.Caveat) []error {
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
-	jContext, err := jcontext.JavaContext(env, context)
+	jContext, err := jcontext.JavaContext(env, context, nil)
 	if err != nil {
 		return errors(err, len(sets))
 	}
diff --git a/v23/security/jni.go b/v23/security/jni.go
index aaa3593..9bfbf45 100644
--- a/v23/security/jni.go
+++ b/v23/security/jni.go
@@ -913,7 +913,7 @@
 		jutil.JThrowV(env, err)
 		return
 	}
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return
@@ -937,7 +937,7 @@
 //export Java_io_v_v23_security_VSecurity_nativeGetRemoteBlessingNames
 func Java_io_v_v23_security_VSecurity_nativeGetRemoteBlessingNames(jenv *C.JNIEnv, jVSecurityClass C.jclass, jCtx C.jobject, jCall C.jobject) C.jobjectArray {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -959,7 +959,7 @@
 //export Java_io_v_v23_security_VSecurity_nativeGetSigningBlessingNames
 func Java_io_v_v23_security_VSecurity_nativeGetSigningBlessingNames(jenv *C.JNIEnv, jVSecurityClass C.jclass, jCtx C.jobject, jPrincipal C.jobject, jBlessings C.jobject) C.jobjectArray {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
@@ -986,7 +986,7 @@
 //export Java_io_v_v23_security_VSecurity_nativeGetLocalBlessingNames
 func Java_io_v_v23_security_VSecurity_nativeGetLocalBlessingNames(jenv *C.JNIEnv, jVSecurityClass C.jclass, jCtx C.jobject, jCall C.jobject) C.jobjectArray {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jCtx))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return nil
diff --git a/v23/services/groups/jni.go b/v23/services/groups/jni.go
index de60170..c671d0d 100644
--- a/v23/services/groups/jni.go
+++ b/v23/services/groups/jni.go
@@ -51,7 +51,7 @@
 //export Java_io_v_v23_services_groups_PermissionsAuthorizer_nativeAuthorize
 func Java_io_v_v23_services_groups_PermissionsAuthorizer_nativeAuthorize(jenv *C.JNIEnv, jPermissionsAuthorizer C.jobject, goPtr C.jlong, jContext C.jobject, jCall C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.JThrowV(env, err)
 		return
diff --git a/v23/syncbase/nosql/jni.go b/v23/syncbase/nosql/jni.go
index 0f11c2a..8cad8db 100644
--- a/v23/syncbase/nosql/jni.go
+++ b/v23/syncbase/nosql/jni.go
@@ -92,7 +92,7 @@
 		jutil.CallbackOnFailure(env, jCallback, err)
 		return
 	}
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.CallbackOnFailure(env, jCallback, err)
 		return
@@ -119,7 +119,7 @@
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
 	jdb := (*jniDatabase)(jutil.NativePtr(goPtr))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+	ctx, _, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
 		jutil.CallbackOnFailure(env, jCallback, err)
 		return
diff --git a/v23/syncbase/nosql/resolver.go b/v23/syncbase/nosql/resolver.go
index e40a9e8..a0d2114 100644
--- a/v23/syncbase/nosql/resolver.go
+++ b/v23/syncbase/nosql/resolver.go
@@ -43,7 +43,7 @@
 func (r *jniResolver) OnConflict(ctx *context.T, conflict *nosql.Conflict) nosql.Resolution {
 	env, freeFunc := jutil.GetEnv()
 	defer freeFunc()
-	jContext, err := jcontext.JavaContext(env, ctx)
+	jContext, err := jcontext.JavaContext(env, ctx, nil)
 	if err != nil {
 		panic("Couldn't create Java context: " + err.Error())
 	}