v.io/x/jni: support change for mounttable server on java
MultiPart: 2/2
Change-Id: If5ae79766300e61e5e5c0c85031844589da4f8fc
diff --git a/impl/google/jni.go b/impl/google/jni.go
index fd14834..466fbcf 100644
--- a/impl/google/jni.go
+++ b/impl/google/jni.go
@@ -11,7 +11,8 @@
jns "v.io/x/jni/impl/google/namespace"
jrpc "v.io/x/jni/impl/google/rpc"
jrt "v.io/x/jni/impl/google/rt"
- jsyncbased "v.io/x/jni/impl/google/services/syncbase/syncbased"
+ jsyncbase "v.io/x/jni/impl/google/services/syncbase"
+ jmounttable "v.io/x/jni/impl/google/services/mounttable"
jutil "v.io/x/jni/util"
)
@@ -21,7 +22,6 @@
// 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()).
-// interface and then cast into the package-local environment type.
func Init(env jutil.Env) error {
if err := jrpc.Init(env); err != nil {
return err
@@ -35,7 +35,10 @@
if err := jns.Init(env); err != nil {
return err
}
- if err := jsyncbased.Init(env); err != nil {
+ if err := jmounttable.Init(env); err != nil {
+ return err
+ }
+ if err := jsyncbase.Init(env); err != nil {
return err
}
return nil
diff --git a/impl/google/services/mounttable/jni.go b/impl/google/services/mounttable/jni.go
new file mode 100644
index 0000000..50be231
--- /dev/null
+++ b/impl/google/services/mounttable/jni.go
@@ -0,0 +1,160 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build java android
+
+package mounttable
+
+import (
+ "bufio"
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+ "unsafe"
+
+ "v.io/v23"
+ "v.io/v23/security/access"
+ "v.io/x/ref/services/mounttable/mounttablelib"
+
+ jrpc "v.io/x/jni/impl/google/rpc"
+ jutil "v.io/x/jni/util"
+ jcontext "v.io/x/jni/v23/context"
+ jaccess "v.io/x/jni/v23/security/access"
+ "v.io/v23/options"
+)
+
+// #include "jni.h"
+import "C"
+
+var (
+ permissionsSign = jutil.ClassSign("io.v.v23.security.access.Permissions")
+ listenSpecSign = jutil.ClassSign("io.v.v23.rpc.ListenSpec")
+ contextSign = jutil.ClassSign("io.v.v23.context.VContext")
+ serverSign = jutil.ClassSign("io.v.v23.rpc.Server")
+
+ jSystemClass jutil.Class
+ jVClass jutil.Class
+ jVRuntimeImplClass jutil.Class
+)
+
+// 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()).
+func Init(env jutil.Env) error {
+ var err error
+ jSystemClass, err = jutil.JFindClass(env, "java/lang/System")
+ if err != nil {
+ return err
+ }
+ jVClass, err = jutil.JFindClass(env, "io/v/v23/V")
+ if err != nil {
+ return err
+ }
+ jVRuntimeImplClass, err = jutil.JFindClass(env, "io/v/impl/google/rt/VRuntimeImpl")
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+//export Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer
+func Java_io_v_impl_google_services_mounttable_MountTableServer_nativeWithNewServer(jenv *C.JNIEnv, jMountTableServerClass C.jclass, jContext C.jobject, jMountTableServerParams C.jobject) C.jobject {
+ env := jutil.WrapEnv(jenv)
+ jCtx := jutil.WrapObject(jContext)
+ jParams := jutil.WrapObject(jMountTableServerParams)
+
+ // Read and translate all of the server params.
+ mountName, err := jutil.CallStringMethod(env, jParams, "getName", nil)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ rootDir, err := jutil.CallStringMethod(env, jParams, "getStorageRootDir", nil)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ if rootDir == "" {
+ rootDir, err = jutil.CallStaticStringMethod(env, jSystemClass, "getProperty", []jutil.Sign{jutil.StringSign}, "java.io.tmpdir")
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ }
+ permsJMap, err := jutil.CallMapMethod(env, jParams, "getPermissions", nil)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ permsMap := make(map[string]access.Permissions)
+ for jPath, jPerms := range permsJMap {
+ path := jutil.GoString(env, jPath)
+ perms, err := jaccess.GoPermissions(env, jPerms)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ permsMap[path] = perms
+ }
+ // Write JSON-encoded permissions to a file.
+ jsonPerms, err := json.Marshal(permsMap)
+ if err != nil {
+ jutil.JThrowV(env, fmt.Errorf("Couldn't JSON-encode path-permissions: %v", err))
+ return nil
+
+ }
+ permsFile, err := os.Create(filepath.Join(rootDir, "jni_permissions"))
+ if err != nil {
+ jutil.JThrowV(env, fmt.Errorf("Couldn't create permissions file: %v", err))
+ return nil
+ }
+ w := bufio.NewWriter(permsFile)
+ if _, err := w.Write(jsonPerms); err != nil {
+ jutil.JThrowV(env, fmt.Errorf("Couldn't write to permissions file: %v", err))
+ return nil
+ }
+ if err := w.Flush(); err != nil {
+ jutil.JThrowV(env, fmt.Errorf("Couldn't flush to permissions file: %v", err))
+ }
+ statsPrefix, err := jutil.CallStringMethod(env, jParams, "getStatsPrefix", nil)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+
+ // Start the mounttable server.
+ ctx, err := jcontext.GoContext(env, jCtx)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ d, err := mounttablelib.NewMountTableDispatcher(ctx, permsFile.Name(), rootDir, statsPrefix)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ newCtx, s, err := v23.WithNewDispatchingServer(ctx, mountName, d, options.ServesMountTable(true))
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ jNewCtx, err := jcontext.JavaContext(env, newCtx, nil)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ jServer, err := jrpc.JavaServer(env, s)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ // Attach a server to the new context.
+ jServerAttCtx, err := jutil.CallStaticObjectMethod(env, jVRuntimeImplClass, "withServer", []jutil.Sign{contextSign, serverSign}, contextSign, jNewCtx, jServer)
+ if err != nil {
+ jutil.JThrowV(env, err)
+ return nil
+ }
+ return C.jobject(unsafe.Pointer(jServerAttCtx))
+}
diff --git a/impl/google/services/syncbase/syncbased/jni.go b/impl/google/services/syncbase/jni.go
similarity index 83%
rename from impl/google/services/syncbase/syncbased/jni.go
rename to impl/google/services/syncbase/jni.go
index 964c8cd..545bda7 100644
--- a/impl/google/services/syncbase/syncbased/jni.go
+++ b/impl/google/services/syncbase/jni.go
@@ -4,7 +4,7 @@
// +build java android
-package syncbased
+package syncbase
import (
"unsafe"
@@ -25,7 +25,7 @@
permissionsSign = jutil.ClassSign("io.v.v23.security.access.Permissions")
listenSpecSign = jutil.ClassSign("io.v.v23.rpc.ListenSpec")
contextSign = jutil.ClassSign("io.v.v23.context.VContext")
- syncbaseStorageEngineSign = jutil.ClassSign("io.v.v23.syncbase.SyncbaseStorageEngine")
+ storageEngineSign = jutil.ClassSign("io.v.impl.google.services.syncbase.SyncbaseServer$StorageEngine")
serverSign = jutil.ClassSign("io.v.v23.rpc.Server")
jSystemClass jutil.Class
@@ -33,6 +33,9 @@
jVRuntimeImplClass jutil.Class
)
+// 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()).
func Init(env jutil.Env) error {
var err error
jSystemClass, err = jutil.JFindClass(env, "java/lang/System")
@@ -50,8 +53,8 @@
return nil
}
-//export Java_io_v_impl_google_services_syncbase_syncbased_SyncbaseServer_nativeWithNewServer
-func Java_io_v_impl_google_services_syncbase_syncbased_SyncbaseServer_nativeWithNewServer(jenv *C.JNIEnv, jSyncbaseServerClass C.jclass, jContext C.jobject, jSyncbaseServerParams C.jobject) C.jobject {
+//export Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer
+func Java_io_v_impl_google_services_syncbase_SyncbaseServer_nativeWithNewServer(jenv *C.JNIEnv, jSyncbaseServerClass C.jclass, jContext C.jobject, jSyncbaseServerParams C.jobject) C.jobject {
env := jutil.WrapEnv(jenv)
jCtx := jutil.WrapObject(jContext)
jParams := jutil.WrapObject(jSyncbaseServerParams)
@@ -84,7 +87,7 @@
return nil
}
}
- jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, syncbaseStorageEngineSign)
+ jEngine, err := jutil.CallObjectMethod(env, jParams, "getStorageEngine", nil, storageEngineSign)
if err != nil {
jutil.JThrowV(env, err)
return nil
diff --git a/impl/google/services/syncbase/syncbased/util.go b/impl/google/services/syncbase/util.go
similarity index 95%
rename from impl/google/services/syncbase/syncbased/util.go
rename to impl/google/services/syncbase/util.go
index 8f8daee..44a21e8 100644
--- a/impl/google/services/syncbase/syncbased/util.go
+++ b/impl/google/services/syncbase/util.go
@@ -4,7 +4,7 @@
// +build java android
-package syncbased
+package syncbase
import (
jutil "v.io/x/jni/util"