TBR v.io/x/jni: support for discovery async api

Change-Id: I4def2dc0e796e039dbaf51dd52684d8d9857aca6
MultiPart: 2/2
diff --git a/impl/google/discovery/jni.go b/impl/google/discovery/jni.go
index 99a78d3..deaf818 100644
--- a/impl/google/discovery/jni.go
+++ b/impl/google/discovery/jni.go
@@ -11,10 +11,13 @@
 	"encoding/binary"
 	"unsafe"
 
+	"v.io/v23/context"
 	"v.io/v23/discovery"
 	"v.io/v23/security"
+	"v.io/v23/verror"
 	idiscovery "v.io/x/ref/lib/discovery"
 
+	jchannel "v.io/x/jni/impl/google/channel"
 	jutil "v.io/x/jni/util"
 	jcontext "v.io/x/jni/v23/context"
 )
@@ -110,119 +113,123 @@
 	return convertStringtoUUID(jenv, jclass, jName, converter)
 }
 
-//export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeFinalize
-func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeFinalize(jenv *C.JNIEnv, _ C.jobject, discovery C.jlong, trigger C.jlong) {
-	jutil.GoUnref(jutil.NativePtr(discovery))
-	jutil.GoUnref(jutil.NativePtr(trigger))
-}
-
-//export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_advertise
-func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_advertise(jenv *C.JNIEnv, jDiscoveryObj C.jobject, jContext C.jobject, jServiceObject C.jobject, jVisibility C.jobject, jCallback C.jobject) {
-	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
+func doAdvertise(ctx *context.T, ds discovery.T, trigger *idiscovery.Trigger, service discovery.Service, visibility []security.BlessingPattern, jService jutil.Object, jDoneCallback jutil.Object) (jutil.Object, error) {
+	// Blocking call, so don't call GetEnv() beforehand.
+	done, err := ds.Advertise(ctx, &service, visibility)
+	env, freeFunc := jutil.GetEnv()
+	defer freeFunc()
+	defer jutil.DeleteGlobalRef(env, jService)
 	if err != nil {
-		return
+		jutil.DeleteGlobalRef(env, jDoneCallback)
+		return jutil.NullObject, err
 	}
-	jService := jutil.Object(uintptr(unsafe.Pointer(jServiceObject)))
-	var service discovery.Service
-	if err := jutil.GoVomCopy(env, jService, jServiceClass, &service); err != nil {
-		jutil.JThrowV(env, err)
-		return
+	// Copy back service.InstanceId to jService since it's the only field that would be updated.
+	if err = jutil.CallVoidMethod(env, jService, "setInstanceId", []jutil.Sign{jutil.StringSign}, service.InstanceId); err != nil {
+		jutil.DeleteGlobalRef(env, jDoneCallback)
+		return jutil.NullObject, err
 	}
-
-	visibilityArray, err := jutil.GoObjectList(env, jutil.Object(uintptr(unsafe.Pointer(jVisibility))))
+	listenableFutureSign := jutil.ClassSign("com.google.common.util.concurrent.ListenableFuture")
+	jDoneFuture, err := jutil.CallObjectMethod(env, jDoneCallback, "getFuture", nil, listenableFutureSign)
 	if err != nil {
-		jutil.JThrowV(env, err)
-		return
+		jutil.DeleteGlobalRef(env, jDoneCallback)
+		return jutil.NullObject, err
 	}
-	visibilitySlice := make([]security.BlessingPattern, len(visibilityArray))
-	for i, jPattern := range visibilityArray {
-		if err := jutil.GoVomCopy(env, jPattern, jBlessingPatternClass, &visibilitySlice[i]); err != nil {
-			jutil.JThrowV(env, err)
-			return
-		}
-	}
-	jDiscovery := jutil.Object(uintptr(unsafe.Pointer(jDiscoveryObj)))
-	discoveryPtr, err := jutil.JLongField(env, jDiscovery, "nativeDiscovery")
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-
-	ds := *(*discovery.T)(jutil.NativePtr(discoveryPtr))
-
-	triggerPtr, err := jutil.JLongField(env, jDiscovery, "nativeTrigger")
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-
-	trigger := (*idiscovery.Trigger)(jutil.NativePtr(triggerPtr))
-
-	done, err := ds.Advertise(ctx, &service, visibilitySlice)
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-	// Copy back service.InstanceId to jServiceObject since it's the only field that would be updated.
-	if err = jutil.CallVoidMethod(env, jutil.Object(uintptr(unsafe.Pointer(jServiceObject))), "setInstanceId", []jutil.Sign{jutil.StringSign}, service.InstanceId); err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-	cb := jutil.Object(uintptr(unsafe.Pointer(jCallback)))
-	cb = jutil.NewGlobalRef(env, cb)
 	trigger.Add(func() {
 		env, freeFunc := jutil.GetEnv()
 		defer freeFunc()
-		// TODO(bjornick): What should we do on errors?
-		if err := jutil.CallVoidMethod(env, cb, "done", nil); err != nil {
-			ctx.Errorf("failed to call done:", err)
-		}
-		jutil.DeleteGlobalRef(env, cb)
+		jutil.CallbackOnSuccess(env, jDoneCallback, jutil.NullObject)
+		jutil.DeleteGlobalRef(env, jDoneCallback)
 	}, done)
+	// Must grab a global reference as we free up the env and all local references that come along
+	// with it.
+	return jutil.NewGlobalRef(env, jDoneFuture), nil // Un-refed in DoAsyncCall
 }
 
-//export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_scan
-func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_scan(jenv *C.JNIEnv, jDiscoveryObj C.jobject, jContext C.jobject, jQuery C.jstring, jCallback C.jobject) {
+//export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeAdvertise
+func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeAdvertise(jenv *C.JNIEnv, jDiscovery C.jobject, goDiscoveryPtr C.jlong, goTriggerPtr C.jlong, jContext C.jobject, jServiceObj C.jobject, jVisibilityObj C.jobject, jStartCallbackObj C.jobject, jDoneCallbackObj C.jobject) {
+	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
+	jService := jutil.Object(uintptr(unsafe.Pointer(jServiceObj)))
+	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))))
+	if err != nil {
+		jutil.CallbackOnFailure(env, jStartCallback, err)
+		return
+	}
+	var service discovery.Service
+	if err := jutil.GoVomCopy(env, jService, jServiceClass, &service); err != nil {
+		jutil.CallbackOnFailure(env, jStartCallback, err)
+		return
+	}
+	varr, err := jutil.GoObjectList(env, jVisibility)
+	if err != nil {
+		jutil.CallbackOnFailure(env, jStartCallback, err)
+		return
+	}
+	visibility := make([]security.BlessingPattern, len(varr))
+	for i, jPattern := range varr {
+		if err := jutil.GoVomCopy(env, jPattern, jBlessingPatternClass, &visibility[i]); err != nil {
+			jutil.CallbackOnFailure(env, jStartCallback, err)
+			return
+		}
+	}
+	ds := *(*discovery.T)(jutil.NativePtr(goDiscoveryPtr))
+	trigger := (*idiscovery.Trigger)(jutil.NativePtr(goTriggerPtr))
+	jService = jutil.NewGlobalRef(env, jService)           // Un-refed in doAdvertise
+	jDoneCallback = jutil.NewGlobalRef(env, jDoneCallback) // Un-refed in doAdvertise
+	jutil.DoAsyncCall(env, jStartCallback, func() (jutil.Object, error) {
+		return doAdvertise(ctx, ds, trigger, service, visibility, jService, jDoneCallback)
+	})
+}
+
+//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))))
 	if err != nil {
-		return
+		jutil.JThrowV(env, err)
+		return nil
 	}
 	query := jutil.GoString(env, jutil.Object(uintptr(unsafe.Pointer(jQuery))))
+	ds := *(*discovery.T)(jutil.NativePtr(goDiscoveryPtr))
 
-	jDiscovery := jutil.Object(uintptr(unsafe.Pointer(jDiscoveryObj)))
-	discoveryPtr, err := jutil.JLongField(env, jDiscovery, "nativeDiscovery")
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-	ds := *(*discovery.T)(jutil.NativePtr(discoveryPtr))
-
-	updates, err := ds.Scan(ctx, query)
-
-	jutil.NewGlobalRef(env, jutil.Object(uintptr(unsafe.Pointer(jCallback))))
-	if err != nil {
-		jutil.JThrowV(env, err)
-		return
-	}
-	cb := jutil.Object(uintptr(unsafe.Pointer(jCallback)))
-	cb = jutil.NewGlobalRef(env, cb)
+	var scanChannel <-chan discovery.Update
+	var scanError error
+	scanDone := make(chan bool)
 	go func() {
+		scanChannel, scanError = ds.Scan(ctx, query)
+		close(scanDone)
+	}()
+	jChannel, err := jchannel.JavaInputChannel(env, func() (jutil.Object, error) {
+		// A few blocking calls below - don't call GetEnv() before they complete.
+		<-scanDone
+		if scanError != nil {
+			return jutil.NullObject, scanError
+		}
+		update, ok := <-scanChannel
+		if !ok {
+			return jutil.NullObject, verror.NewErrEndOfFile(ctx)
+		}
 		env, freeFunc := jutil.GetEnv()
 		defer freeFunc()
-		for v := range updates {
-			jUpdate, err := jutil.JVomCopy(env, v, jUpdateClass)
-			if err != nil {
-				ctx.Errorf("Failed to convert update: %v", err)
-				continue
-			}
-			err = jutil.CallVoidMethod(env, cb, "handleUpdate", []jutil.Sign{updateSign}, jUpdate)
-			if err != nil {
-				ctx.Errorf("Failed to call handler: %v", err)
-				continue
-			}
+		jUpdate, err := jutil.JVomCopy(env, update, jUpdateClass)
+		if err != nil {
+			return jutil.NullObject, err
 		}
-		jutil.DeleteGlobalRef(env, cb)
-	}()
+		// Must grab a global reference as we free up the env and all local references that come
+		// along with it.
+		return jutil.NewGlobalRef(env, jUpdate), nil // Un-refed by InputChannelImpl_nativeRecv
+	})
+	if err != nil {
+		jutil.JThrowV(env, err)
+		return nil
+	}
+	return C.jobject(unsafe.Pointer(jChannel))
+}
+
+//export Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeFinalize
+func Java_io_v_impl_google_lib_discovery_VDiscoveryImpl_nativeFinalize(jenv *C.JNIEnv, jDiscovery C.jobject, goDiscoveryPtr C.jlong, goTriggerPtr C.jlong) {
+	jutil.GoUnref(jutil.NativePtr(goDiscoveryPtr))
+	jutil.GoUnref(jutil.NativePtr(goTriggerPtr))
 }
diff --git a/impl/google/discovery/util.go b/impl/google/discovery/util.go
index de4cbef..65566d9 100644
--- a/impl/google/discovery/util.go
+++ b/impl/google/discovery/util.go
@@ -12,6 +12,7 @@
 	"v.io/v23/discovery"
 	idiscovery "v.io/x/ref/lib/discovery"
 )
+
 // #include "jni.h"
 import "C"
 
diff --git a/impl/google/jni.go b/impl/google/jni.go
index bda3428..8c27dbc 100644
--- a/impl/google/jni.go
+++ b/impl/google/jni.go
@@ -8,12 +8,12 @@
 
 import (
 	jchannel "v.io/x/jni/impl/google/channel"
+	jdiscovery "v.io/x/jni/impl/google/discovery"
 	jns "v.io/x/jni/impl/google/namespace"
 	jrpc "v.io/x/jni/impl/google/rpc"
 	jrt "v.io/x/jni/impl/google/rt"
 	jservices "v.io/x/jni/impl/google/services"
 	jutil "v.io/x/jni/util"
-	jdiscovery "v.io/x/jni/impl/google/discovery"
 )
 
 // #include "jni.h"
diff --git a/impl/google/namespace/jni.go b/impl/google/namespace/jni.go
index 35c9481..ccfc2da 100644
--- a/impl/google/namespace/jni.go
+++ b/impl/google/namespace/jni.go
@@ -7,7 +7,6 @@
 package namespace
 
 import (
-	"fmt"
 	"time"
 	"unsafe"
 
@@ -16,6 +15,7 @@
 	"v.io/v23/naming"
 	"v.io/v23/security/access"
 	"v.io/v23/verror"
+
 	jchannel "v.io/x/jni/impl/google/channel"
 	jutil "v.io/x/jni/util"
 	jcontext "v.io/x/jni/v23/context"
@@ -71,23 +71,32 @@
 	return
 }
 
-func doGlob(n namespace.T, context *context.T, pattern string, opts []naming.NamespaceOpt) (jutil.Object, error) {
-	c, err := n.Glob(context, pattern, opts...)
+//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob
+func Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jPattern C.jstring, jOptions C.jobject) C.jobject {
+	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
+	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
+	context, pattern, opts, err := globArgs(env, jContext, jPattern, jOptions)
 	if err != nil {
-		return jutil.NullObject, err
+		jutil.JThrowV(env, err)
+		return nil
 	}
-	env, freeFunc := jutil.GetEnv()
-	defer freeFunc()
+	var globChannel <-chan naming.GlobReply
+	var globError error
+	globDone := make(chan bool)
+	go func() {
+		globChannel, globError = n.Glob(context, pattern, opts...)
+		close(globDone)
+	}()
 	jChannel, err := jchannel.JavaInputChannel(env, func() (jutil.Object, error) {
-		// This is a blocking call, so don't call GetEnv() before this line.
-		val, ok := <-c
+		// A few blocking calls below - don't call GetEnv() before they complete.
+		<-globDone
+		if globError != nil {
+			return jutil.NullObject, globError
+		}
+		globReply, ok := <-globChannel
 		if !ok {
 			return jutil.NullObject, verror.NewErrEndOfFile(context)
 		}
-		globReply, ok := val.(naming.GlobReply)
-		if !ok {
-			return jutil.NullObject, fmt.Errorf("Expected value of GlobReply type, got type %T: %v", val, val)
-		}
 		env, freeFunc := jutil.GetEnv()
 		defer freeFunc()
 		jReply, err := jutil.JVomCopy(env, globReply, jGlobReplyClass)
@@ -96,29 +105,13 @@
 		}
 		// Must grab a global reference as we free up the env and all local references that come
 		// along with it.
-		return jutil.NewGlobalRef(env, jReply), nil  // Un-refed by InputChannelImpl_nativeRecv
+		return jutil.NewGlobalRef(env, jReply), nil // Un-refed by InputChannelImpl_nativeRecv
 	})
 	if err != nil {
-		return jutil.NullObject, err
+		jutil.JThrowV(env, err)
+		return nil
 	}
-	// Must grab a global reference as we free up the env and all local references that come along
-	// with it.
-	return jutil.NewGlobalRef(env, jChannel), nil  // Un-refed by DoAsyncCall
-}
-
-//export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob
-func Java_io_v_impl_google_namespace_NamespaceImpl_nativeGlob(jenv *C.JNIEnv, jNamespaceClass C.jclass, goNamespacePtr C.jlong, jContext C.jobject, jPattern C.jstring, jOptions C.jobject, jCallbackObj C.jobject) {
-	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	n := *(*namespace.T)(jutil.NativePtr(goNamespacePtr))
-	jCallback := jutil.Object(uintptr(unsafe.Pointer(jCallbackObj)))
-	context, pattern, opts, err := globArgs(env, jContext, jPattern, jOptions)
-	if err != nil {
-		jutil.CallbackOnFailure(env, jCallback, err)
-		return
-	}
-	jutil.DoAsyncCall(env, jCallback, func() (jutil.Object, error) {
-		return doGlob(n, context, pattern, opts)
-	})
+	return C.jobject(unsafe.Pointer(jChannel))
 }
 
 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) {
@@ -232,7 +225,7 @@
 	}
 	// Must grab a global reference as we free up the env and all local references that come along
 	// with it.
-	return jutil.NewGlobalRef(env, jEntry), nil  // Un-refed in DoAsyncCall
+	return jutil.NewGlobalRef(env, jEntry), nil // Un-refed in DoAsyncCall
 }
 
 //export Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolve
@@ -276,7 +269,7 @@
 	}
 	// Must grab a global reference as we free up the env and all local references that come along
 	// with it.
-	return jutil.NewGlobalRef(env, jEntry), nil  // Un-refed in DoAsyncCall
+	return jutil.NewGlobalRef(env, jEntry), nil // Un-refed in DoAsyncCall
 }
 
 //export Java_io_v_impl_google_namespace_NamespaceImpl_nativeResolveToMountTable
@@ -388,7 +381,7 @@
 	}
 	// Must grab a global reference as we free up the env and all local references that come along
 	// with it.
-	return jutil.NewGlobalRef(env, jResult), nil  // Un-refed in DoAsyncCall
+	return jutil.NewGlobalRef(env, jResult), nil // Un-refed in DoAsyncCall
 }
 
 //export Java_io_v_impl_google_namespace_NamespaceImpl_nativeGetPermissions
diff --git a/impl/google/rpc/dispatcher.go b/impl/google/rpc/dispatcher.go
index c425a3e..180314d 100644
--- a/impl/google/rpc/dispatcher.go
+++ b/impl/google/rpc/dispatcher.go
@@ -30,7 +30,7 @@
 	jExecutor = jutil.NewGlobalRef(env, jExecutor)
 	d := &dispatcher{
 		jDispatcher: jDispatcher,
-		jExecutor: jExecutor,
+		jExecutor:   jExecutor,
 	}
 	runtime.SetFinalizer(d, func(d *dispatcher) {
 		env, freeFunc := jutil.GetEnv()
diff --git a/impl/google/rpc/invoker.go b/impl/google/rpc/invoker.go
index 66fe71c..7d8f210 100644
--- a/impl/google/rpc/invoker.go
+++ b/impl/google/rpc/invoker.go
@@ -18,10 +18,10 @@
 	"v.io/v23/vdlroot/signature"
 	"v.io/v23/vom"
 
-	jrpc "v.io/x/jni/v23/rpc"
 	jchannel "v.io/x/jni/impl/google/channel"
 	jutil "v.io/x/jni/util"
 	jcontext "v.io/x/jni/v23/context"
+	jrpc "v.io/x/jni/v23/rpc"
 )
 
 // #include "jni.h"
@@ -47,7 +47,7 @@
 	jInvoker = jutil.NewGlobalRef(env, jInvoker)
 	jExecutor = jutil.NewGlobalRef(env, jExecutor)
 	i := &invoker{
-		jInvoker: jInvoker,
+		jInvoker:  jInvoker,
 		jExecutor: jExecutor,
 	}
 	runtime.SetFinalizer(i, func(i *invoker) {
@@ -149,9 +149,9 @@
 	// We're blocking, so have to explicitly release the env here.
 	freeFunc()
 	select {
-	case results := <- succCh:
+	case results := <-succCh:
 		return results, nil
-	case err := <- errCh:
+	case err := <-errCh:
 		return nil, err
 	}
 }
diff --git a/impl/google/rpc/jni.go b/impl/google/rpc/jni.go
index 0d78fc5..d01034c 100644
--- a/impl/google/rpc/jni.go
+++ b/impl/google/rpc/jni.go
@@ -17,12 +17,12 @@
 	"v.io/v23/vdl"
 	"v.io/v23/vom"
 
+	"v.io/v23/verror"
 	jbt "v.io/x/jni/impl/google/rpc/protocols/bt"
 	jutil "v.io/x/jni/util"
 	jcontext "v.io/x/jni/v23/context"
 	jnaming "v.io/x/jni/v23/naming"
 	jsecurity "v.io/x/jni/v23/security"
-	"v.io/v23/verror"
 )
 
 // #include "jni.h"
@@ -275,7 +275,7 @@
 	}
 	// Must grab a global reference as we free up the env and all local references that come along
 	// with it.
-	return jutil.NewGlobalRef(env, jCall), nil  // Un-refed in DoAsyncCall
+	return jutil.NewGlobalRef(env, jCall), nil // Un-refed in DoAsyncCall
 }
 
 //export Java_io_v_impl_google_rpc_ClientImpl_nativeStartCall
@@ -349,7 +349,7 @@
 		}
 		// Must grab a global reference as we free up the env and all local references that come along
 		// with it.
-		return jutil.NewGlobalRef(env, jResult), nil  // Un-refed in DoAsyncCall
+		return jutil.NewGlobalRef(env, jResult), nil // Un-refed in DoAsyncCall
 	})
 }
 
@@ -397,7 +397,7 @@
 	}
 	// Must grab a global reference as we free up the env and all local references that come along
 	// with it.
-	return jutil.NewGlobalRef(env, jArr), nil  // Un-refed in DoAsyncCall
+	return jutil.NewGlobalRef(env, jArr), nil // Un-refed in DoAsyncCall
 }
 
 //export Java_io_v_impl_google_rpc_ClientCallImpl_nativeFinish
diff --git a/impl/google/rt/jni.go b/impl/google/rt/jni.go
index 420f378..d215ed4 100644
--- a/impl/google/rt/jni.go
+++ b/impl/google/rt/jni.go
@@ -12,11 +12,11 @@
 	"v.io/v23"
 	"v.io/v23/context"
 
+	jdiscovery "v.io/x/jni/impl/google/discovery"
 	jns "v.io/x/jni/impl/google/namespace"
 	jrpc "v.io/x/jni/impl/google/rpc"
 	jutil "v.io/x/jni/util"
 	jcontext "v.io/x/jni/v23/context"
-	jdiscovery "v.io/x/jni/impl/google/discovery"
 	jsecurity "v.io/x/jni/v23/security"
 )
 
@@ -280,13 +280,13 @@
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	ctx, err := jcontext.GoContext(env, jutil.Object(uintptr(unsafe.Pointer(jContext))))
 	if err != nil {
-		jutil.JThrowV(env, err);
+		jutil.JThrowV(env, err)
 		return nil
 	}
 
 	jDiscovery, err := jdiscovery.JavaDiscovery(env, v23.GetDiscovery(ctx))
 	if err != nil {
-		jutil.JThrowV(env, err);
+		jutil.JThrowV(env, err)
 		return nil
 	}
 	return C.jobject(unsafe.Pointer(jDiscovery))
diff --git a/jni_java.go b/jni_java.go
index 631a60d..8fd18ac 100644
--- a/jni_java.go
+++ b/jni_java.go
@@ -30,4 +30,4 @@
 		return
 	}
 	vlog.Log.Configure(vlog.OverridePriorConfiguration(true), dir, toStderr, level, vmodule)
-}
\ No newline at end of file
+}
diff --git a/libs/discovery/jni.go b/libs/discovery/jni.go
index e6bf2a3..efcd95f 100644
--- a/libs/discovery/jni.go
+++ b/libs/discovery/jni.go
@@ -12,14 +12,16 @@
 	jutil "v.io/x/jni/util"
 	"v.io/x/ref/lib/discovery"
 )
+
 // #include "jni.h"
 import "C"
+
 var (
 	androidContextSign = jutil.ClassSign("android.content.Context")
-	contextSign = jutil.ClassSign("io.v.v23.context.VContext")
-	advertisementSign = jutil.ClassSign("io.v.x.ref.lib.discovery.Advertisement")
-	uuidSign = jutil.ClassSign("java.util.UUID")
-	scanHandlerSign = jutil.ClassSign("io.v.impl.google.lib.discovery.ScanHandler")
+	contextSign        = jutil.ClassSign("io.v.v23.context.VContext")
+	advertisementSign  = jutil.ClassSign("io.v.x.ref.lib.discovery.Advertisement")
+	uuidSign           = jutil.ClassSign("java.util.UUID")
+	scanHandlerSign    = jutil.ClassSign("io.v.impl.google.lib.discovery.ScanHandler")
 
 	// Global reference for io.v.android.libs.discovery.ble.BlePlugin
 	jBlePluginClass jutil.Class
@@ -54,9 +56,9 @@
 }
 
 //export Java_io_v_android_libs_discovery_ble_NativeScanHandler_nativeHandleUpdate
-func Java_io_v_android_libs_discovery_ble_NativeScanHandler_nativeHandleUpdate(jenv *C.JNIEnv, _ C.jobject, jAdvObj C.jobject, goPtr C.jlong)  {
+func Java_io_v_android_libs_discovery_ble_NativeScanHandler_nativeHandleUpdate(jenv *C.JNIEnv, _ C.jobject, jAdvObj C.jobject, goPtr C.jlong) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
-	ch := (*(*chan <-discovery.Advertisement)(jutil.NativePtr(goPtr)))
+	ch := (*(*chan<- discovery.Advertisement)(jutil.NativePtr(goPtr)))
 
 	jAdv := jutil.Object(uintptr(unsafe.Pointer(jAdvObj)))
 	var adv discovery.Advertisement
@@ -64,7 +66,7 @@
 		jutil.JThrowV(env, err)
 		return
 	}
-	ch <-adv
+	ch <- adv
 }
 
 //export Java_io_v_android_libs_discovery_ble_NativeScanHandler_nativeFinalize
diff --git a/libs/discovery/plugin.go b/libs/discovery/plugin.go
index 8632349..65fcb48 100644
--- a/libs/discovery/plugin.go
+++ b/libs/discovery/plugin.go
@@ -5,6 +5,7 @@
 // +build android
 
 package discovery
+
 import (
 	"bytes"
 	"encoding/binary"
@@ -14,8 +15,8 @@
 
 	"v.io/x/ref/lib/discovery"
 
-	jcontext "v.io/x/jni/v23/context"
 	jutil "v.io/x/jni/util"
+	jcontext "v.io/x/jni/v23/context"
 )
 
 // #include "jni.h"
@@ -91,7 +92,6 @@
 		return err
 	}
 
-
 	jutil.GoRef(&ch)
 	jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(&ch)))
 	if err != nil {
@@ -108,7 +108,6 @@
 	return nil
 }
 
-
 // JavaUUID converts a Go UUID type to a Java UUID object.
 func JavaUUID(env jutil.Env, uuid discovery.Uuid) (jutil.Object, error) {
 	buf := bytes.NewBuffer(uuid)
diff --git a/util/call.go b/util/call.go
index 57560f4..fbf822c 100644
--- a/util/call.go
+++ b/util/call.go
@@ -315,7 +315,7 @@
 // approach to pass parameters through to fnToWrap.
 func DoAsyncCall(env Env, jCallback Object, fnToWrap func() (Object, error)) {
 	go func(jCallback Object) {
-		jResult, err := fnToWrap()  // probably blocking, so don't call GetEnv() before this line
+		jResult, err := fnToWrap() // probably blocking, so don't call GetEnv() before this line
 		env, freeFunc := GetEnv()
 		defer freeFunc()
 		defer DeleteGlobalRef(env, jCallback)
diff --git a/util/util.go b/util/util.go
index 9206b6c..2619d85 100644
--- a/util/util.go
+++ b/util/util.go
@@ -877,4 +877,4 @@
 		return nil, fmt.Errorf("couldn't find field %s: %v", name, err)
 	}
 	return fid, nil
-}
\ No newline at end of file
+}
diff --git a/v23/rpc/jni.go b/v23/rpc/jni.go
index fe81a99..28ecd1e 100644
--- a/v23/rpc/jni.go
+++ b/v23/rpc/jni.go
@@ -35,14 +35,14 @@
 //export Java_io_v_v23_rpc_NativeCallback_nativeOnSuccess
 func Java_io_v_v23_rpc_NativeCallback_nativeOnSuccess(jenv *C.JNIEnv, jNativeCallback C.jobject, goSuccessPtr C.jlong, jResultObj C.jobject) {
 	jResult := jutil.Object(uintptr(unsafe.Pointer(jResultObj)))
-	(*(*func (jutil.Object))(jutil.NativePtr(goSuccessPtr)))(jResult)
+	(*(*func(jutil.Object))(jutil.NativePtr(goSuccessPtr)))(jResult)
 }
 
 //export Java_io_v_v23_rpc_NativeCallback_nativeOnFailure
 func Java_io_v_v23_rpc_NativeCallback_nativeOnFailure(jenv *C.JNIEnv, jNativeCallback C.jobject, goFailurePtr C.jlong, jVException C.jobject) {
 	env := jutil.Env(uintptr(unsafe.Pointer(jenv)))
 	err := jutil.GoError(env, jutil.Object(uintptr(unsafe.Pointer(jVException))))
-	(*(*func (error))(jutil.NativePtr(goFailurePtr)))(err)
+	(*(*func(error))(jutil.NativePtr(goFailurePtr)))(err)
 }
 
 //export Java_io_v_v23_rpc_NativeCallback_nativeFinalize
diff --git a/v23/rpc/util.go b/v23/rpc/util.go
index c597d6b..8d53618 100644
--- a/v23/rpc/util.go
+++ b/v23/rpc/util.go
@@ -17,7 +17,7 @@
 	if err != nil {
 		return jutil.NullObject, err
 	}
-	jutil.GoRef(&success)  // Un-refed when jCallback is finalized
-	jutil.GoRef(&failure)  // Un-refed when jCallback is finalized
+	jutil.GoRef(&success) // Un-refed when jCallback is finalized
+	jutil.GoRef(&failure) // Un-refed when jCallback is finalized
 	return jCallback, nil
-}
\ No newline at end of file
+}