-
Bug
-
Resolution: Fixed
-
P3
-
1.4.0
-
beta
-
x86
-
windows_2000
By examination of the code, we have found a JNI reference leak in the new
focus implementation:
void AwtWindow::SendWindowEvent(jint id, HWND opposite)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...
if (env->EnsureLocalCapacity(3) < 0) {
return;
}
jobject target = GetTarget(env);
jobject jOpposite = NULL;
if (opposite != NULL) {
AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
if (awtOpposite != NULL) {
jOpposite = awtOpposite->GetTarget(env);
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
jOpposite);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
env->DeleteLocalRef(jOpposite); jOpposite = NULL;
}
env->DeleteLocalRef(target); target = NULL;
if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
{
jobject sequencedEvent = env->NewObject(sequencedEventCls,
sequencedEventConst,
event);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(sequencedEvent != NULL);
env->DeleteLocalRef(event);
event = sequencedEvent;
}
SendEvent(event);
env->DeleteLocalRef(target);
}
The call to 'env->DeleteLocalRef(target);' at the end of the method is
clearly wrong. 'target' was explicitly set to NULL earlier in the method.
In addition, the local reference to 'event' is never deleted, so WindowEvents
can never be garbage collected.
focus implementation:
void AwtWindow::SendWindowEvent(jint id, HWND opposite)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
...
if (env->EnsureLocalCapacity(3) < 0) {
return;
}
jobject target = GetTarget(env);
jobject jOpposite = NULL;
if (opposite != NULL) {
AwtComponent *awtOpposite = AwtComponent::GetComponent(opposite);
if (awtOpposite != NULL) {
jOpposite = awtOpposite->GetTarget(env);
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
jOpposite);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
env->DeleteLocalRef(jOpposite); jOpposite = NULL;
}
env->DeleteLocalRef(target); target = NULL;
if (id == java_awt_event_WindowEvent_WINDOW_GAINED_FOCUS ||
id == java_awt_event_WindowEvent_WINDOW_LOST_FOCUS)
{
jobject sequencedEvent = env->NewObject(sequencedEventCls,
sequencedEventConst,
event);
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(sequencedEvent != NULL);
env->DeleteLocalRef(event);
event = sequencedEvent;
}
SendEvent(event);
env->DeleteLocalRef(target);
}
The call to 'env->DeleteLocalRef(target);' at the end of the method is
clearly wrong. 'target' was explicitly set to NULL earlier in the method.
In addition, the local reference to 'event' is never deleted, so WindowEvents
can never be garbage collected.