[sword-svn] r3644 - in trunk/bindings: cordova/cordova-plugin-crosswire-sword cordova/cordova-plugin-crosswire-sword/src/android java-jni/jni

scribe at crosswire.org scribe at crosswire.org
Sun Jun 9 13:51:55 MST 2019


Author: scribe
Date: 2019-06-09 13:51:54 -0700 (Sun, 09 Jun 2019)
New Revision: 3644

Modified:
   trunk/bindings/cordova/cordova-plugin-crosswire-sword/package.json
   trunk/bindings/cordova/cordova-plugin-crosswire-sword/plugin.xml
   trunk/bindings/cordova/cordova-plugin-crosswire-sword/src/android/SWORD.java
   trunk/bindings/java-jni/jni/swordstub.cpp
Log:
update java jni bindings to work better in a multi-threaded environment
Fixed cordova plugin when SWModule remoteSource name is "null" from JavaScript

Modified: trunk/bindings/cordova/cordova-plugin-crosswire-sword/package.json
===================================================================
--- trunk/bindings/cordova/cordova-plugin-crosswire-sword/package.json	2019-06-09 20:51:44 UTC (rev 3643)
+++ trunk/bindings/cordova/cordova-plugin-crosswire-sword/package.json	2019-06-09 20:51:54 UTC (rev 3644)
@@ -1,6 +1,6 @@
 {
   "name": "cordova-plugin-crosswire-sword",
-  "version": "0.0.5",
+  "version": "0.0.7",
   "description": "The SWORD Project Plugin",
   "cordova": {
     "id": "cordova-plugin-crosswire-sword",

Modified: trunk/bindings/cordova/cordova-plugin-crosswire-sword/plugin.xml
===================================================================
--- trunk/bindings/cordova/cordova-plugin-crosswire-sword/plugin.xml	2019-06-09 20:51:44 UTC (rev 3643)
+++ trunk/bindings/cordova/cordova-plugin-crosswire-sword/plugin.xml	2019-06-09 20:51:54 UTC (rev 3644)
@@ -4,7 +4,7 @@
     xmlns:rim="http://www.blackberry.com/ns/widgets"
     xmlns:android="http://schemas.android.com/apk/res/android"
     id="cordova-plugin-crosswire-sword"
-    version="0.0.5">
+    version="0.0.7">
     <name>cordova-plugin-crosswire-sword</name>
     <description>The SWORD Project Plugin</description>
     <license>GNU 2.0</license>

Modified: trunk/bindings/cordova/cordova-plugin-crosswire-sword/src/android/SWORD.java
===================================================================
--- trunk/bindings/cordova/cordova-plugin-crosswire-sword/src/android/SWORD.java	2019-06-09 20:51:44 UTC (rev 3643)
+++ trunk/bindings/cordova/cordova-plugin-crosswire-sword/src/android/SWORD.java	2019-06-09 20:51:54 UTC (rev 3644)
@@ -480,7 +480,10 @@
 			callbackContext.success(r);
 		}
 		else if (action.equals("SWModule_getConfigEntry")) {
-			SWModule mod = new SWModule(args.getString(0), args.getString(2));
+			String modName = args.getString(0);
+			String sourceName = args.getString(2);
+			if ("null".equals(sourceName)) sourceName = null;
+			SWModule mod = new SWModule(modName, sourceName);
 			if (mod == null) { callbackContext.error("couldn't find module: " + args.getString(0)); return true; }
 			callbackContext.success(mod.getConfigEntry(args.getString(1)));
 		}

Modified: trunk/bindings/java-jni/jni/swordstub.cpp
===================================================================
--- trunk/bindings/java-jni/jni/swordstub.cpp	2019-06-09 20:51:44 UTC (rev 3643)
+++ trunk/bindings/java-jni/jni/swordstub.cpp	2019-06-09 20:51:54 UTC (rev 3644)
@@ -59,6 +59,8 @@
 using namespace sword;
 
 namespace {
+bool firstInit = true;
+JavaVM *javaVM = 0;
 WebMgr *mgr = 0;
 InstallMgr *installMgr = 0;
 LocaleMgr *localeMgr = 0;
@@ -68,7 +70,6 @@
 using std::string;
 jobject bibleSyncListener = 0;
 JNIEnv *bibleSyncListenerEnv = 0;
-JNIEnv *lastEnv = 0;
 #endif
 static SWBuf STORAGE_BASE;
 const char *SWORD_PATH = "/sdcard/sword";
@@ -160,33 +161,46 @@
 class AndroidStringMgr : public StringMgr {
 public:
 	virtual char *upperUTF8(char *buf, unsigned int maxLen = 0) const {
-		if (lastEnv) {
+		JNIEnv *myThreadsEnv = 0;
+
+		// double check it's all ok
+		int getEnvStat = javaVM->GetEnv((void**)&myThreadsEnv, JNI_VERSION_1_6);
+		// should never happen
+		if (getEnvStat == JNI_EDETACHED) {
+			std::cout << "GetEnv: not attached" << std::endl;
+			if (javaVM->AttachCurrentThread(&myThreadsEnv, NULL) != 0) {
+				std::cout << "Failed to attach" << std::endl;
+			}
+		}
+
+		if (myThreadsEnv) {
 			long bufLen = strlen(buf);
-			jbyteArray array = lastEnv->NewByteArray(bufLen);
-			lastEnv->SetByteArrayRegion(array, 0, bufLen, (const jbyte *)buf);
-			jstring strEncode = lastEnv->NewStringUTF("UTF-8");
-			jclass cls = lastEnv->FindClass("java/lang/String");
-			jmethodID ctor = lastEnv->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
-			jstring object = (jstring) lastEnv->NewObject(cls, ctor, array, strEncode);
-			jmethodID toUpperCase = lastEnv->GetMethodID(cls, "toUpperCase", "()Ljava/lang/String;");
-			jstring objectUpper = (jstring)lastEnv->CallObjectMethod(object, toUpperCase, NULL);
+			jbyteArray array = myThreadsEnv->NewByteArray(bufLen);
+			myThreadsEnv->SetByteArrayRegion(array, 0, bufLen, (const jbyte *)buf);
+			jstring strEncode = myThreadsEnv->NewStringUTF("UTF-8");
+			jclass cls = myThreadsEnv->FindClass("java/lang/String");
+			jmethodID ctor = myThreadsEnv->GetMethodID(cls, "<init>", "([BLjava/lang/String;)V");
+			jstring object = (jstring) myThreadsEnv->NewObject(cls, ctor, array, strEncode);
+			jmethodID toUpperCase = myThreadsEnv->GetMethodID(cls, "toUpperCase", "()Ljava/lang/String;");
+			jstring objectUpper = (jstring)myThreadsEnv->CallObjectMethod(object, toUpperCase, NULL);
 
-			const char *ret = (objectUpper?lastEnv->GetStringUTFChars(objectUpper, NULL):0);
+			const char *ret = (objectUpper?myThreadsEnv->GetStringUTFChars(objectUpper, NULL):0);
 			if (ret) {
 				unsigned long retLen = strlen(ret);
 				if (retLen >= maxLen) retLen = maxLen-1;
 				memcpy(buf, ret, retLen);
 				buf[retLen] = 0;
 
-				lastEnv->ReleaseStringUTFChars(objectUpper, ret);
+				myThreadsEnv->ReleaseStringUTFChars(objectUpper, ret);
 			}
 
-			lastEnv->DeleteLocalRef(strEncode);
-			lastEnv->DeleteLocalRef(array);
-			lastEnv->DeleteLocalRef(cls);
-			lastEnv->DeleteLocalRef(objectUpper);
-			lastEnv->DeleteLocalRef(object);
+			myThreadsEnv->DeleteLocalRef(strEncode);
+			myThreadsEnv->DeleteLocalRef(array);
+			myThreadsEnv->DeleteLocalRef(cls);
+			myThreadsEnv->DeleteLocalRef(objectUpper);
+			myThreadsEnv->DeleteLocalRef(object);
 		}
+//		javaVM->DetachCurrentThread();
 		return buf;
 	}
 protected:
@@ -195,13 +209,12 @@
 
 static void init(JNIEnv *env) {
 
-	// very first init
-	if (!lastEnv) {
+	if (firstInit) {
 		SWLog::setSystemLog(new AndroidLogger());
 		SWLog::getSystemLog()->setLogLevel(SWLog::LOG_DEBUG);
 		StringMgr::setSystemStringMgr(new AndroidStringMgr());
+		firstInit = false;
 	}
-	if (env) lastEnv = env;
 	if (!mgr) {
 SWLog::getSystemLog()->logDebug("libsword: init() begin");
 		SWBuf baseDir  = SWORD_PATH;
@@ -1034,7 +1047,7 @@
 	jstring sourceNameJS = (jstring)env->GetObjectField(me, sourceFieldID);
 	const char *modName = (modNameJS?env->GetStringUTFChars(modNameJS, NULL):0);
 	const char *sourceName = (sourceNameJS?env->GetStringUTFChars(sourceNameJS, NULL):0);
-SWLog::getSystemLog()->logDebug("libsword: lookup up module %s at from source: %s", modName?modName:"null", sourceName?sourceName:"null");
+SWLog::getSystemLog()->logDebug("libsword: lookup up module %s from source: %s", modName?modName:"<null>", sourceName?sourceName:"<null>");
 
 	if (sourceName && *sourceName) {
 		initInstall(env);
@@ -1644,12 +1657,14 @@
 
 
 		const char *configValue = module->getConfigEntry(configKey);
+//SWLog::getSystemLog()->logDebug("getConfigEntry, configValue: %s", configValue);
 		if (configValue) {
 			SWBuf confValue = configValue;
 			// special processing if we're requesting About-- kindof cheese
 			if (!strcmp("About", configKey)) {
 				RTFHTML().processText(confValue);
 			}
+//SWLog::getSystemLog()->logDebug("getConfigEntry, configValue: %s", confValue.c_str());
 			retVal = strToUTF8Java(env, assureValidUTF8(confValue.c_str()));
 		}
 	}
@@ -2245,6 +2260,7 @@
 }
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+	javaVM = vm;
 	return JNI_VERSION_1_2;
 }
 




More information about the sword-cvs mailing list