瀏覽代碼

HPCC-23126 Fix regression in javaembed_ex8 test

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 5 年之前
父節點
當前提交
3aeff6e6de
共有 2 個文件被更改,包括 38 次插入18 次删除
  1. 35 18
      plugins/javaembed/javaembed.cpp
  2. 3 0
      testing/regress/ecl/javascope.ecl

+ 35 - 18
plugins/javaembed/javaembed.cpp

@@ -2323,6 +2323,7 @@ public:
         // the Java thread
         contexts.kill();
         persistedObjects.kill();
+        loaders.kill();
         // According to the Java VM 1.7 docs, "A native thread attached to
         // the VM must call DetachCurrentThread() to detach itself before
         // exiting."
@@ -2375,9 +2376,41 @@ public:
         p->crit.enter();  // needed to keep code common between local/global cases
         return p;
     }
+
+    jobject createThreadClassLoader(const char *classPath, const char *classname, size32_t bytecodeLen, const byte *bytecode)
+    {
+        if (bytecodeLen || (classPath && *classPath))
+        {
+            jstring jClassPath = (classPath && *classPath) ? JNIenv->NewStringUTF(classPath) : nullptr;
+            jobject helperName = JNIenv->NewStringUTF(helperLibraryName);
+            jobject contextClassLoaderObj = JNIenv->CallStaticObjectMethod(customLoaderClass, clc_newInstance, jClassPath, getSystemClassLoader(), bytecodeLen, (uint64_t) bytecode, helperName);
+            assertex(contextClassLoaderObj);
+            return contextClassLoaderObj;
+        }
+        else
+        {
+            return getSystemClassLoader();
+        }
+    }
+    jobject getThreadClassLoader(const char *classPath, const char *classname, size32_t bytecodeLen, const byte *bytecode)
+    {
+        StringBuffer key(classname);
+        if (classPath && *classPath)
+            key.append('!').append(classPath);
+        PersistedObject *p;
+        p = loaders.find(key);
+        if (!p)
+        {
+            p = new PersistedObject(key);
+            p->instance = JNIenv->NewGlobalRef(createThreadClassLoader(classPath, classname, bytecodeLen, bytecode), "cachedClassLoader");
+            loaders.replaceOwn(*p);
+        }
+        return p->instance;
+    }
 private:
     IArrayOf<IEmbedFunctionContext> contexts;
     StringMapOf<PersistedObject> persistedObjects = { false };
+    StringMapOf<PersistedObject> loaders = { false };
 };
 
 class JavaXmlBuilder : implements IXmlWriterExt, public CInterface
@@ -3673,7 +3706,7 @@ public:
                 if (classLoader)
                 {
                     JNIenv->DeleteGlobalRef(classLoader);
-                    javaClass = nullptr;
+                    classLoader = nullptr;
                 }
                 loadFunction(classpath, 0, nullptr);
             }
@@ -4280,22 +4313,6 @@ protected:
         return s.append(methodName);
     }
 
-    jobject createThreadClassLoader(const char *classPath, size32_t bytecodeLen, const byte *bytecode)
-    {
-        if (bytecodeLen || (classPath && *classPath))
-        {
-            jstring jClassPath = (classPath && *classPath) ? JNIenv->NewStringUTF(classPath) : nullptr;
-            jobject helperName = JNIenv->NewStringUTF(helperLibraryName);
-            jobject contextClassLoaderObj = JNIenv->CallStaticObjectMethod(customLoaderClass, clc_newInstance, jClassPath, sharedCtx->getSystemClassLoader(), bytecodeLen, (uint64_t) bytecode, helperName);
-            assertex(contextClassLoaderObj);
-            return contextClassLoaderObj;
-        }
-        else
-        {
-            return sharedCtx->getSystemClassLoader();
-        }
-    }
-
     jobject createInstance()
     {
         jmethodID constructor;
@@ -4373,7 +4390,7 @@ protected:
                 {
                     if (!classname)
                         throw MakeStringException(MSGAUD_user, 0, "Invalid import name - Expected classname.methodname:signature");
-                    classLoader = JNIenv->NewGlobalRef(createThreadClassLoader(classpath, bytecodeLen, bytecode), "classLoader");
+                    classLoader = JNIenv->NewGlobalRef(sharedCtx->getThreadClassLoader(classpath, classname, bytecodeLen, bytecode), "classLoader");
                     sharedCtx->setThreadClassLoader(classLoader);
 
                     jmethodID loadClassMethod = JNIenv->GetMethodID(JNIenv->GetObjectClass(classLoader), "loadClass","(Ljava/lang/String;)Ljava/lang/Class;");

+ 3 - 0
testing/regress/ecl/javascope.ecl

@@ -17,6 +17,9 @@
 
 IMPORT Java;
 
+//class=embedded
+//class=3rdparty
+
 //version forceNonThread=false
 //version forceNonThread=true