我使用Windows EvtSubscribe(推送)来获取事件并将其发送到java进行处理。从方法Java_evetsubscribepush
返回时,我在java中接收 java.lang.StackOverflowError 。这是我的示例代码。无论它运行几秒钟还是几个小时 java.lang.StackOverflowError 仅在代码退出时发生,而不是在发送事件的java用法之间。我有什么遗失的吗?
JNIEXPORT jobject JNICALL Java_evetsubscribepush(JNIEnv *env, jobject obj){
wprintf( L"\n Java_evetsubscribepush starts");
CoInitialize(NULL);
DWORD res = ERROR_SUCCESS;
EventSubscribeLog * handler = new EventSubscribeLog();
res = handler->EventSubscribePush ( handler ,env);
CoUninitialize();
wprintf( L"\n Java_evetsubscribepush ends" );
return NULL;
}
DWORD EventSubscribeLog::EventSubscribePush ( EventSubscribeLog * handler , JNIEnv *javaEnv)
{
DWORD status = ERROR_SUCCESS;
LPWSTR Path = L"Security";
LPWSTR Query = L"<QueryList>" \
L" <Query Id='0' Path='Security'>" \
L" <Select Path='Security'>*</Select>" \
L" </Query>" \
L"</QueryList>";
EVT_HANDLE hSubscription = NULL;
EVT_HANDLE sessionHndl = OpenRemoteSession ();
if (sessionHndl == NULL) {
log ( javaEnv, L"\n EvtSubscribe open remote session failed in %lu", status );
goto exit;
}
DWORD callBACKstatus = ERROR_SUCCESS;
USER_CONTEXT UserContext;
UserContext.handler = handler;
UserContext.callBACKstatus = &callBACKstatus;
UserContext.env = javaEnv;
hSubscription = EvtSubscribe ( sessionHndl, NULL, Path, Query, NULL, &UserContext,
(EVT_SUBSCRIBE_CALLBACK) EventSubscribeLog::SubscriptionCallback, EvtSubscribeToFutureEvents );
if (NULL == hSubscription) {
status = GetLastError ( );
log ( javaEnv, L"\n EvtSubscribe failed %lu. ", status );
goto exit;
}
while (true) {
if (ERROR_SUCCESS != callBACKstatus) {
status = callBACKstatus;
log ( javaEnv, L"\n EvtSubscribe call Back failed with error code %lu. ", status );
goto exit;
}
Sleep ( 5000 );
}
log ( javaEnv, L"\n EvtSubscribe PUSH ends. " );
exit:
if (hSubscription) {
EvtClose ( hSubscription );
}
if (sessionHndl) {
EvtClose ( sessionHndl );
}
if (Query != NULL) {
free ( Query );
Query = NULL;
}
return status;
}
// The callback that receives the events.(static method)
DWORD WINAPI EventSubscribeLog::SubscriptionCallback ( EVT_SUBSCRIBE_NOTIFY_ACTION action, PVOID pContext, EVT_HANDLE hEvent )
{
DWORD status = ERROR_SUCCESS;
PUSER_CONTEXT Callbackcontext = (PUSER_CONTEXT) pContext;
EventSubscribeLog *handler = Callbackcontext->handler;
DWORD *callBACKstatus = Callbackcontext->callBACKstatus;
JNIEnv *temp_env = Callbackcontext->env;
bool isEnvAttached = FALSE;
JavaVM *callBackJVM;
JNIEnv *callBackEnv;
if (temp_env->GetJavaVM ( &callBackJVM ) < 0)
{
goto exit;
}
if (callBackJVM->AttachCurrentThread ( (void **) &callBackEnv, NULL ) < 0)
{
goto exit;
}
isEnvAttached = TRUE;
if (action == EvtSubscribeActionError) {
status = (DWORD) hEvent;
handler->log ( javaEnv, L"\n The subscription callback received the following Win32 error: %lu", status );
goto exit;
}
if (action == EvtSubscribeActionDeliver) {
handler->SendEventToJDKPUSH ( hEvent, handler, callBackEnv );
}
exit:
if (isEnvAttached) {
callBackJVM->DetachCurrentThread ( );
}
if (ERROR_SUCCESS != status) {
*callBACKstatus = status;
}
return status;
}
void EventSubscribeLog::SendEventToJDKPUSH ( EVT_HANDLE hEvent, EventSubscribeLog *handle, JNIEnv *watcherJNIEnv )
{
PEVT_VARIANT RenderedValues = EventRender ( watcherJNIEnv, hEvent, 1 );
if (RenderedValues != NULL) {
__try {
WORD EvtId = RenderedValues[EvtSystemEventID].UInt16Val;
LPCWSTR EvtProviderName = RenderedValues[EvtSystemProviderName].StringVal;
ULONGLONG I64Time = RenderedValues[EvtSystemTimeCreated].FileTimeVal;
unsigned long EvtTimeCreated = FileTimeToUnixTime ( I64Time );
unsigned long EvtTimeWritten = EvtTimeCreated;
unsigned __int64 EvtRecordNumber = RenderedValues[EvtSystemEventRecordId].UInt64Val;
WORD EvtCategory = RenderedValues[EvtSystemTask].UInt16Val;
jobject
eventHash = watcherJNIEnv->NewObject ( jClHashtable, jConHashtable ),
jEvtCategory = watcherJNIEnv->NewObject ( intClass, intConID, EvtCategory ),
jEvtCode = watcherJNIEnv->NewObject ( intClass, intConID, EvtId ),
jEvtTimeGenerated = watcherJNIEnv->NewObject ( intClass, intConID, EvtTimeCreated ),
jEvtTimeWritten = watcherJNIEnv->NewObject ( intClass, intConID, EvtTimeWritten ),
jEvtRecordNumber = watcherJNIEnv->NewObject ( longClass, longConID, EvtRecordNumber ),
watcherJNIEnv->CallObjectMethod ( eventHash, jMtdPutHashtable, jEvtCategoryKey, jEvtCategory );
watcherJNIEnv->CallObjectMethod ( eventHash, jMtdPutHashtable, jEvtCodeKey, jEvtCode );
watcherJNIEnv->CallObjectMethod ( eventHash, jMtdPutHashtable, jEvtTimeGeneratedKey, jEvtTimeGenerated );
watcherJNIEnv->CallObjectMethod ( eventHash, jMtdPutHashtable, jEvtTimeWrittenKey, jEvtTimeWritten );
watcherJNIEnv->CallObjectMethod ( eventHash, jMtdPutHashtable, jEvtRecordNumberKey, jEvtRecordNumber );
watcherJNIEnv->CallStaticVoidMethod ( AppServerClass, evtNotify, eventHash ); //send event to java cache
if (watcherJNIEnv->ExceptionOccurred ( ) != NULL) {
log ( watcherJNIEnv, L"Exception occurred here in SendEventToJDKPUSH ...!" );
watcherJNIEnv->ExceptionDescribe ( );
watcherJNIEnv->ExceptionCheck ( );
watcherJNIEnv->ExceptionClear ( );
}
watcherJNIEnv->DeleteLocalRef ( jEvtCategory );
watcherJNIEnv->DeleteLocalRef ( jEvtCode );
watcherJNIEnv->DeleteLocalRef ( jEvtTimeGenerated );
watcherJNIEnv->DeleteLocalRef ( jEvtTimeWritten );
watcherJNIEnv->DeleteLocalRef ( jEvtRecordNumber );
watcherJNIEnv->DeleteLocalRef ( eventHash );
} __except (EXCEPTION_EXECUTE_HANDLER) {
log ( watcherJNIEnv, L"Exception Caught in SendEventToJDKPUSH %lu", GetExceptionCode ( ) );
}
goto exit;
} else {
log ( watcherJNIEnv, L"Rendering Failed in SendEventToJDKPUSH" );
goto exit;
}
exit:
free ( RenderedValues );
RenderedValues = NULL;
}
PEVT_VARIANT EventSubscribeLog::EventRender(JNIEnv *javaEnv, EVT_HANDLE hEvent, int renderContextFlag)
{
DWORD error = ERROR_SUCCESS;
EVT_HANDLE hContext = NULL;
DWORD dwBufferSize = 0;
DWORD dwBufferUsed = 0;
DWORD dwPropertyCount = 0;
PEVT_VARIANT RenderedValues = NULL;
BOOL ret = false;
if (renderContextFlag == 1){
hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
}else{
hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextUser);
}
if (NULL == hContext){
error = GetLastError();
log( javaEnv, L"EventRender:EvtCreateRenderContext failed with %lu", error);
goto exit;
}
ret = EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, RenderedValues, &dwBufferUsed, &dwPropertyCount);
if (!ret){
error = GetLastError();
if (error == ERROR_INSUFFICIENT_BUFFER){
dwBufferSize = dwBufferUsed;
RenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (RenderedValues){
ret = EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, RenderedValues, &dwBufferUsed, &dwPropertyCount);
if (!ret){
log( javaEnv, L"EventRender:EvtRender failed with %lu", error);
}
}else{
log( javaEnv, L"EventRender:malloc failed");
error = E_OUTOFMEMORY;
goto exit;
}
}else{
log( javaEnv, L"EventRender:EvtRender failed with %lu", error);
goto exit;
}
}
exit:
if (hContext) {EvtClose(hContext);}
return RenderedValues;
}
void log ( JNIEnv *javaEnv, const wchar_t* message, ... ) //For JAVA Log method
{
va_list args;
int len;
wchar_t * buffer;
va_start ( args, message );
len = _vscwprintf ( message, args ) + 1;
buffer = (wchar_t*) malloc ( len * sizeof ( wchar_t ) );
vswprintf ( buffer, message, args );
jstring jsMessage = javaEnv->NewString ( (jchar*) buffer, wcslen ( buffer ) );
javaEnv->CallStaticVoidMethod ( LogClass, LogMethod, jsMessage );
free ( buffer );
javaEnv->DeleteLocalRef ( jsMessage );
}
在Java中
public static void log( String message) {
nativeLogger.log(Level.WARNING, message);
}
异常追踪:
java.lang.StackOverflowError
at evetsubscribepush.log(evetsubscribepush.java:XX)
我得到的就是Exception trace。