2424#include <stdio.h>
2525#include <stdlib.h>
2626
27+ #ifdef WINDOWS
28+ #include <windows.h>
29+ #else
30+ #include <dlfcn.h>
31+ #endif // WINDOWS
32+
2733#include "jni.h"
2834
2935static JavaVM * jvm ;
@@ -52,6 +58,48 @@ static void report(const char* func, int ret_actual, int ret_expected) {
5258
5359static int using_system_exit = 0 ; // Not System.exit by default
5460
61+ typedef jint (JNICALL * GetDefaultJavaVMInitArgs_t )(void * args );
62+ typedef jint (JNICALL * GetCreatedJavaVMs_t )(JavaVM * * vmBuf , jsize bufLen , jsize * nVMs );
63+ typedef jint (JNICALL * CreateJavaVM_t )(JavaVM * * pvm , void * * penv , void * args );
64+
65+ GetDefaultJavaVMInitArgs_t GetDefaultJavaVMInitArgs = NULL ;
66+ GetCreatedJavaVMs_t GetCreatedJavaVMs = NULL ;
67+ CreateJavaVM_t CreateJavaVM = NULL ;
68+
69+ // VM is already loaded.
70+ jboolean getJavaVMfunctions () {
71+ #ifdef WINDOWS
72+ HMODULE handle ;
73+ handle = GetModuleHandle ("jvm.dll" );
74+ if (handle == NULL ) {
75+ // No loaded jvm.dll. Get the handle to the executable.
76+ handle = GetModuleHandle (NULL );
77+ }
78+ #endif
79+
80+ #ifdef WINDOWS
81+ #define GET_VM_FUNCTION (f ) GetProcAddress(handle, f)
82+ #else
83+ #define GET_VM_FUNCTION (f ) dlsym(RTLD_DEFAULT, f)
84+ #endif
85+ GetDefaultJavaVMInitArgs = (GetDefaultJavaVMInitArgs_t )GET_VM_FUNCTION ("JNI_GetDefaultJavaVMInitArgs" );
86+ if (GetDefaultJavaVMInitArgs == NULL ) {
87+ fprintf (stderr , "Failed to find JNI_GetDefaultJavaVMInitArgs" );
88+ return JNI_FALSE ;
89+ }
90+ GetCreatedJavaVMs = (GetCreatedJavaVMs_t )GET_VM_FUNCTION ("JNI_GetCreatedJavaVMs" );
91+ if (GetCreatedJavaVMs == NULL ) {
92+ fprintf (stderr , "Failed to find JNI_GetCreatedJavaVMs" );
93+ return JNI_FALSE ;
94+ }
95+ CreateJavaVM = (CreateJavaVM_t )GET_VM_FUNCTION ("JNI_CreateJavaVM" );
96+ if (CreateJavaVM == NULL ) {
97+ fprintf (stderr , "Failed to find JNI_CreateJavaVM" );
98+ return JNI_FALSE ;
99+ }
100+ return JNI_TRUE ;
101+ }
102+
55103JNIEXPORT
56104void JNICALL Java_TestAtExit_00024Tester_setUsingSystemExit (JNIEnv * env , jclass c ) {
57105 using_system_exit = 1 ;
@@ -60,6 +108,10 @@ void JNICALL Java_TestAtExit_00024Tester_setUsingSystemExit(JNIEnv* env, jclass
60108void at_exit_handler (void ) {
61109 printf ("In at_exit_handler\n" );
62110
111+ if (!getJavaVMfunctions ()) {
112+ return ;
113+ }
114+
63115 // We've saved the JavaVM from OnLoad time so we first try to
64116 // get a JNIEnv for the current thread.
65117 JNIEnv * env ;
@@ -78,12 +130,12 @@ void at_exit_handler(void) {
78130
79131 JavaVMInitArgs args ;
80132 args .version = JNI_VERSION_1_2 ;
81- res = JNI_GetDefaultJavaVMInitArgs (& args );
133+ res = ( * GetDefaultJavaVMInitArgs ) (& args );
82134 report ("JNI_GetDefaultJavaVMInitArgs" , res , JNI_OK );
83135
84136 JavaVM * jvm_p [1 ];
85137 int nVMs ;
86- res = JNI_GetCreatedJavaVMs (jvm_p , 1 , & nVMs );
138+ res = ( * GetCreatedJavaVMs ) (jvm_p , 1 , & nVMs );
87139 report ("JNI_GetCreatedJavaVMs" , res , JNI_OK );
88140 // Whether nVMs is 0 or 1 depends on the termination path
89141 if (nVMs == 0 && !using_system_exit ) {
@@ -98,7 +150,7 @@ void at_exit_handler(void) {
98150 report ("DestroyJavaVM" , res , JNI_ERR );
99151
100152 // Failure mode depends on the termination path
101- res = JNI_CreateJavaVM (jvm_p , (void * * )& env , & args );
153+ res = ( * CreateJavaVM ) (jvm_p , (void * * )& env , & args );
102154 report ("JNI_CreateJavaVM" , res , using_system_exit ? JNI_EEXIST : JNI_ERR );
103155 }
104156 // else test has already failed
0 commit comments