You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/05/25 16:13:30 UTC

svn commit: r541662 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3909/ src/test/regression/excludes/ vm/vmcore/include/ vm/vmcore/src/init/ vm/vmcore/src/jni/

Author: gshimansky
Date: Fri May 25 07:13:29 2007
New Revision: 541662

URL: http://svn.apache.org/viewvc?view=rev&rev=541662
Log:
Applied patch and regression test from HARMONY-3909 [drlvm][thread] Problems with associating native thread with Java thread when using AttachCurrentThread[AsDaemon]


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3909/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
    harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp?view=auto&rev=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp Fri May 25 07:13:29 2007
@@ -0,0 +1,227 @@
+/**
+ * Test case for finalizer threads thread group
+ * Checks that finalizer threads are in system thread group.
+ */
+
+#include <iostream>
+#include <string.h>
+#include <jvmti.h>
+
+using namespace std;
+
+#define PACKAGE "org/apache/harmony/drlvm/tests/regression/h3909/"
+
+static const char* EXCEPTION_CLASS = "L" PACKAGE "InvokeAgentException;";
+
+#define FINALIZER_THREAD_NAME "finalizer"
+
+#define TURN_EVENT(event, state) { \
+    jvmtiError err = turn_event(jvmti, event, state, #event); \
+    if (JVMTI_ERROR_NONE != err) return; \
+}
+
+#define CHECK_RESULT(func) \
+    if (JVMTI_ERROR_NONE != err) { \
+        cerr << "[JvmtiAgent] ERROR: " << #func << " failed with error: " << err << endl;  \
+        return; \
+    }
+
+#define CHECK_JNI3(result, func, error_code) { \
+    if (jni->ExceptionCheck()) { \
+        cerr << "[JvmtiAgent] ERROR: unexpected exception in " << #func << endl;  \
+        jni->ExceptionDescribe(); \
+        return error_code; \
+    } \
+    if (! (result)) { \
+        cerr << "[JvmtiAgent] ERROR: get NULL in " << #func << endl;  \
+        return error_code; \
+    } \
+}
+
+#define CHECK_JNI(result, func) CHECK_JNI3(result, func, )
+
+static void set_passed_state(JNIEnv* jni)
+{
+    cerr << endl << "TEST PASSED" << endl << endl;
+
+    jclass cl = jni->FindClass(PACKAGE "Status");
+    CHECK_JNI(cl, FindClass);
+
+    jfieldID testGroup_field = jni->GetStaticFieldID(cl, "status", "Z");
+    CHECK_JNI(testGroup_field, GetStaticFieldID);
+
+    jni->SetStaticBooleanField(cl, testGroup_field, JNI_TRUE);
+    CHECK_JNI(true, SetStaticBooleanField);
+}
+
+static jvmtiError turn_event(jvmtiEnv* jvmti, jvmtiEvent event, bool state,
+        const char* event_name)
+{
+    jvmtiError err;
+    err = jvmti->SetEventNotificationMode(state ? JVMTI_ENABLE : JVMTI_DISABLE,
+            event, NULL);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to " << (state ? "en" : "dis")
+                << "able " << event_name
+                << endl;
+    }
+
+    return err;
+}
+
+static void JNICALL VMInit(jvmtiEnv* jvmti, JNIEnv* jni, jthread thread)
+{
+    cerr << endl << "==> VM Init callback" << endl;
+
+    TURN_EVENT(JVMTI_EVENT_EXCEPTION, true);
+}
+
+static void JNICALL
+Exception(jvmtiEnv *jvmti,
+            JNIEnv* jni,
+            jthread thread,
+            jmethodID method,
+            jlocation location,
+            jobject exception,
+            jmethodID catch_method,
+            jlocation catch_location)
+{
+    jvmtiError err;
+
+    jclass exn_class = jni->GetObjectClass(exception);
+    CHECK_JNI(exn_class, GetObjectClass);
+
+    char* class_name = NULL;
+    err = jvmti->GetClassSignature(exn_class, &class_name, NULL);
+    CHECK_RESULT(GetClassSignature);
+
+    if (0 != strcmp(EXCEPTION_CLASS, class_name))
+        return;
+
+    cerr << endl << "==> Exception callback" << endl;
+    cerr << "    for class: " << class_name << endl;
+
+    TURN_EVENT(JVMTI_EVENT_EXCEPTION, false);
+
+    jint group_count;
+    jthreadGroup* groups;
+
+    err = jvmti->GetTopThreadGroups(&group_count, &groups);
+    CHECK_RESULT(GetTopThreadGroups);
+
+    if (group_count != 1) {
+        cerr << "group_count: " << group_count << "\texpected: 1" << endl;
+        return;
+    }
+
+    jthreadGroup system_group = groups[0];
+
+    jvmtiThreadGroupInfo group_info;
+
+    err = jvmti->GetThreadGroupInfo(system_group, &group_info);
+    CHECK_RESULT(GetThreadDroupInfo);
+
+    cerr << endl << "System group:\t" << group_info.name << endl;
+
+    jint threads_count;
+    jthread* threads;
+
+    err = jvmti->GetAllThreads(&threads_count, &threads);
+    CHECK_RESULT(GetAllThreads);
+
+    int finalizer_theads_count = 0;
+    bool fail = false;
+
+    cerr << endl << "All threads:" << endl;
+    for (int i = 0; i < threads_count; i++) {
+        jvmtiThreadInfo thread_info;
+
+        err = jvmti->GetThreadInfo(threads[i], &thread_info);
+        CHECK_RESULT(GetThreadInfo);
+
+
+        jvmtiThreadGroupInfo group_info;
+
+        err = jvmti->GetThreadGroupInfo(thread_info.thread_group, &group_info);
+        CHECK_RESULT(GetThreadDroupInfo);
+
+        cerr << i << ":\t" << thread_info.name << "\tin group: "
+                << group_info.name << endl;
+
+        if (0 == strcmp(FINALIZER_THREAD_NAME, thread_info.name)) {
+            finalizer_theads_count ++;
+
+            if (jni->IsSameObject(system_group, thread_info.thread_group)) {
+                cerr << "ok" << endl;
+            } else {
+                cerr << " --- not in system group" << endl;
+                fail = true;
+            }
+        }
+    }
+
+    if (finalizer_theads_count <= 0) {
+        cerr << "FAILED: No finalizer threads found"
+                << endl;
+        return;
+    }
+
+    if (fail) {
+        cerr << "FAILED: Some of finalizer threads are not in system group"
+                << endl;
+        return;
+    }
+
+    cerr << "Found " << finalizer_theads_count
+            << " finalizer threads. All in system group" << endl;
+
+    set_passed_state(jni);
+}
+
+JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
+{
+    jvmtiEnv *jvmti = NULL;
+    jvmtiError err;
+
+    // Get JVMTI interface pointer
+    jint iRes = vm->GetEnv((void**)&jvmti, JVMTI_VERSION);
+    if (JNI_OK != iRes) {
+        cerr << "[JvmtiAgent] ERROR: unable to get JVMTI environment" << endl;
+        return -1;
+    }
+
+    // Set events callbacks
+    jvmtiEventCallbacks callbacks;
+    memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+
+    callbacks.VMInit = VMInit;
+    callbacks.Exception = Exception;
+
+    err = jvmti->SetEventCallbacks(&callbacks, sizeof(jvmtiEventCallbacks));
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to register event callbacks" << endl;
+        return -1;
+    }
+
+    err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
+            JVMTI_EVENT_VM_INIT, NULL);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to enable VMInit event"
+                << endl;
+        return -1;
+    }
+
+    // Set capabilities
+    jvmtiCapabilities capabilities;
+    memset(&capabilities, 0, sizeof(jvmtiCapabilities));
+    capabilities.can_generate_exception_events = 1;
+
+    err = jvmti->AddCapabilities(&capabilities);
+    if (JVMTI_ERROR_NONE != err) {
+        cerr << "[JvmtiAgent] ERROR: unable to possess capabilities" << endl;
+        return -1;
+    }
+
+    // Agent initialized successfully
+    return 0;
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java?view=auto&rev=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java Fri May 25 07:13:29 2007
@@ -0,0 +1,34 @@
+package org.apache.harmony.drlvm.tests.regression.h3909;
+
+import junit.framework.TestCase;
+
+/**
+ * Test case for finalizer threads thread group
+ */
+public class FinalizerThreadGroup extends TestCase {
+
+    public static void main(String args[]) {
+        (new FinalizerThreadGroup()).test();
+    }
+
+    public void test() {
+
+        try {
+            System.err.println("[Java]: Throwing an exception to invoke agent");
+            // pass execution to the agent
+            throw new InvokeAgentException();
+        } catch (Exception e) {
+            System.err.println("[Java]: Exception caught");
+        }
+
+        System.err.println("[Java]: test done");
+        assertTrue(Status.status);
+    }
+}
+
+class InvokeAgentException extends Exception {}
+
+class Status {
+    /** the field should be modified by jvmti agent to determine test result. */
+    public static boolean status = false;
+}

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/FinalizerThreadGroup.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml?view=auto&rev=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml Fri May 25 07:13:29 2007
@@ -0,0 +1,9 @@
+<project name="RUN HARMONY-3909 Regression Test">
+    <target name="run-test">
+        <!-- use special launcher for JVMTI tests -->
+        <run-jvmti-test
+            test="org.apache.harmony.drlvm.tests.regression.h3909.FinalizerThreadGroup"
+            agent="FinalizerThreadGroup"/>
+    </target>
+</project>
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3909/run.test.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.linux.x86_64 Fri May 25 07:13:29 2007
@@ -9,4 +9,6 @@
 H3698
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3894
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3909
 

Modified: harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 (original)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/excludes/exclude.windows.x86_64 Fri May 25 07:13:29 2007
@@ -6,4 +6,7 @@
 H3698
 # Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
 H3894
+# Exclude this test because JVMTI is not implemented for x86_64 in JIT mode yet
+H3909
+
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/finalizer_thread.h Fri May 25 07:13:29 2007
@@ -63,7 +63,7 @@
 
 extern Boolean get_finalizer_shutdown_flag();
 extern Boolean get_finalizer_on_exit_flag();
-extern void finalizer_threads_init(JavaVM *java_vm);
+extern void finalizer_threads_init(JavaVM *java_vm, JNIEnv* jni_env);
 extern void finalizer_shutdown(Boolean start_finalization_on_exit);
 extern void activate_finalizer_threads(Boolean wait);
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/ref_enqueue_thread.h Fri May 25 07:13:29 2007
@@ -41,7 +41,7 @@
 }Ref_Enqueue_Thread_Info;
 
 
-extern void ref_enqueue_thread_init(JavaVM *java_vm);
+extern void ref_enqueue_thread_init(JavaVM *java_vm, JNIEnv* jni_env);
 extern void ref_enqueue_shutdown(void);
 extern void activate_ref_enqueue_thread(Boolean wait);
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/finalizer_thread.cpp Fri May 25 07:13:29 2007
@@ -79,7 +79,17 @@
 static void wait_fin_thread_attached(void)
 { while(!fin_thread_info->thread_attached){hythread_yield();}}
 
-void finalizer_threads_init(JavaVM *java_vm)
+
+jobject get_system_thread_group(JNIEnv* jni_env)
+{
+    jclass thread_class = GetObjectClass(jni_env, jthread_self());
+    jfieldID sysTG_field = GetStaticFieldID(jni_env, thread_class,
+        "systemThreadGroup", "Ljava/lang/ThreadGroup;");
+    assert(sysTG_field);
+    return GetStaticObjectField(jni_env, thread_class, sysTG_field);
+}
+
+void finalizer_threads_init(JavaVM *java_vm, JNIEnv* jni_env)
 {   if(!native_fin_thread_flag)
         return;
     
@@ -107,14 +117,15 @@
     fin_thread_info->thread_ids = (hythread_t *)STD_MALLOC(sizeof(hythread_t) * fin_thread_info->thread_num);
     
     for(unsigned int i = 0; i < fin_thread_info->thread_num; i++){
-        void **args = (void **)STD_MALLOC(sizeof(void *) * 2);
+        void **args = (void **)STD_MALLOC(sizeof(void *) * 3);
         args[0] = (void *)java_vm;
         args[1] = (void *)(UDATA)(i + 1);
+        args[2] = (void*)get_system_thread_group(jni_env);
         fin_thread_info->thread_ids[i] = NULL;
         clear_fin_thread_attached();
         status = hythread_create(&fin_thread_info->thread_ids[i], 0, FINALIZER_THREAD_PRIORITY, 0, (hythread_entrypoint_t)finalizer_thread_func, args);
         assert(status == TM_ERROR_NONE);
-       wait_fin_thread_attached();
+        wait_fin_thread_attached();
     }    
 }
 
@@ -197,55 +208,22 @@
     assert(stat == TM_ERROR_NONE);
 }
 
-void assign_classloader_to_native_threads(JNIEnv *jni_env)
-{
-    jthread self_jthread = jthread_self();
-    ManagedObject *self_obj = (*self_jthread).object;
-    char *thread_jclass_name = "java/lang/Thread";
-    jclass thread_jclass = FindClass(jni_env, thread_jclass_name);
-    Class *thread_class = jclass_to_struct_Class(thread_jclass);
-    Field *loader_field = LookupField(thread_class, "contextClassLoader");
-    unsigned int offset = loader_field->get_offset();
-    
-    char *loader_jclass_name = "java/lang/ClassLoader";
-    jclass loader_jclass = FindClass(jni_env, loader_jclass_name);
-    Class *loader_class = jclass_to_struct_Class(loader_jclass);
-    
-    tmn_suspend_disable();
-    
-    Method *get_loader_method = LookupMethod(loader_class, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
-    assert(get_loader_method);
-    jvalue result;
-    vm_execute_java_method_array((jmethodID)get_loader_method, &result, NULL);
-    ManagedObject *sys_class_loader = (*(result.l)).object;
-    
-    uint32 *the_field = (uint32*)((POINTER_SIZE_INT)self_obj + offset);
-    void *heap_null = Slot::managed_null();
-    assert(sys_class_loader > heap_null);
-    *the_field = (uint32)((POINTER_SIZE_INT)sys_class_loader - (POINTER_SIZE_INT)heap_null);
-    
-    tmn_suspend_enable();
-}
+extern jint set_current_thread_context_loader(JNIEnv* jni_env);
 
 static IDATA finalizer_thread_func(void **args)
 {
     JavaVM *java_vm = (JavaVM *)args[0];
     JNIEnv *jni_env;
-    //jthread java_thread;
     char *name = "finalizer";
-    //jboolean daemon = JNI_TRUE;
-    
-    //IDATA status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon);
-    //assert(status == JNI_OK);
-    //status = jthread_attach(jni_env, java_thread, daemon);
-    //assert(status == TM_ERROR_NONE);
+    // FIXME: use args[1] (thread number) to distinguish finalization threads by name
+
     JavaVMAttachArgs *jni_args = (JavaVMAttachArgs*)STD_MALLOC(sizeof(JavaVMAttachArgs));
     jni_args->version = JNI_VERSION_1_2;
     jni_args->name = name;
-    jni_args->group = NULL;
+    jni_args->group = (jobject)args[2];
     IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args);
     assert(status == JNI_OK);
-    assign_classloader_to_native_threads(jni_env);
+    set_current_thread_context_loader(jni_env);
     assert(!get_fin_thread_attached());
     set_fin_thread_attached();
     

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/ref_enqueue_thread.cpp Fri May 25 07:13:29 2007
@@ -39,8 +39,9 @@
 
 static IDATA ref_enqueue_thread_func(void **args);
 static void wait_ref_thread_attached(void);
+extern jobject get_system_thread_group(JNIEnv* jni_env);
 
-void ref_enqueue_thread_init(JavaVM *java_vm)
+void ref_enqueue_thread_init(JavaVM *java_vm, JNIEnv* jni_env)
 {
     if(!native_ref_thread_flag)
         return;
@@ -57,8 +58,9 @@
     status = hymutex_create(&ref_thread_info->end_mutex, TM_MUTEX_DEFAULT);
     assert(status == TM_ERROR_NONE);
     
-    void **args = (void **)STD_MALLOC(sizeof(void *));
+    void **args = (void **)STD_MALLOC(sizeof(void *)*2);
     args[0] = (void *)java_vm;
+    args[1] = (void*)get_system_thread_group(jni_env);
     status = hythread_create(NULL, 0, REF_ENQUEUE_THREAD_PRIORITY, 0, (hythread_entrypoint_t)ref_enqueue_thread_func, args);
     assert(status == TM_ERROR_NONE);
     
@@ -125,27 +127,21 @@
     assert(stat == TM_ERROR_NONE);
 }
 
-extern void assign_classloader_to_native_threads(JNIEnv *jni_env);
+extern jint set_current_thread_context_loader(JNIEnv* jni_env);
 
 static IDATA ref_enqueue_thread_func(void **args)
 {
     JavaVM *java_vm = (JavaVM *)args[0];
     JNIEnv *jni_env;
-    //jthread java_thread;
     char *name = "ref handler";
-    //jboolean daemon = JNI_TRUE;
-    
-    //IDATA status = vm_attach_internal(&jni_env, &java_thread, java_vm, NULL, name, daemon);
-    //assert(status == JNI_OK);
-    //status = jthread_attach(jni_env, java_thread, daemon);
-    //assert(status == TM_ERROR_NONE);
+
     JavaVMAttachArgs *jni_args = (JavaVMAttachArgs*)STD_MALLOC(sizeof(JavaVMAttachArgs));
     jni_args->version = JNI_VERSION_1_2;
     jni_args->name = name;
-    jni_args->group = NULL;
+    jni_args->group = (jobject)args[1];
     IDATA status = AttachCurrentThreadAsDaemon(java_vm, (void**)&jni_env, jni_args);
     assert(status == JNI_OK);
-    assign_classloader_to_native_threads(jni_env);
+    set_current_thread_context_loader(jni_env);
     inc_ref_thread_num();
     
     while(true){

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp Fri May 25 07:13:29 2007
@@ -451,14 +451,14 @@
     return JNI_OK;
 }
 
-static jint set_main_thread_context_loader(JNIEnv* jni_env) {
-    Global_Env* vm_env = jni_get_vm_env(jni_env);
-    jthread main_thread = jthread_self();
-    jfieldID scl_field = jni_env->GetFieldID(jni_env->GetObjectClass(main_thread),
+jint set_current_thread_context_loader(JNIEnv* jni_env) {
+    jthread current_thread = jthread_self();
+    jfieldID scl_field = jni_env->GetFieldID(jni_env->GetObjectClass(current_thread),
         "contextClassLoader", "Ljava/lang/ClassLoader;");
     assert(scl_field);
+    Global_Env* vm_env = jni_get_vm_env(jni_env);
     jobject loader = jni_env->NewLocalRef((jobject)(vm_env->system_class_loader->GetLoaderHandle()));
-    jni_env->SetObjectField(main_thread, scl_field, loader);
+    jni_env->SetObjectField(current_thread, scl_field, loader);
     jni_env->DeleteLocalRef(loader);
 
     return JNI_OK;
@@ -875,7 +875,7 @@
 
     TRACE("system class loader initialized");
 
-    set_main_thread_context_loader(jni_env);
+    set_current_thread_context_loader(jni_env);
 
     status = run_java_init(jni_env);
     if (status != JNI_OK) return status;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp?view=diff&rev=541662&r1=541661&r2=541662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jni/jni.cpp Fri May 25 07:13:29 2007
@@ -515,10 +515,7 @@
     }
     assert(jthread_self() != NULL);
     *p_jni_env = jni_env;
-    
-    finalizer_threads_init(java_vm);   /* added for NATIVE FINALIZER THREAD */
-    ref_enqueue_thread_init(java_vm);  /* added for NATIVE REFERENCE ENQUEUE THREAD */
-    
+
     // Now JVMTIThread keeps global reference. Discard temporary global reference.
     jni_env->DeleteGlobalRef(java_thread);
 
@@ -526,6 +523,9 @@
     if (status != JNI_OK) {
         goto done;
     }
+
+    finalizer_threads_init(java_vm, jni_env);   /* added for NATIVE FINALIZER THREAD */
+    ref_enqueue_thread_init(java_vm, jni_env);  /* added for NATIVE REFERENCE ENQUEUE THREAD */
 
     // Send VM start event. JNI services are available now.
     // JVMTI services permited in the start phase are available as well.