Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong JNI type in getField: Not Long but Java Object #1482

Open
vonox7 opened this issue Jul 20, 2016 · 11 comments
Open

Wrong JNI type in getField: Not Long but Java Object #1482

vonox7 opened this issue Jul 20, 2016 · 11 comments

Comments

@vonox7
Copy link
Contributor

vonox7 commented Jul 20, 2016

When setting a ConnectionLogger or OperationQueueListener to SMTPSession the setupNative function fails with the following error:
JNI GetObjectField called with pending exception java.lang.NoSuchFieldError: no "J" field "connectionLogger" in class "Lcom/libmailcore/SMTPSession;" or its superclasses

The connectionLogger/operationQueueListener field in SMTPSession is not a Long ("J") but an Object ("L..."), therefore the JNI GetFieldID function fails.

In File JavaHandle.cpp the function getField fetches through JNI an object, but GetFieldID falsly assumes that the type to search is a Long instead of an Java Object:

static jfieldID getField(JNIEnv * env, jobject obj, const char * fieldName)
{
    jclass c = env->GetObjectClass(obj);
    return env->GetFieldID(c, fieldName, "J");
}

The getField function is only called by getObjectField():

jobject mailcore::getObjectField(JNIEnv *env, jobject obj, const char * fieldName)
{
    return env->GetObjectField(obj, getField(env, obj, fieldName));
}

Expected code:
jclass c = env->GetFieldID(c, fieldName, "Lcom/libmailcore/ConnectionLogger;")
and
jclass c = env->GetFieldID(c, fieldName, "Lcom/libmailcore/OperationQueueListener;")

To solve this issue for all functions that use the getObjectField function, we would need an additional parameter that specifies the Java class we are looking for. (ConnectionLogger, OperationQueueListener...).

@functionaldude
Copy link

+1

@dinhvh
Copy link
Member

dinhvh commented Jul 22, 2016

Could you send a pull request to fix it?
Thanks!

@vonox7
Copy link
Contributor Author

vonox7 commented Jul 23, 2016

I tried to fix it, but apparently there are more bugs related to that issue.

@dinhvh
Copy link
Member

dinhvh commented Jul 23, 2016

@vonox7, would the following work?

static jfieldID getFieldForObject(JNIEnv * env, jobject obj, const char * fieldName)
{
    jclass c = env->GetObjectClass(obj);
    return env->GetFieldID(c, fieldName, "Ljava/lang/Object;");
}

jobject mailcore::getObjectField(JNIEnv *env, jobject obj, const char * fieldName)
{
    return env->GetObjectField(obj, getFieldForObject(env, obj, fieldName));
}

@vonox7
Copy link
Contributor Author

vonox7 commented Jul 26, 2016

Unfortunately, "Ljava/lang/Object;" won't work, as we get an NoSuchFieldError, see stacktrace: https://gist.github.com/vonox7/90f9bdd4c422f4925f99ba1933f7145e

By using the followig hack we get the correct field (connectionLogger/operationQueueListener), but then there seems to be some threading issues, have a look at the stacktrace: https://gist.github.com/vonox7/5868369b8ce76f254e1c72c6a3edf3bb
Hacky solution in getFieldForObject:

if (strcmp ("connectionLogger", fieldName) == 0) {
        return env->GetFieldID(c, fieldName, "Lcom/libmailcore/ConnectionLogger;");
    } else if (strcmp ("operationQueueListener", fieldName) == 0) {
        return env->GetFieldID(c, fieldName, "Lcom/libmailcore/OperationQueueListener;");
    }
}

@dinhvh
Copy link
Member

dinhvh commented Jul 26, 2016

Could you create a specific method for connectionLogger and send a pull request?

@vonox7
Copy link
Contributor Author

vonox7 commented Jul 26, 2016

As said above, even with the specific object call it will crash because of threading issues. Can you have a look into that threading issue? https://gist.github.com/vonox7/5868369b8ce76f254e1c72c6a3edf3bb

@dinhvh
Copy link
Member

dinhvh commented Jul 26, 2016

Ah ok. We probably need to fix mailcore::JavaConnectionLogger::log() to lookup properly connectionLogger from a thread.

@beczesz
Copy link
Contributor

beczesz commented Aug 22, 2017

Any news about this issue?

@BigNateBombBomb
Copy link

Same boat here. Having issues with Office365 SMTP and would love to be able to see the actual responses so I can pinpoint the issue better

@filippo-orru
Copy link

I'd also really benefit from this. I'm trying to debug why creating a "manual" IMAP connection works, but mailcore doesn't

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants