I am currently working on creating some Java bindings for a C library I work on. One of our C-structs has a char buffer that is a file system path. After calling the C function, the buffer is correctly populated. I want to take the buffer and convert it to a java.nio.file.Path
member on the Java object.
I am having some trouble however. I for some reason am generating a NullPointerException
within C, and I can’t really see the problem.
The way to create a java.nio.file.Path
object is going through java.nio.file.Paths::get()
.
Here is the relevant C code:
const jclass paths_class = (*env)->FindClass(env, "java/nio/file/Paths"); if ((*env)->ExceptionCheck(env)) return; const jmethodID get_method = (*env)->GetStaticMethodID( env, paths_class, "get", "(Ljava/lang/String;[Ljava/lang/String;)Ljava/nio/file/Path;"); if ((*env)->ExceptionCheck(env)) return; const jstring path_str = (*env)->NewStringUTF(env, info.mi_path); if ((*env)->ExceptionCheck(env)) return; const jobject path_obj = (*env)->CallStaticObjectMethod(env, paths_class, get_method, path_str); // exception generated here if ((*env)->ExceptionCheck(env)) return;
And the Java class for good measure:
public final class MclassInfo { private native void _get(final Kvdb kvdb, Mclass mclass) throws HseException; private long allocatedBytes; private long usedBytes; private Path path; MclassInfo(final Kvdb kvdb, final Mclass mclass) throws HseException { _get(kvdb, mclass); } public long getAllocatedBytes() { return allocatedBytes; } public long getUsedBytes() { return usedBytes; } public Path getPath() { return path; } }
All I can think is that somehow I am not calling the Java variadic function properly. I have also tried passing NULL
as an extra argument to the method call, but ended up with the same issue.
Advertisement
Answer
The method you are trying to invoke is declared as get(String first, String... more)
. The variadic syntax in Java is just sugar for an array of the specified type, i.e. the two arguments of this method are really String
and String[]
— which you correctly coded in the GetStaticMethodID
call as (Ljava/lang/String;[Ljava/lang/String;)
.
So to call it you need two arguments: one String
and one String[]
(array) — and (for your case) the array must contain zero elements, but such an empty array is not the same as NULL. Have a gander at NewObjectArray
.