Note that there are some explanatory texts on larger screens.

plurals
  1. POProblems with using a windows service to invoke a java program using JNI and LoadLibrary
    primarykey
    data
    text
    <p>I'm creating a windows service program which invokes a java program.</p> <p>Here is part of the code, hModule is a global variable and LoadLibrary is called in ServiceStart after which it invoked invokeJVM. I manage to start the service and it runs fine, however, whenever I stop the service, it gives me an error: Windows could not stop the service on the local computer Error 1067: The windows service terminated unexpectedly</p> <p>After adding additional logging, I found that the place where the unexpected termination error occurs is the return of the invokeJVM function. When I check the event viewer it gives me some BEX error, which on googling, says that it is a stack overflow error, but I could not determine the cause of it, any idea why?</p> <pre><code>HMODULE hModule; VOID ServiceStart ( DWORD dwArgc, LPTSTR *lpszArgv ) { // Let the service control manager know that the service is // initializing. if ( !ReportStatus( SERVICE_START_PENDING, NO_ERROR, 3000 ) ) //goto cleanup; return; hModule = LoadLibrary( TEXT( "C:\\Program Files (x86)\\Java\\jre6\\bin\\client\\jvm.dll" ) ); // Create a Stop Event if ( !( hServerStopEvent = CreateEvent( NULL, TRUE, FALSE, NULL) ) ) goto cleanup; lpszJavaArgs = getJavaArgs( &amp;lpszJavaArgs, &amp;dwJLen, dwArgc, lpszArgv ); lpszAppArgs = getAppArgs( &amp;lpszAppArgs, &amp;dwALen, dwArgc, lpszArgv ); wrkdir = getWorkingDirectory( dwArgc, lpszArgv ); if ( !ReportStatus( SERVICE_RUNNING, NO_ERROR, 0 ) ) goto cleanup; // After the initialization is complete (we've checked for arguments) and // the service control manager has been told the service is running, invoke // the Java application. If clients are unable to access // the server, check the event log for messages that should indicate any errors // that may have occured while firing up Java... invokeJVM( NULL ); // Wait for the stop event to be signalled. WaitForSingleObject( hServerStopEvent, INFINITE ); cleanup: ( VOID ) ReportStatus( SERVICE_STOPPED, 0, 0 ); if ( hServerStopEvent ) CloseHandle( hServerStopEvent ); ( *vm ) -&gt; DestroyJavaVM( vm ); FreeLibraryAndExitThread( hModule, 0 ); return; } VOID invokeJVM( VOID *dummy ) { jint res; jclass cls; jmethodID mid; jstring jstr; jobjectArray args; JavaVMInitArgs vm_args; JavaVMOption options[ MAX_OPTIONS ]; jint ( *createJavaVM )( JavaVM **, void **, void * ) = ( jint ( * )( JavaVM **, void **, void * ) ) GetProcAddress( hModule, "JNI_CreateJavaVM" ); char buf[256]; jclass cls2; jmethodID mid2; UINT uIdx; if ( wrkdir ) { if ( !SetCurrentDirectory( wrkdir ) ) AddToMessageLog( TEXT( "Unable to change working directory." ) ); } if(dwJLen &gt; MAX_OPTIONS) { AddToMessageLog( TEXT( "Max. number of Java args exceeded." ) ); return; } // Assign the arguments for the JVM, such as the classpath, // RMI codebase, etc. for ( uIdx = 0; uIdx &lt; dwJLen; ++uIdx ) options[ uIdx ].optionString = lpszJavaArgs[ uIdx ]; // PROBLEM HERE vm_args.version = JNI_VERSION_1_6; vm_args.options = options; vm_args.nOptions = dwJLen; vm_args.ignoreUnrecognized = TRUE; //res = JNI_CreateJavaVM( &amp;vm, ( void ** ) &amp;env, &amp;vm_args ); res = ( *createJavaVM )( &amp;vm, ( void ** ) &amp;env, &amp;vm_args ); if ( res &lt; 0 ) { AddToMessageLog( TEXT( "Cannot create Java VM." ) ); return; } // Get the main class if ( !( cls = ( *env ) -&gt; FindClass( env, SZMAINCLASS ) ) ) { AddToMessageLog( TEXT( "Cannot find main class." ) ); return; } // Get the method ID for the class's main(String[]) function. if ( !( mid = ( *env ) -&gt; GetStaticMethodID( env, cls, "main", "([Ljava/lang/String;)V" ) ) ) { AddToMessageLog( TEXT( "Cannot find main method." ) ); return; } // If there are arguments, create an ObjectArray sized to contain the // argument list, and then scan the list, inserting each argument into // the ObjectArray. if( dwALen &gt; 0 ) { if ( !( args = ( *env ) -&gt; NewObjectArray( env, dwALen, ( *env ) -&gt; FindClass( env, "java/lang/String" ), NULL ) ) ) { AddToMessageLog( TEXT( "Out of Memory!" ) ); return; } for( uIdx = 0; uIdx &lt; dwALen; ++uIdx ) { if ( !( jstr = ( *env ) -&gt; NewStringUTF( env, lpszAppArgs[ uIdx ] ) ) ) { AddToMessageLog( TEXT( "Out of Memory!" ) ); return; } ( *env ) -&gt; SetObjectArrayElement( env, args, uIdx, jstr ); } } // Otherwise, create an empty array. This is needed to avoid // creating an overloaded main that takes no arguments in the Java // app, and then getting a different method ID to the no-argument // main() method in this invoker code. else { args = ( *env ) -&gt; NewObjectArray( env, 0, ( *env ) -&gt; FindClass( env, "java/lang/String" ), NULL ); } //Now, get the class of the java SCMEventManager if ( !( cls2 = ( *env ) -&gt; FindClass( env, SZSCMEVENTMANAGER ) ) ) { AddToMessageLog( TEXT( "Cannot find SCMEventManager class." ) ); goto finished; } //Get the method ID for SCMEventManager.getInstance() sprintf( buf, "()L%s;", SZSCMEVENTMANAGER ); if ( !( mid2 = ( *env ) -&gt; GetStaticMethodID( env, cls2, "getInstance", buf ) ) ) { AddToMessageLog( TEXT( "Cannot find SCMEventManager.getInstance." ) ); goto finished; } //Call SCMEventManager.getInstance() and save the returned object //We'll use this later on. if ( !( jobj = ( *env ) -&gt; NewGlobalRef( env, ( *env ) -&gt; CallStaticObjectMethod( env, cls2, mid2 ) ) ) ) { AddToMessageLog( TEXT( "Cannot call SCMEventManager.getInstance." ) ); goto finished; } finished: // Run the main class... ( *env ) -&gt; CallStaticVoidMethod( env, cls, mid, args ); SetConsoleCtrlHandler( logoffHandler, TRUE ); return; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload