diff --git a/src/JNI.jl b/src/JNI.jl new file mode 100644 index 0000000..4764169 --- /dev/null +++ b/src/JNI.jl @@ -0,0 +1,606 @@ +module JNI + +# jnienv.jl exports +export JNINativeInterface, JNIEnv, JNIInvokeInterface, JavaVM +# jni_md.h exports +export jint, jlong, jbyte +# jni.h exports +export jboolean, jchar, jshort, jfloat, jdouble, jsize, jprimitive +# constant export +export JNI_TRUE, JNI_FALSE +export JNI_VERSION_1_1, JNI_VERSION_1_2, JNI_VERSION_1_4, JNI_VERSION_1_6, JNI_VERSION_1_8 +# export JNI_VERSION_9, JNI_VERSION_10 # Intentionally excluded, use JNI.JNI_VERSION_9 +export JNI_OK, JNI_ERR, JNI_EDETACHED, JNI_EVERSION, JNI_ENOMEM, JNI_EEXIST, JNI_EINV +# Legacy exports +export jnifunc + +include("jnienv.jl") + +const jniref = Ref(JNINativeInterface()) +global jnifunc + +# jni_md.h +const jint = Cint +#ifdef _LP64 /* 64-bit Solaris */ +# typedef long jlong; +const jlong = Clonglong +const jbyte = Cchar + +# jni.h + +const jboolean = Cuchar +const jchar = Cushort +const jshort = Cshort +const jfloat = Cfloat +const jdouble = Cdouble +const jsize = jint +jprimitive = Union{jboolean, jchar, jshort, jfloat, jdouble, jint, jlong} + +jobject = Ptr{Nothing} +jclass = Ptr{Nothing} +jthrowable = Ptr{Nothing} +jweak = Ptr{Nothing} +jmethodID = Ptr{Nothing} +jfieldID = Ptr{Nothing} +jstring = Ptr{Nothing} +jarray = Ptr{Nothing} +JNINativeMethod = Ptr{Nothing} +jobjectArray = Ptr{Nothing} +jbooleanArray = Ptr{Nothing} +jbyteArray = Ptr{Nothing} +jshortArray = Ptr{Nothing} +jintArray = Ptr{Nothing} +jlongArray = Ptr{Nothing} +jfloatArray = Ptr{Nothing} +jdoubleArray = Ptr{Nothing} +jcharArray = Ptr{Nothing} +jvalue = Int64 + +@enum jobjectRefType begin + JNIInvalidRefType = 0 + JNILocalRefType = 1 + JNIGlobalRefType = 2 + JNIWeakGlobalRefType = 3 +end + +const JNI_VERSION_1_1 = convert(Cint, 0x00010001) +const JNI_VERSION_1_2 = convert(Cint, 0x00010002) +const JNI_VERSION_1_4 = convert(Cint, 0x00010004) +const JNI_VERSION_1_6 = convert(Cint, 0x00010006) +const JNI_VERSION_1_8 = convert(Cint, 0x00010008) +const JNI_VERSION_9 = convert(Cint, 0x00090000) +const JNI_VERSION_10 = convert(Cint, 0x000a0000) + +const JNI_TRUE = convert(Cchar, 1) +const JNI_FALSE = convert(Cchar, 0) + +# Return Values +const JNI_OK = convert(Cint, 0) #/* success */ +const JNI_ERR = convert(Cint, -1) #/* unknown error */ +const JNI_EDETACHED = convert(Cint, -2) #/* thread detached from the VM */ +const JNI_EVERSION = convert(Cint, -3) #/* JNI version error */ +const JNI_ENOMEM = convert(Cint, -4) #/* not enough memory */ +const JNI_EEXIST = convert(Cint, -5) #/* VM already created */ +const JNI_EINVAL = convert(Cint, -6) #/* invalid arguments */ + +# There is likely over specification here +PtrIsCopy = Union{Ptr{jboolean},Ref{jboolean},Array{jboolean,}} +AnyString = Union{AbstractString,Cstring,Ptr{UInt8}} + +function load_jni(penv::Ptr{JNIEnv}) + jnienv = unsafe_load(penv) + jniref[] = unsafe_load(jnienv.JNINativeInterface_) #The JNI Function table + global jnifunc = jniref[] +end +is_jni_loaded() = jniref[].GetVersion != C_NULL + +# === Below Generated by make_jni2.jl === + +GetVersion(env::Ptr{JNIEnv}) = + ccall(jniref[].GetVersion, jint, (Ptr{JNIEnv},), env) + +DefineClass(env::Ptr{JNIEnv}, name::AnyString, loader::jobject, buf::Array{jbyte,1}, len::Integer) = + ccall(jniref[].DefineClass, jclass, (Ptr{JNIEnv}, Cstring, jobject, Ptr{jbyte}, jsize,), env, name, loader, buf, len) + +FindClass(env::Ptr{JNIEnv}, name::AnyString) = + ccall(jniref[].FindClass, jclass, (Ptr{JNIEnv}, Cstring,), env, name) + +FromReflectedMethod(env::Ptr{JNIEnv}, method::jobject) = + ccall(jniref[].FromReflectedMethod, jmethodID, (Ptr{JNIEnv}, jobject,), env, method) + +FromReflectedField(env::Ptr{JNIEnv}, field::jobject) = + ccall(jniref[].FromReflectedField, jfieldID, (Ptr{JNIEnv}, jobject,), env, field) + +ToReflectedMethod(env::Ptr{JNIEnv}, cls::jclass, methodID::jmethodID, isStatic::jboolean) = + ccall(jniref[].ToReflectedMethod, jobject, (Ptr{JNIEnv}, jclass, jmethodID, jboolean,), env, cls, methodID, isStatic) + +GetSuperclass(env::Ptr{JNIEnv}, sub::jclass) = + ccall(jniref[].GetSuperclass, jclass, (Ptr{JNIEnv}, jclass,), env, sub) + +IsAssignableFrom(env::Ptr{JNIEnv}, sub::jclass, sup::jclass) = + ccall(jniref[].IsAssignableFrom, jboolean, (Ptr{JNIEnv}, jclass, jclass,), env, sub, sup) + +ToReflectedField(env::Ptr{JNIEnv}, cls::jclass, fieldID::jfieldID, isStatic::jboolean) = + ccall(jniref[].ToReflectedField, jobject, (Ptr{JNIEnv}, jclass, jfieldID, jboolean,), env, cls, fieldID, isStatic) + +Throw(env::Ptr{JNIEnv}, obj::jthrowable) = + ccall(jniref[].Throw, jint, (Ptr{JNIEnv}, jthrowable,), env, obj) + +ThrowNew(env::Ptr{JNIEnv}, clazz::jclass, msg::AnyString) = + ccall(jniref[].ThrowNew, jint, (Ptr{JNIEnv}, jclass, Cstring,), env, clazz, msg) + +ExceptionOccurred(env::Ptr{JNIEnv}) = + ccall(jniref[].ExceptionOccurred, jthrowable, (Ptr{JNIEnv},), env) + +ExceptionDescribe(env::Ptr{JNIEnv}) = + ccall(jniref[].ExceptionDescribe, Nothing, (Ptr{JNIEnv},), env) + +ExceptionClear(env::Ptr{JNIEnv}) = + ccall(jniref[].ExceptionClear, Nothing, (Ptr{JNIEnv},), env) + +FatalError(env::Ptr{JNIEnv}, msg::AnyString) = + ccall(jniref[].FatalError, Nothing, (Ptr{JNIEnv}, Cstring,), env, msg) + +PushLocalFrame(env::Ptr{JNIEnv}, capacity::jint) = + ccall(jniref[].PushLocalFrame, jint, (Ptr{JNIEnv}, jint,), env, capacity) + +PopLocalFrame(env::Ptr{JNIEnv}, result::jobject) = + ccall(jniref[].PopLocalFrame, jobject, (Ptr{JNIEnv}, jobject,), env, result) + +NewGlobalRef(env::Ptr{JNIEnv}, lobj::jobject) = + ccall(jniref[].NewGlobalRef, jobject, (Ptr{JNIEnv}, jobject,), env, lobj) + +DeleteGlobalRef(env::Ptr{JNIEnv}, gref::jobject) = + ccall(jniref[].DeleteGlobalRef, Nothing, (Ptr{JNIEnv}, jobject,), env, gref) + +DeleteLocalRef(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].DeleteLocalRef, Nothing, (Ptr{JNIEnv}, jobject,), env, obj) + +IsSameObject(env::Ptr{JNIEnv}, obj1::jobject, obj2::jobject) = + ccall(jniref[].IsSameObject, jboolean, (Ptr{JNIEnv}, jobject, jobject,), env, obj1, obj2) + +NewLocalRef(env::Ptr{JNIEnv}, ref::jobject) = + ccall(jniref[].NewLocalRef, jobject, (Ptr{JNIEnv}, jobject,), env, ref) + +EnsureLocalCapacity(env::Ptr{JNIEnv}, capacity::jint) = + ccall(jniref[].EnsureLocalCapacity, jint, (Ptr{JNIEnv}, jint,), env, capacity) + +AllocObject(env::Ptr{JNIEnv}, clazz::jclass) = + ccall(jniref[].AllocObject, jobject, (Ptr{JNIEnv}, jclass,), env, clazz) + +NewObjectA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].NewObjectA, jobject, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +GetObjectClass(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].GetObjectClass, jclass, (Ptr{JNIEnv}, jobject,), env, obj) + +IsInstanceOf(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass) = + ccall(jniref[].IsInstanceOf, jboolean, (Ptr{JNIEnv}, jobject, jclass,), env, obj, clazz) + +GetMethodID(env::Ptr{JNIEnv}, clazz::jclass, name::AnyString, sig::AnyString) = + ccall(jniref[].GetMethodID, jmethodID, (Ptr{JNIEnv}, jclass, Cstring, Cstring,), env, clazz, name, sig) + +CallObjectMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallObjectMethodA, jobject, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallBooleanMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallBooleanMethodA, jboolean, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallByteMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallByteMethodA, jbyte, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallCharMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallCharMethodA, jchar, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallShortMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallShortMethodA, jshort, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallIntMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallIntMethodA, jint, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallLongMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallLongMethodA, jlong, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallFloatMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallFloatMethodA, jfloat, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallDoubleMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallDoubleMethodA, jdouble, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallVoidMethodA(env::Ptr{JNIEnv}, obj::jobject, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallVoidMethodA, Nothing, (Ptr{JNIEnv}, jobject, jmethodID, Ptr{jvalue},), env, obj, methodID, args) + +CallNonvirtualObjectMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualObjectMethodA, jobject, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualBooleanMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualBooleanMethodA, jboolean, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualByteMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualByteMethodA, jbyte, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualCharMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualCharMethodA, jchar, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualShortMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualShortMethodA, jshort, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualIntMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualIntMethodA, jint, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualLongMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualLongMethodA, jlong, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualFloatMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualFloatMethodA, jfloat, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualDoubleMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualDoubleMethodA, jdouble, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +CallNonvirtualVoidMethodA(env::Ptr{JNIEnv}, obj::jobject, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallNonvirtualVoidMethodA, Nothing, (Ptr{JNIEnv}, jobject, jclass, jmethodID, Ptr{jvalue},), env, obj, clazz, methodID, args) + +GetFieldID(env::Ptr{JNIEnv}, clazz::jclass, name::AnyString, sig::AnyString) = + ccall(jniref[].GetFieldID, jfieldID, (Ptr{JNIEnv}, jclass, Cstring, Cstring,), env, clazz, name, sig) + +GetObjectField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetObjectField, jobject, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetBooleanField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetBooleanField, jboolean, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetByteField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetByteField, jbyte, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetCharField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetCharField, jchar, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetShortField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetShortField, jshort, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetIntField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetIntField, jint, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetLongField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetLongField, jlong, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetFloatField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetFloatField, jfloat, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +GetDoubleField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID) = + ccall(jniref[].GetDoubleField, jdouble, (Ptr{JNIEnv}, jobject, jfieldID,), env, obj, fieldID) + +SetObjectField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jobject) = + ccall(jniref[].SetObjectField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jobject,), env, obj, fieldID, val) + +SetBooleanField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jboolean) = + ccall(jniref[].SetBooleanField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jboolean,), env, obj, fieldID, val) + +SetByteField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jbyte) = + ccall(jniref[].SetByteField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jbyte,), env, obj, fieldID, val) + +SetCharField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jchar) = + ccall(jniref[].SetCharField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jchar,), env, obj, fieldID, val) + +SetShortField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jshort) = + ccall(jniref[].SetShortField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jshort,), env, obj, fieldID, val) + +SetIntField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jint) = + ccall(jniref[].SetIntField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jint,), env, obj, fieldID, val) + +SetLongField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jlong) = + ccall(jniref[].SetLongField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jlong,), env, obj, fieldID, val) + +SetFloatField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jfloat) = + ccall(jniref[].SetFloatField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jfloat,), env, obj, fieldID, val) + +SetDoubleField(env::Ptr{JNIEnv}, obj::jobject, fieldID::jfieldID, val::jdouble) = + ccall(jniref[].SetDoubleField, Nothing, (Ptr{JNIEnv}, jobject, jfieldID, jdouble,), env, obj, fieldID, val) + +GetStaticMethodID(env::Ptr{JNIEnv}, clazz::jclass, name::AnyString, sig::AnyString) = + ccall(jniref[].GetStaticMethodID, jmethodID, (Ptr{JNIEnv}, jclass, Cstring, Cstring,), env, clazz, name, sig) + +CallStaticObjectMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticObjectMethodA, jobject, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticBooleanMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticBooleanMethodA, jboolean, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticByteMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticByteMethodA, jbyte, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticCharMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticCharMethodA, jchar, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticShortMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticShortMethodA, jshort, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticIntMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticIntMethodA, jint, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticLongMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticLongMethodA, jlong, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticFloatMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticFloatMethodA, jfloat, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticDoubleMethodA(env::Ptr{JNIEnv}, clazz::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticDoubleMethodA, jdouble, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, clazz, methodID, args) + +CallStaticVoidMethodA(env::Ptr{JNIEnv}, cls::jclass, methodID::jmethodID, args::Array{jvalue,1}) = + ccall(jniref[].CallStaticVoidMethodA, Nothing, (Ptr{JNIEnv}, jclass, jmethodID, Ptr{jvalue},), env, cls, methodID, args) + +GetStaticFieldID(env::Ptr{JNIEnv}, clazz::jclass, name::AnyString, sig::AnyString) = + ccall(jniref[].GetStaticFieldID, jfieldID, (Ptr{JNIEnv}, jclass, Cstring, Cstring,), env, clazz, name, sig) + +GetStaticObjectField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticObjectField, jobject, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticBooleanField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticBooleanField, jboolean, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticByteField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticByteField, jbyte, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticCharField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticCharField, jchar, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticShortField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticShortField, jshort, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticIntField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticIntField, jint, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticLongField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticLongField, jlong, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticFloatField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticFloatField, jfloat, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +GetStaticDoubleField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID) = + ccall(jniref[].GetStaticDoubleField, jdouble, (Ptr{JNIEnv}, jclass, jfieldID,), env, clazz, fieldID) + +SetStaticObjectField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jobject) = + ccall(jniref[].SetStaticObjectField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jobject,), env, clazz, fieldID, value) + +SetStaticBooleanField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jboolean) = + ccall(jniref[].SetStaticBooleanField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jboolean,), env, clazz, fieldID, value) + +SetStaticByteField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jbyte) = + ccall(jniref[].SetStaticByteField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jbyte,), env, clazz, fieldID, value) + +SetStaticCharField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jchar) = + ccall(jniref[].SetStaticCharField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jchar,), env, clazz, fieldID, value) + +SetStaticShortField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jshort) = + ccall(jniref[].SetStaticShortField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jshort,), env, clazz, fieldID, value) + +SetStaticIntField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jint) = + ccall(jniref[].SetStaticIntField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jint,), env, clazz, fieldID, value) + +SetStaticLongField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jlong) = + ccall(jniref[].SetStaticLongField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jlong,), env, clazz, fieldID, value) + +SetStaticFloatField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jfloat) = + ccall(jniref[].SetStaticFloatField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jfloat,), env, clazz, fieldID, value) + +SetStaticDoubleField(env::Ptr{JNIEnv}, clazz::jclass, fieldID::jfieldID, value::jdouble) = + ccall(jniref[].SetStaticDoubleField, Nothing, (Ptr{JNIEnv}, jclass, jfieldID, jdouble,), env, clazz, fieldID, value) + +NewString(env::Ptr{JNIEnv}, unicode::Array{jchar,1}, len::Integer) = + ccall(jniref[].NewString, jstring, (Ptr{JNIEnv}, Ptr{jchar}, jsize,), env, unicode, len) + +GetStringLength(env::Ptr{JNIEnv}, str::jstring) = + ccall(jniref[].GetStringLength, jsize, (Ptr{JNIEnv}, jstring,), env, str) + +GetStringChars(env::Ptr{JNIEnv}, str::jstring, isCopy::PtrIsCopy) = + ccall(jniref[].GetStringChars, Ptr{jchar}, (Ptr{JNIEnv}, jstring, Ptr{jboolean},), env, str, isCopy) + +ReleaseStringChars(env::Ptr{JNIEnv}, str::jstring, chars::Array{jchar,1}) = + ccall(jniref[].ReleaseStringChars, Nothing, (Ptr{JNIEnv}, jstring, Ptr{jchar},), env, str, chars) + +NewStringUTF(env::Ptr{JNIEnv}, utf::AnyString) = + ccall(jniref[].NewStringUTF, jstring, (Ptr{JNIEnv}, Cstring,), env, utf) + +GetStringUTFLength(env::Ptr{JNIEnv}, str::jstring) = + ccall(jniref[].GetStringUTFLength, jsize, (Ptr{JNIEnv}, jstring,), env, str) + +GetStringUTFChars(env::Ptr{JNIEnv}, str::jstring, isCopy::PtrIsCopy) = + ccall(jniref[].GetStringUTFChars, Cstring, (Ptr{JNIEnv}, jstring, Ptr{jboolean},), env, str, isCopy) + +## Prior to this module we used UInt8 instead of Cstring, must match return value of above +#ReleaseStringUTFChars(env::Ptr{JNIEnv}, str::jstring, chars::Ptr{UInt8}) = +# ccall(jniref[].ReleaseStringUTFChars, Nothing, (Ptr{JNIEnv}, jstring, Ptr{UInt8},), env, str, chars) +ReleaseStringUTFChars(env::Ptr{JNIEnv}, str::jstring, chars::AnyString) = + ccall(jniref[].ReleaseStringUTFChars, Nothing, (Ptr{JNIEnv}, jstring, Cstring,), env, str, chars) + +GetArrayLength(env::Ptr{JNIEnv}, array::jarray) = + ccall(jniref[].GetArrayLength, jsize, (Ptr{JNIEnv}, jarray,), env, array) + +NewObjectArray(env::Ptr{JNIEnv}, len::Integer, clazz::jclass, init::jobject) = + ccall(jniref[].NewObjectArray, jobjectArray, (Ptr{JNIEnv}, jsize, jclass, jobject,), env, len, clazz, init) + +GetObjectArrayElement(env::Ptr{JNIEnv}, array::jobjectArray, index::Integer) = + ccall(jniref[].GetObjectArrayElement, jobject, (Ptr{JNIEnv}, jobjectArray, jsize,), env, array, index) + +SetObjectArrayElement(env::Ptr{JNIEnv}, array::jobjectArray, index::Integer, val::jobject) = + ccall(jniref[].SetObjectArrayElement, Nothing, (Ptr{JNIEnv}, jobjectArray, jsize, jobject,), env, array, index, val) + +NewBooleanArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewBooleanArray, jbooleanArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewByteArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewByteArray, jbyteArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewCharArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewCharArray, jcharArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewShortArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewShortArray, jshortArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewIntArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewIntArray, jintArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewLongArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewLongArray, jlongArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewFloatArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewFloatArray, jfloatArray, (Ptr{JNIEnv}, jsize,), env, len) + +NewDoubleArray(env::Ptr{JNIEnv}, len::Integer) = + ccall(jniref[].NewDoubleArray, jdoubleArray, (Ptr{JNIEnv}, jsize,), env, len) + +GetBooleanArrayElements(env::Ptr{JNIEnv}, array::jbooleanArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetBooleanArrayElements, Ptr{jboolean}, (Ptr{JNIEnv}, jbooleanArray, Ptr{jboolean},), env, array, isCopy) + +GetByteArrayElements(env::Ptr{JNIEnv}, array::jbyteArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetByteArrayElements, Ptr{jbyte}, (Ptr{JNIEnv}, jbyteArray, Ptr{jboolean},), env, array, isCopy) + +GetCharArrayElements(env::Ptr{JNIEnv}, array::jcharArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetCharArrayElements, Ptr{jchar}, (Ptr{JNIEnv}, jcharArray, Ptr{jboolean},), env, array, isCopy) + +GetShortArrayElements(env::Ptr{JNIEnv}, array::jshortArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetShortArrayElements, Ptr{jshort}, (Ptr{JNIEnv}, jshortArray, Ptr{jboolean},), env, array, isCopy) + +GetIntArrayElements(env::Ptr{JNIEnv}, array::jintArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetIntArrayElements, Ptr{jint}, (Ptr{JNIEnv}, jintArray, Ptr{jboolean},), env, array, isCopy) + +GetLongArrayElements(env::Ptr{JNIEnv}, array::jlongArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetLongArrayElements, Ptr{jlong}, (Ptr{JNIEnv}, jlongArray, Ptr{jboolean},), env, array, isCopy) + +GetFloatArrayElements(env::Ptr{JNIEnv}, array::jfloatArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetFloatArrayElements, Ptr{jfloat}, (Ptr{JNIEnv}, jfloatArray, Ptr{jboolean},), env, array, isCopy) + +GetDoubleArrayElements(env::Ptr{JNIEnv}, array::jdoubleArray, isCopy::PtrIsCopy) = + ccall(jniref[].GetDoubleArrayElements, Ptr{jdouble}, (Ptr{JNIEnv}, jdoubleArray, Ptr{jboolean},), env, array, isCopy) + +ReleaseBooleanArrayElements(env::Ptr{JNIEnv}, array::jbooleanArray, elems::Ptr{jboolean}, mode::jint) = + ccall(jniref[].ReleaseBooleanArrayElements, Nothing, (Ptr{JNIEnv}, jbooleanArray, Ptr{jboolean}, jint,), env, array, elems, mode) + +ReleaseByteArrayElements(env::Ptr{JNIEnv}, array::jbyteArray, elems::Ptr{jbyte}, mode::jint) = + ccall(jniref[].ReleaseByteArrayElements, Nothing, (Ptr{JNIEnv}, jbyteArray, Ptr{jbyte}, jint,), env, array, elems, mode) + +ReleaseCharArrayElements(env::Ptr{JNIEnv}, array::jcharArray, elems::Ptr{jchar}, mode::jint) = + ccall(jniref[].ReleaseCharArrayElements, Nothing, (Ptr{JNIEnv}, jcharArray, Ptr{jchar}, jint,), env, array, elems, mode) + +ReleaseShortArrayElements(env::Ptr{JNIEnv}, array::jshortArray, elems::Ptr{jshort}, mode::jint) = + ccall(jniref[].ReleaseShortArrayElements, Nothing, (Ptr{JNIEnv}, jshortArray, Ptr{jshort}, jint,), env, array, elems, mode) + +ReleaseIntArrayElements(env::Ptr{JNIEnv}, array::jintArray, elems::Ptr{jint}, mode::jint) = + ccall(jniref[].ReleaseIntArrayElements, Nothing, (Ptr{JNIEnv}, jintArray, Ptr{jint}, jint,), env, array, elems, mode) + +ReleaseLongArrayElements(env::Ptr{JNIEnv}, array::jlongArray, elems::Ptr{jlong}, mode::jint) = + ccall(jniref[].ReleaseLongArrayElements, Nothing, (Ptr{JNIEnv}, jlongArray, Ptr{jlong}, jint,), env, array, elems, mode) + +ReleaseFloatArrayElements(env::Ptr{JNIEnv}, array::jfloatArray, elems::Ptr{jfloat}, mode::jint) = + ccall(jniref[].ReleaseFloatArrayElements, Nothing, (Ptr{JNIEnv}, jfloatArray, Ptr{jfloat}, jint,), env, array, elems, mode) + +ReleaseDoubleArrayElements(env::Ptr{JNIEnv}, array::jdoubleArray, elems::Ptr{jdouble}, mode::jint) = + ccall(jniref[].ReleaseDoubleArrayElements, Nothing, (Ptr{JNIEnv}, jdoubleArray, Ptr{jdouble}, jint,), env, array, elems, mode) + +GetBooleanArrayRegion(env::Ptr{JNIEnv}, array::jbooleanArray, start::Integer, l::Integer, buf::Array{jboolean,1}) = + ccall(jniref[].GetBooleanArrayRegion, Nothing, (Ptr{JNIEnv}, jbooleanArray, jsize, jsize, Ptr{jboolean},), env, array, start, l, buf) + +GetByteArrayRegion(env::Ptr{JNIEnv}, array::jbyteArray, start::Integer, len::Integer, buf::Array{jbyte,1}) = + ccall(jniref[].GetByteArrayRegion, Nothing, (Ptr{JNIEnv}, jbyteArray, jsize, jsize, Ptr{jbyte},), env, array, start, len, buf) + +GetCharArrayRegion(env::Ptr{JNIEnv}, array::jcharArray, start::Integer, len::Integer, buf::Array{jchar,1}) = + ccall(jniref[].GetCharArrayRegion, Nothing, (Ptr{JNIEnv}, jcharArray, jsize, jsize, Ptr{jchar},), env, array, start, len, buf) + +GetShortArrayRegion(env::Ptr{JNIEnv}, array::jshortArray, start::Integer, len::Integer, buf::Array{jshort,1}) = + ccall(jniref[].GetShortArrayRegion, Nothing, (Ptr{JNIEnv}, jshortArray, jsize, jsize, Ptr{jshort},), env, array, start, len, buf) + +GetIntArrayRegion(env::Ptr{JNIEnv}, array::jintArray, start::Integer, len::Integer, buf::Array{jint,1}) = + ccall(jniref[].GetIntArrayRegion, Nothing, (Ptr{JNIEnv}, jintArray, jsize, jsize, Ptr{jint},), env, array, start, len, buf) + +GetLongArrayRegion(env::Ptr{JNIEnv}, array::jlongArray, start::Integer, len::Integer, buf::Array{jlong,1}) = + ccall(jniref[].GetLongArrayRegion, Nothing, (Ptr{JNIEnv}, jlongArray, jsize, jsize, Ptr{jlong},), env, array, start, len, buf) + +GetFloatArrayRegion(env::Ptr{JNIEnv}, array::jfloatArray, start::Integer, len::Integer, buf::Array{jfloat,1}) = + ccall(jniref[].GetFloatArrayRegion, Nothing, (Ptr{JNIEnv}, jfloatArray, jsize, jsize, Ptr{jfloat},), env, array, start, len, buf) + +GetDoubleArrayRegion(env::Ptr{JNIEnv}, array::jdoubleArray, start::Integer, len::Integer, buf::Array{jdouble,1}) = + ccall(jniref[].GetDoubleArrayRegion, Nothing, (Ptr{JNIEnv}, jdoubleArray, jsize, jsize, Ptr{jdouble},), env, array, start, len, buf) + +SetBooleanArrayRegion(env::Ptr{JNIEnv}, array::jbooleanArray, start::Integer, l::Integer, buf::Array{jboolean,1}) = + ccall(jniref[].SetBooleanArrayRegion, Nothing, (Ptr{JNIEnv}, jbooleanArray, jsize, jsize, Ptr{jboolean},), env, array, start, l, buf) + +SetByteArrayRegion(env::Ptr{JNIEnv}, array::jbyteArray, start::Integer, len::Integer, buf::Array{jbyte,1}) = + ccall(jniref[].SetByteArrayRegion, Nothing, (Ptr{JNIEnv}, jbyteArray, jsize, jsize, Ptr{jbyte},), env, array, start, len, buf) + +SetCharArrayRegion(env::Ptr{JNIEnv}, array::jcharArray, start::Integer, len::Integer, buf::Array{jchar,1}) = + ccall(jniref[].SetCharArrayRegion, Nothing, (Ptr{JNIEnv}, jcharArray, jsize, jsize, Ptr{jchar},), env, array, start, len, buf) + +SetShortArrayRegion(env::Ptr{JNIEnv}, array::jshortArray, start::Integer, len::Integer, buf::Array{jshort,1}) = + ccall(jniref[].SetShortArrayRegion, Nothing, (Ptr{JNIEnv}, jshortArray, jsize, jsize, Ptr{jshort},), env, array, start, len, buf) + +SetIntArrayRegion(env::Ptr{JNIEnv}, array::jintArray, start::Integer, len::Integer, buf::Array{jint,1}) = + ccall(jniref[].SetIntArrayRegion, Nothing, (Ptr{JNIEnv}, jintArray, jsize, jsize, Ptr{jint},), env, array, start, len, buf) + +SetLongArrayRegion(env::Ptr{JNIEnv}, array::jlongArray, start::Integer, len::Integer, buf::Array{jlong,1}) = + ccall(jniref[].SetLongArrayRegion, Nothing, (Ptr{JNIEnv}, jlongArray, jsize, jsize, Ptr{jlong},), env, array, start, len, buf) + +SetFloatArrayRegion(env::Ptr{JNIEnv}, array::jfloatArray, start::Integer, len::Integer, buf::Array{jfloat,1}) = + ccall(jniref[].SetFloatArrayRegion, Nothing, (Ptr{JNIEnv}, jfloatArray, jsize, jsize, Ptr{jfloat},), env, array, start, len, buf) + +SetDoubleArrayRegion(env::Ptr{JNIEnv}, array::jdoubleArray, start::Integer, len::Integer, buf::Array{jdouble,1}) = + ccall(jniref[].SetDoubleArrayRegion, Nothing, (Ptr{JNIEnv}, jdoubleArray, jsize, jsize, Ptr{jdouble},), env, array, start, len, buf) + +RegisterNatives(env::Ptr{JNIEnv}, clazz::jclass, methods::Array{JNINativeMethod,1}, nMethods::jint) = + ccall(jniref[].RegisterNatives, jint, (Ptr{JNIEnv}, jclass, Ptr{JNINativeMethod}, jint,), env, clazz, methods, nMethods) + +UnregisterNatives(env::Ptr{JNIEnv}, clazz::jclass) = + ccall(jniref[].UnregisterNatives, jint, (Ptr{JNIEnv}, jclass,), env, clazz) + +MonitorEnter(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].MonitorEnter, jint, (Ptr{JNIEnv}, jobject,), env, obj) + +MonitorExit(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].MonitorExit, jint, (Ptr{JNIEnv}, jobject,), env, obj) + +GetJavaVM(env::Ptr{JNIEnv}, vm::Array{JavaVM,1}) = + ccall(jniref[].GetJavaVM, jint, (Ptr{JNIEnv}, Array{JavaVM,1},), env, vm) + +GetStringRegion(env::Ptr{JNIEnv}, str::jstring, start::Integer, len::Integer, buf::Array{jchar,1}) = + ccall(jniref[].GetStringRegion, Nothing, (Ptr{JNIEnv}, jstring, jsize, jsize, Ptr{jchar},), env, str, start, len, buf) + +GetStringUTFRegion(env::Ptr{JNIEnv}, str::jstring, start::Integer, len::Integer, buf::AnyString) = + ccall(jniref[].GetStringUTFRegion, Nothing, (Ptr{JNIEnv}, jstring, jsize, jsize, Cstring,), env, str, start, len, buf) + +GetPrimitiveArrayCritical(env::Ptr{JNIEnv}, array::jarray, isCopy::PtrIsCopy) = + ccall(jniref[].GetPrimitiveArrayCritical, Ptr{Nothing}, (Ptr{JNIEnv}, jarray, Ptr{jboolean},), env, array, isCopy) + +ReleasePrimitiveArrayCritical(env::Ptr{JNIEnv}, array::jarray, carray::Ptr{Nothing}, mode::jint) = + ccall(jniref[].ReleasePrimitiveArrayCritical, Nothing, (Ptr{JNIEnv}, jarray, Ptr{Nothing}, jint,), env, array, carray, mode) + +GetStringCritical(env::Ptr{JNIEnv}, string::jstring, isCopy::PtrIsCopy) = + ccall(jniref[].GetStringCritical, Ptr{jchar}, (Ptr{JNIEnv}, jstring, Ptr{jboolean},), env, string, isCopy) + +ReleaseStringCritical(env::Ptr{JNIEnv}, string::jstring, cstring::Array{jchar,1}) = + ccall(jniref[].ReleaseStringCritical, Nothing, (Ptr{JNIEnv}, jstring, Ptr{jchar},), env, string, cstring) + +NewWeakGlobalRef(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].NewWeakGlobalRef, jweak, (Ptr{JNIEnv}, jobject,), env, obj) + +DeleteWeakGlobalRef(env::Ptr{JNIEnv}, ref::jweak) = + ccall(jniref[].DeleteWeakGlobalRef, Nothing, (Ptr{JNIEnv}, jweak,), env, ref) + +ExceptionCheck(env::Ptr{JNIEnv}) = + ccall(jniref[].ExceptionCheck, jboolean, (Ptr{JNIEnv},), env) + +NewDirectByteBuffer(env::Ptr{JNIEnv}, address::Ptr{Nothing}, capacity::jlong) = + ccall(jniref[].NewDirectByteBuffer, jobject, (Ptr{JNIEnv}, Ptr{Nothing}, jlong,), env, address, capacity) + +GetDirectBufferAddress(env::Ptr{JNIEnv}, buf::jobject) = + ccall(jniref[].GetDirectBufferAddress, Ptr{Nothing}, (Ptr{JNIEnv}, jobject,), env, buf) + +GetDirectBufferCapacity(env::Ptr{JNIEnv}, buf::jobject) = + ccall(jniref[].GetDirectBufferCapacity, jlong, (Ptr{JNIEnv}, jobject,), env, buf) + +GetObjectRefType(env::Ptr{JNIEnv}, obj::jobject) = + ccall(jniref[].GetObjectRefType, jobjectRefType, (Ptr{JNIEnv}, jobject,), env, obj) + + +# === Above Generated by make_jni2.jl === + +end diff --git a/src/JavaCall.jl b/src/JavaCall.jl index 093b796..7c66bb9 100644 --- a/src/JavaCall.jl +++ b/src/JavaCall.jl @@ -23,7 +23,8 @@ import Base: convert, unsafe_convert, unsafe_string JULIA_COPY_STACKS = false -include("jnienv.jl") +include("JNI.jl") +using .JNI include("jvm.jl") include("core.jl") include("convert.jl") diff --git a/src/convert.jl b/src/convert.jl index 0a65d23..9001713 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -4,14 +4,14 @@ convert(::Type{JObject}, str::AbstractString) = convert(JObject, JString(str)) #Cast java object from S to T . Needed for polymorphic calls function convert(::Type{JavaObject{T}}, obj::JavaObject{S}) where {T,S} if isConvertible(T, S) #Safe static cast - ptr = ccall(jnifunc.NewLocalRef, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) + ptr = JNI.NewLocalRef(penv, obj.ptr) ptr === C_NULL && geterror() return JavaObject{T}(ptr) end isnull(obj) && throw(ArgumentError("Cannot convert NULL")) - realClass = ccall(jnifunc.GetObjectClass, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing} ), penv, obj.ptr) + realClass = JNI.GetObjectClass(penv, obj.ptr) if isConvertible(T, realClass) #dynamic cast - ptr = ccall(jnifunc.NewLocalRef, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) + ptr = JNI.NewLocalRef(penv, obj.ptr) ptr === C_NULL && geterror() return JavaObject{T}(ptr) end @@ -19,12 +19,8 @@ function convert(::Type{JavaObject{T}}, obj::JavaObject{S}) where {T,S} end #Is java type convertible from S to T. -isConvertible(T, S) = (ccall(jnifunc.IsAssignableFrom, jboolean, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}), penv, metaclass(S), - metaclass(T)) == JNI_TRUE) -isConvertible(T, S::Ptr{Nothing}) = (ccall(jnifunc.IsAssignableFrom, jboolean, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}), penv, S, - metaclass(T)) == JNI_TRUE) +isConvertible(T, S) = JNI.IsAssignableFrom(penv, metaclass(S).ptr, metaclass(T).ptr) == JNI_TRUE +isConvertible(T, S::Ptr{Nothing} ) = JNI.IsAssignableFrom(penv, S, metaclass(T).ptr) == JNI_TRUE unsafe_convert(::Type{Ptr{Nothing}}, cls::JavaMetaClass) = cls.ptr @@ -63,21 +59,20 @@ function convert_arg(argtype::Type{T}, arg) where T<:JavaObject return x, x.ptr end -for (x, y, z) in [ (:jboolean, :(jnifunc.NewBooleanArray), :(jnifunc.SetBooleanArrayRegion)), - (:jchar, :(jnifunc.NewCharArray), :(jnifunc.SetCharArrayRegion)), - (:jbyte, :(jnifunc.NewByteArray), :(jnifunc.SetByteArrayRegion)), - (:jshort, :(jnifunc.NewShortArray), :(jnifunc.SetShortArrayRegion)), - (:jint, :(jnifunc.NewIntArray), :(jnifunc.SetIntArrayRegion)), - (:jlong, :(jnifunc.NewLongArray), :(jnifunc.SetLongArrayRegion)), - (:jfloat, :(jnifunc.NewFloatArray), :(jnifunc.SetFloatArrayRegion)), - (:jdouble, :(jnifunc.NewDoubleArray), :(jnifunc.SetDoubleArrayRegion)) ] +for (x, y, z) in [(:jboolean, :(JNI.NewBooleanArray), :(JNI.SetBooleanArrayRegion)), + (:jchar, :(JNI.NewCharArray), :(JNI.SetCharArrayRegion)) , + (:jbyte, :(JNI.NewByteArray), :(JNI.SetByteArrayRegion)) , + (:jshort, :(JNI.NewShortArray), :(JNI.SetShortArrayRegion)) , + (:jint, :(JNI.NewIntArray), :(JNI.SetIntArrayRegion)) , + (:jlong, :(JNI.NewLongArray), :(JNI.SetLongArrayRegion)) , + (:jfloat, :(JNI.NewFloatArray), :(JNI.SetFloatArrayRegion)) , + (:jdouble, :(JNI.NewDoubleArray), :(JNI.SetDoubleArrayRegion)) ] m = quote function convert_arg(argtype::Type{Array{$x,1}}, arg) carg = convert(argtype, arg) sz=length(carg) - arrayptr = ccall($y, Ptr{Nothing}, (Ptr{JNIEnv}, jint), penv, sz) - ccall($z, Nothing, (Ptr{JNIEnv}, Ptr{Nothing}, jint, jint, Ptr{$x}), penv, arrayptr, 0, sz, - carg) + arrayptr = $y(penv, sz) + $z(penv, arrayptr, 0, sz, carg) return carg, arrayptr end end @@ -88,11 +83,9 @@ function convert_arg(argtype::Type{Array{T,1}}, arg) where T<:JavaObject carg = convert(argtype, arg) sz = length(carg) init = carg[1] - arrayptr = ccall(jnifunc.NewObjectArray, Ptr{Nothing}, - (Ptr{JNIEnv}, jint, Ptr{Nothing}, Ptr{Nothing}), penv, sz, metaclass(T), init.ptr) + arrayptr = JNI.NewObjectArray(penv, sz, metaclass(T).ptr, init.ptr) for i=2:sz - ccall(jnifunc.SetObjectArrayElement, Nothing, (Ptr{JNIEnv}, Ptr{Nothing}, jint, Ptr{Nothing}), - penv, arrayptr, i-1, carg[i].ptr) + JNI.SetObjectArrayElement(penv, arrayptr, i-1, carg[i].ptr) end return carg, arrayptr end @@ -101,37 +94,34 @@ convert_result(rettype::Type{T}, result) where {T<:JString} = unsafe_string(JStr convert_result(rettype::Type{T}, result) where {T<:JavaObject} = T(result) convert_result(rettype, result) = result -for (x, y, z) in [(:jboolean, :(jnifunc.GetBooleanArrayElements), :(jnifunc.ReleaseBooleanArrayElements)), - (:jchar, :(jnifunc.GetCharArrayElements), :(jnifunc.ReleaseCharArrayElements)), - (:jbyte, :(jnifunc.GetByteArrayElements), :(jnifunc.ReleaseByteArrayElements)), - (:jshort, :(jnifunc.GetShortArrayElements), :(jnifunc.ReleaseShortArrayElements)), - (:jint, :(jnifunc.GetIntArrayElements), :(jnifunc.ReleaseIntArrayElements)), - (:jlong, :(jnifunc.GetLongArrayElements), :(jnifunc.ReleaseLongArrayElements)), - (:jfloat, :(jnifunc.GetFloatArrayElements), :(jnifunc.ReleaseFloatArrayElements)), - (:jdouble, :(jnifunc.GetDoubleArrayElements), :(jnifunc.ReleaseDoubleArrayElements)) ] +for (x, y, z) in [(:jboolean, :(JNI.GetBooleanArrayElements), :(JNI.ReleaseBooleanArrayElements)), + (:jchar, :(JNI.GetCharArrayElements), :(JNI.ReleaseCharArrayElements)) , + (:jbyte, :(JNI.GetByteArrayElements), :(JNI.ReleaseByteArrayElements)) , + (:jshort, :(JNI.GetShortArrayElements), :(JNI.ReleaseShortArrayElements)) , + (:jint, :(JNI.GetIntArrayElements), :(JNI.ReleaseIntArrayElements)) , + (:jlong, :(JNI.GetLongArrayElements), :(JNI.ReleaseLongArrayElements)) , + (:jfloat, :(JNI.GetFloatArrayElements), :(JNI.ReleaseFloatArrayElements)) , + (:jdouble, :(JNI.GetDoubleArrayElements), :(JNI.ReleaseDoubleArrayElements)) ] m = quote function convert_result(rettype::Type{Array{$(x),1}}, result) - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, result) - arr = ccall($(y), Ptr{$(x)}, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{jboolean} ), penv, result, - C_NULL) + sz = JNI.GetArrayLength(penv, result) + arr = $y(penv, result, Ptr{jboolean}(C_NULL)) jl_arr::Array = unsafe_wrap(Array, arr, Int(sz)) jl_arr = deepcopy(jl_arr) - ccall($(z), Nothing, (Ptr{JNIEnv},Ptr{Nothing}, Ptr{$(x)}, jint), penv, result, arr, 0) + $z(penv, result, arr, Int32(0)) return jl_arr end end eval(m) end - function convert_result(rettype::Type{Array{JavaObject{T},1}}, result) where T - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, result) + sz = JNI.GetArrayLength(penv, result) ret = Array{JavaObject{T}}(undef, sz) for i=1:sz - a = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, - result, i-1) + a=JNI.GetObjectArrayElement(penv, result, i-1) ret[i] = JavaObject{T}(a) end return ret @@ -140,12 +130,12 @@ end # covers return types like Vector{Vector{T}} function convert_result(rettype::Type{Array{T,1}}, result) where T - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, result) + sz = JNI.GetArrayLength(penv, result) ret = Array{T}(undef, sz) for i=1:sz - a=ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, result, i-1) + a=JNI.GetObjectArrayElement(penv, result, i-1) ret[i] = convert_result(T, a) end return ret @@ -153,23 +143,20 @@ end function convert_result(rettype::Type{Array{JavaObject{T},2}}, result) where T - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, result) + sz = JNI.GetArrayLength(penv, result) if sz == 0 return Array{T}(undef, 0,0) end - a_1 = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, - result, 0) - sz_1 = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, a_1) + a_1 = JNI.GetObjectArrayElement(penv, result, 0) + sz_1 = JNI.GetArrayLength(penv, a_1) ret = Array{JavaObject{T}}(undef, sz, sz_1) for i=1:sz - a = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, - result, i-1) + a = JNI.GetObjectArrayElement(penv, result, i-1) # check that size of the current subarray is the same as for the first one - sz_a = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, a) + sz_a = JNI.GetArrayLength(penv, a) @assert(sz_a == sz_1, "Size of $(i)th subrarray is $sz_a, but size of the 1st subarray was $sz_1") for j=1:sz_1 - x = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), - penv, a, j-1) + x = JNI.GetObjectArrayElement(penv, a, j-1) ret[i, j] = JavaObject{T}(x) end end @@ -179,19 +166,17 @@ end # matrices of primitive types and other arrays function convert_result(rettype::Type{Array{T,2}}, result) where T - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, result) + sz = JNI.GetArrayLength(penv, result) if sz == 0 return Array{T}(undef, 0,0) end - a_1 = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, - result, 0) - sz_1 = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, a_1) + a_1 = JNI.GetObjectArrayElement(penv, result, 0) + sz_1 = JNI.GetArrayLength(penv, a_1) ret = Array{T}(undef, sz, sz_1) for i=1:sz - a = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{Nothing}, jint), penv, - result, i-1) + a = JNI.GetObjectArrayElement(penv, result, i-1) # check that size of the current subarray is the same as for the first one - sz_a = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, a) + sz_a = JNI.GetArrayLength(penv, a) @assert(sz_a == sz_1, "Size of $(i)th subrarray is $sz_a, but size of the 1st subarray was $sz_1") ret[i, :] = convert_result(Vector{T}, a) end @@ -267,30 +252,28 @@ end function unsafe_string(jstr::JString) #jstr must be a jstring obtained via a JNI call if isnull(jstr); return ""; end #Return empty string to keep type stability. But this is questionable pIsCopy = Array{jboolean}(undef, 1) - buf::Ptr{UInt8} = ccall(jnifunc.GetStringUTFChars, Ptr{UInt8}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{jboolean}), penv, jstr.ptr, pIsCopy) + #buf::Ptr{UInt8} = JNI.GetStringUTFChars(penv, jstr.ptr, pIsCopy) + buf = JNI.GetStringUTFChars(penv, jstr.ptr, pIsCopy) s = unsafe_string(buf) - ccall(jnifunc.ReleaseStringUTFChars, Nothing, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}), penv, - jstr.ptr, buf) + JNI.ReleaseStringUTFChars(penv, jstr.ptr, buf) return s end -for (x, y, z) in [(:jboolean, :(jnifunc.GetBooleanArrayElements), :(jnifunc.ReleaseBooleanArrayElements)), - (:jchar, :(jnifunc.GetCharArrayElements), :(jnifunc.ReleaseCharArrayElements)), - (:jbyte, :(jnifunc.GetByteArrayElements), :(jnifunc.ReleaseByteArrayElements)), - (:jshort, :(jnifunc.GetShortArrayElements), :(jnifunc.ReleaseShortArrayElements)), - (:jint, :(jnifunc.GetIntArrayElements), :(jnifunc.ReleaseIntArrayElements)), - (:jlong, :(jnifunc.GetLongArrayElements), :(jnifunc.ReleaseLongArrayElements)), - (:jfloat, :(jnifunc.GetFloatArrayElements), :(jnifunc.ReleaseFloatArrayElements)), - (:jdouble, :(jnifunc.GetDoubleArrayElements), :(jnifunc.ReleaseDoubleArrayElements)) ] +for (x, y, z) in [(:jboolean, :(JNI.GetBooleanArrayElements), :(JNI.ReleaseBooleanArrayElements)), + (:jchar, :(JNI.GetCharArrayElements), :(JNI.ReleaseCharArrayElements)) , + (:jbyte, :(JNI.GetByteArrayElements), :(JNI.ReleaseByteArrayElements)) , + (:jshort, :(JNI.GetShortArrayElements), :(JNI.ReleaseShortArrayElements)) , + (:jint, :(JNI.GetIntArrayElements), :(JNI.ReleaseIntArrayElements)) , + (:jlong, :(JNI.GetLongArrayElements), :(JNI.ReleaseLongArrayElements)) , + (:jfloat, :(JNI.GetFloatArrayElements), :(JNI.ReleaseFloatArrayElements)) , + (:jdouble, :(JNI.GetDoubleArrayElements), :(JNI.ReleaseDoubleArrayElements)) ] m = quote function convert(::Type{Array{$(x),1}}, obj::JObject) - sz = ccall(jnifunc.GetArrayLength, jint, (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) - arr = ccall($(y), Ptr{$(x)}, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{jboolean}), penv, obj.ptr, - C_NULL) + sz = JNI.GetArrayLength(penv, obj.ptr) + arr = $y(penv, obj.ptr, Ptr{jboolean}(C_NULL)) jl_arr::Array = unsafe_wrap(Array, arr, Int(sz)) jl_arr = deepcopy(jl_arr) - ccall($(z), Nothing, (Ptr{JNIEnv},Ptr{Nothing}, Ptr{$(x)}, jint), penv, obj.ptr, arr, 0) + $z(penv, obj.ptr, arr, Int32(0)) return jl_arr end end @@ -299,12 +282,10 @@ end function convert(::Type{Array{T, 1}}, obj::JObject) where T - sz = ccall(jnifunc.GetArrayLength, jint, - (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) + sz = JNI.GetArrayLength(penv, obj.ptr) ret = Array{T}(undef, sz) for i=1:sz - ptr = ccall(jnifunc.GetObjectArrayElement, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, jint), penv, obj.ptr, i-1) + ptr = JNI.GetObjectArrayElement(penv, obj.ptr, i-1) ret[i] = convert(T, JObject(ptr)) end return ret diff --git a/src/core.jl b/src/core.jl index 783f765..f5548c8 100644 --- a/src/core.jl +++ b/src/core.jl @@ -1,21 +1,3 @@ - -# jni_md.h -const jint = Cint -#ifdef _LP64 /* 64-bit Solaris */ -# typedef long jlong; -const jlong = Clonglong -const jbyte = Cchar - -# jni.h - -const jboolean = Cuchar -const jchar = Cushort -const jshort = Cshort -const jfloat = Cfloat -const jdouble = Cdouble -const jsize = jint -jprimitive = Union{jboolean, jchar, jshort, jfloat, jdouble, jint, jlong} - struct JavaMetaClass{T} ptr::Ptr{Nothing} end @@ -44,8 +26,7 @@ JavaObject{T}() where {T} = JavaObject{T}((),) function deleteref(x::JavaObject) if x.ptr == C_NULL; return; end if (penv==C_NULL); return; end - #ccall(:jl_,Nothing,(Any,),x) - ccall(jnifunc.DeleteLocalRef, Nothing, (Ptr{JNIEnv}, Ptr{Nothing}), penv, x.ptr) + JNI.DeleteLocalRef(penv, x.ptr) x.ptr=C_NULL #Safety in case this function is called direcly, rather than at finalize return end @@ -64,6 +45,7 @@ Checks if the passed JavaObject is null or not true if the passed object is null else false """ isnull(obj::JavaObject) = obj.ptr == C_NULL +isnull(obj::Ptr{Nothing}) = obj == C_NULL """ ``` @@ -87,7 +69,7 @@ const JClassLoader = JavaObject{Symbol("java.lang.ClassLoader")} const JString = JavaObject{Symbol("java.lang.String")} function JString(str::AbstractString) - jstring = ccall(jnifunc.NewStringUTF, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{UInt8}), penv, String(str)) + jstring = JNI.NewStringUTF(penv, String(str)) if jstring == C_NULL geterror() else @@ -125,13 +107,11 @@ end function jnew(T::Symbol, argtypes::Tuple, args...) assertroottask_or_goodenv() sig = method_signature(Nothing, argtypes...) - jmethodId = ccall(jnifunc.GetMethodID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T), - String(""), sig) + jmethodId = JNI.GetMethodID(penv, metaclass(T).ptr, String(""), sig) if jmethodId == C_NULL throw(JavaCallError("No constructor for $T with signature $sig")) end - return _jcall(metaclass(T), jmethodId, jnifunc.NewObjectA, JavaObject{T}, argtypes, args...) + return _jcall(metaclass(T), jmethodId, JNI.NewObjectA, JavaObject{T}, argtypes, args...) end # Call static methods @@ -139,9 +119,7 @@ function jcall(typ::Type{JavaObject{T}}, method::AbstractString, rettype::Type, args... ) where T assertroottask_or_goodenv() sig = method_signature(rettype, argtypes...) - jmethodId = ccall(jnifunc.GetStaticMethodID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T), - String(method), sig) + jmethodId = JNI.GetStaticMethodID(penv, metaclass(T).ptr, String(method), sig) jmethodId==C_NULL && geterror(true) _jcall(metaclass(T), jmethodId, C_NULL, rettype, argtypes, args...) end @@ -150,45 +128,38 @@ end function jcall(obj::JavaObject, method::AbstractString, rettype::Type, argtypes::Tuple, args... ) assertroottask_or_goodenv() sig = method_signature(rettype, argtypes...) - jmethodId = ccall(jnifunc.GetMethodID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(obj), - String(method), sig) + jmethodId = JNI.GetMethodID(penv, metaclass(obj).ptr, String(method), sig) jmethodId==C_NULL && geterror(true) _jcall(obj, jmethodId, C_NULL, rettype, argtypes, args...) end function jfield(typ::Type{JavaObject{T}}, field::AbstractString, fieldType::Type) where T assertroottask_or_goodenv() - jfieldID = ccall(jnifunc.GetStaticFieldID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(T), - String(field), signature(fieldType)) + jfieldID = JNI.GetStaticFieldID(penv, metaclass(T).ptr, String(field), signature(fieldType)) jfieldID==C_NULL && geterror(true) _jfield(metaclass(T), jfieldID, fieldType) end function jfield(obj::JavaObject, field::AbstractString, fieldType::Type) assertroottask_or_goodenv() - jfieldID = ccall(jnifunc.GetFieldID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, metaclass(obj), - String(field), signature(fieldType)) + jfieldID = JNI.GetFieldID(penv, metaclass(obj).ptr, String(field), signature(fieldType)) jfieldID==C_NULL && geterror(true) _jfield(obj, jfieldID, fieldType) end -for (x, y, z) in [(:jboolean, :(jnifunc.GetBooleanField), :(jnifunc.GetStaticBooleanField)), - (:jchar, :(jnifunc.GetCharField), :(jnifunc.GetStaticCharField)), - (:jbyte, :(jnifunc.GetByteField), :(jnifunc.GetStaticBypeField)), - (:jshort, :(jnifunc.GetShortField), :(jnifunc.GetStaticShortField)), - (:jint, :(jnifunc.GetIntField), :(jnifunc.GetStaticIntField)), - (:jlong, :(jnifunc.GetLongField), :(jnifunc.GetStaticLongField)), - (:jfloat, :(jnifunc.GetFloatField), :(jnifunc.GetStaticFloatField)), - (:jdouble, :(jnifunc.GetDoubleField), :(jnifunc.GetStaticDoubleField)) ] +for (x, y, z) in [(:jboolean, :(JNI.GetBooleanField), :(JNI.GetStaticBooleanField)), + (:jchar, :(JNI.GetCharField), :(JNI.GetStaticCharField)) , + (:jbyte, :(JNI.GetByteField), :(JNI.GetStaticBypeField)) , + (:jshort, :(JNI.GetShortField), :(JNI.GetStaticShortField)) , + (:jint, :(JNI.GetIntField), :(JNI.GetStaticIntField)) , + (:jlong, :(JNI.GetLongField), :(JNI.GetStaticLongField)) , + (:jfloat, :(JNI.GetFloatField), :(JNI.GetStaticFloatField)) , + (:jdouble, :(JNI.GetDoubleField), :(JNI.GetStaticDoubleField)) ] m = quote function _jfield(obj, jfieldID::Ptr{Nothing}, fieldType::Type{$(x)}) callmethod = ifelse( typeof(obj)<:JavaObject, $y , $z ) - result = ccall(callmethod, $x, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}), penv, obj.ptr, - jfieldID) + result = callmethod(penv, obj.ptr, jfieldID) result==C_NULL && geterror() return convert_result(fieldType, result) end @@ -197,24 +168,23 @@ for (x, y, z) in [(:jboolean, :(jnifunc.GetBooleanField), :(jnifunc.GetStaticBoo end function _jfield(obj, jfieldID::Ptr{Nothing}, fieldType::Type) - callmethod = ifelse( typeof(obj)<:JavaObject, jnifunc.GetObjectField , jnifunc.GetStaticObjectField ) - result = ccall(callmethod, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}), penv, obj.ptr, - jfieldID) + callmethod = ifelse( typeof(obj)<:JavaObject, JNI.GetObjectField , JNI.GetStaticObjectField ) + result = callmethod(penv, obj.ptr, jfieldID) result==C_NULL && geterror() return convert_result(fieldType, result) end #Generate these methods to satisfy ccall's compile time constant requirement #_jcall for primitive and Nothing return types -for (x, y, z) in [ (:jboolean, :(jnifunc.CallBooleanMethodA), :(jnifunc.CallStaticBooleanMethodA)), - (:jchar, :(jnifunc.CallCharMethodA), :(jnifunc.CallStaticCharMethodA)), - (:jbyte, :(jnifunc.CallByteMethodA), :(jnifunc.CallStaticByteMethodA)), - (:jshort, :(jnifunc.CallShortMethodA), :(jnifunc.CallStaticShortMethodA)), - (:jint, :(jnifunc.CallIntMethodA), :(jnifunc.CallStaticIntMethodA)), - (:jlong, :(jnifunc.CallLongMethodA), :(jnifunc.CallStaticLongMethodA)), - (:jfloat, :(jnifunc.CallFloatMethodA), :(jnifunc.CallStaticFloatMethodA)), - (:jdouble, :(jnifunc.CallDoubleMethodA), :(jnifunc.CallStaticDoubleMethodA)), - (:Nothing, :(jnifunc.CallVoidMethodA), :(jnifunc.CallStaticVoidMethodA)) ] +for (x, y, z) in [(:jboolean, :(JNI.CallBooleanMethodA), :(JNI.CallStaticBooleanMethodA)), + (:jchar, :(JNI.CallCharMethodA), :(JNI.CallStaticCharMethodA)) , + (:jbyte, :(JNI.CallByteMethodA), :(JNI.CallStaticByteMethodA)) , + (:jshort, :(JNI.CallShortMethodA), :(JNI.CallStaticShortMethodA)) , + (:jint, :(JNI.CallIntMethodA), :(JNI.CallStaticIntMethodA)) , + (:jlong, :(JNI.CallLongMethodA), :(JNI.CallStaticLongMethodA)) , + (:jfloat, :(JNI.CallFloatMethodA), :(JNI.CallStaticFloatMethodA)) , + (:jdouble, :(JNI.CallDoubleMethodA), :(JNI.CallStaticDoubleMethodA)) , + (:Nothing, :(JNI.CallVoidMethodA), :(JNI.CallStaticVoidMethodA)) ] m = quote function _jcall(obj, jmethodId::Ptr{Nothing}, callmethod::Ptr{Nothing}, rettype::Type{$(x)}, argtypes::Tuple, args...) @@ -225,7 +195,7 @@ for (x, y, z) in [ (:jboolean, :(jnifunc.CallBooleanMethodA), :(jnifunc.CallStat @assert jmethodId != C_NULL isnull(obj) && throw(JavaCallError("Attempt to call method on Java NULL")) savedArgs, convertedArgs = convert_args(argtypes, args...) - result = ccall(callmethod, $x , (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}, Ptr{Nothing}), penv, obj.ptr, jmethodId, convertedArgs) + result = callmethod(penv, obj.ptr, jmethodId, convertedArgs) result==C_NULL && geterror() result == nothing && (return) return convert_result(rettype, result) @@ -238,18 +208,18 @@ end #obj -- receiver - Class pointer or object prointer #jmethodId -- Java method ID #callmethod -- the C method pointer to call -function _jcall(obj, jmethodId::Ptr{Nothing}, callmethod::Ptr{Nothing}, rettype::Type, argtypes::Tuple, +function _jcall(obj, jmethodId::Ptr{Nothing}, callmethod::Union{Function,Ptr{Nothing}}, rettype::Type, argtypes::Tuple, args...) if callmethod == C_NULL - callmethod = ifelse(typeof(obj)<:JavaObject, jnifunc.CallObjectMethodA , - jnifunc.CallStaticObjectMethodA) + callmethod = ifelse(typeof(obj)<:JavaObject, + JNI.CallObjectMethodA , + JNI.CallStaticObjectMethodA) end @assert callmethod != C_NULL @assert jmethodId != C_NULL isnull(obj) && error("Attempt to call method on Java NULL") savedArgs, convertedArgs = convert_args(argtypes, args...) - result = ccall(callmethod, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}, Ptr{Nothing}), - penv, obj.ptr, jmethodId, convertedArgs) + result = callmethod(penv, obj.ptr, jmethodId, convertedArgs) result==C_NULL && geterror() return convert_result(rettype, result) end @@ -259,7 +229,7 @@ global const _jmc_cache = Dict{Symbol, JavaMetaClass}() function _metaclass(class::Symbol) jclass=javaclassname(class) - jclassptr = ccall(jnifunc.FindClass, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{UInt8}), penv, jclass) + jclassptr = JNI.FindClass(penv, jclass) jclassptr == C_NULL && throw(JavaCallError("Class Not Found $jclass")) return JavaMetaClass(class, jclassptr) end @@ -277,26 +247,21 @@ metaclass(::JavaObject{T}) where {T} = metaclass(T) javaclassname(class::Symbol) = replace(string(class), "."=>"/") function geterror(allow=false) - isexception = ccall(jnifunc.ExceptionCheck, jboolean, (Ptr{JNIEnv},), penv ) + isexception = JNI.ExceptionCheck(penv) if isexception == JNI_TRUE - jthrow = ccall(jnifunc.ExceptionOccurred, Ptr{Nothing}, (Ptr{JNIEnv},), penv) + jthrow = JNI.ExceptionOccurred(penv) jthrow==C_NULL && throw(JavaCallError("Java Exception thrown, but no details could be retrieved from the JVM")) - ccall(jnifunc.ExceptionDescribe, Nothing, (Ptr{JNIEnv},), penv ) #Print java stackstrace to stdout - ccall(jnifunc.ExceptionClear, Nothing, (Ptr{JNIEnv},), penv ) - jclass = ccall(jnifunc.FindClass, Ptr{Nothing}, (Ptr{JNIEnv},Ptr{UInt8}), penv, - "java/lang/Throwable") + JNI.ExceptionDescribe(penv ) #Print java stackstrace to stdout + JNI.ExceptionClear(penv ) + jclass = JNI.FindClass(penv, "java/lang/Throwable") jclass==C_NULL && throw(JavaCallError("Java Exception thrown, but no details could be retrieved from the JVM")) - jmethodId=ccall(jnifunc.GetMethodID, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{UInt8}, Ptr{UInt8}), penv, jclass, "toString", - "()Ljava/lang/String;") + jmethodId=JNI.GetMethodID(penv, jclass, "toString", "()Ljava/lang/String;") jmethodId==C_NULL && throw(JavaCallError("Java Exception thrown, but no details could be retrieved from the JVM")) - res = ccall(jnifunc.CallObjectMethodA, Ptr{Nothing}, - (Ptr{JNIEnv}, Ptr{Nothing}, Ptr{Nothing}, Ptr{Nothing}), penv, jthrow, jmethodId, - C_NULL) + res = JNI.CallObjectMethodA(penv, jthrow, jmethodId, Int[]) res==C_NULL && throw(JavaCallError("Java Exception thrown, but no details could be retrieved from the JVM")) msg = unsafe_string(JString(res)) - ccall(jnifunc.DeleteLocalRef, Nothing, (Ptr{JNIEnv}, Ptr{Nothing}), penv, jthrow) + JNI.DeleteLocalRef(penv, jthrow) throw(JavaCallError(string("Error calling Java: ",msg))) else if allow==false diff --git a/src/jnienv.jl b/src/jnienv.jl index e7732f9..2b2ef66 100644 --- a/src/jnienv.jl +++ b/src/jnienv.jl @@ -76,7 +76,7 @@ struct JNINativeInterface #struct JNINativeInterface_ { CallLongMethodA::Ptr{Nothing} #jlong ( *CallLongMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); CallFloatMethod::Ptr{Nothing} #jfloat ( *CallFloatMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); - CallFloatMEthodV::Ptr{Nothing} #jfloat ( *CallFloatMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + CallFloatMethodV::Ptr{Nothing} #jfloat ( *CallFloatMethodV) (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); CallFloatMethodA::Ptr{Nothing} #jfloat ( *CallFloatMethodA) (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); CallDoubleMethod::Ptr{Nothing} #jdouble ( *CallDoubleMethod) (JNIEnv *env, jobject obj, jmethodID methodID, ...); @@ -89,7 +89,7 @@ struct JNINativeInterface #struct JNINativeInterface_ { CallNonvirtualObjectMethod::Ptr{Nothing} #jobject ( *CallNonvirtualObjectMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); CallNonvirtualObjectMethodV::Ptr{Nothing} #jobject ( *CallNonvirtualObjectMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); - CallNonvirtualObjectMEthodA::Ptr{Nothing} #jobject ( *CallNonvirtualObjectMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args); + CallNonvirtualObjectMethodA::Ptr{Nothing} #jobject ( *CallNonvirtualObjectMethodA) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, const jvalue * args); CallNonvirtualBooleanMethod::Ptr{Nothing} #jboolean ( *CallNonvirtualBooleanMethod) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); CallNonvirtualBooleanMethodV::Ptr{Nothing} #jboolean ( *CallNonvirtualBooleanMethodV) (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args); @@ -304,6 +304,7 @@ struct JNINativeInterface #struct JNINativeInterface_ { GetObjectRefType::Ptr{Nothing} # jobjectRefType ( *GetObjectRefType) (JNIEnv* env, jobject obj); end #}; +JNINativeInterface() = JNINativeInterface(repeat([C_NULL],233)...) struct JNIEnv JNINativeInterface_::Ptr{JNINativeInterface} @@ -328,7 +329,3 @@ end struct JavaVM JNIInvokeInterface_::Ptr{JNIInvokeInterface} end - -struct JavaCallError <: Exception - msg::String -end diff --git a/src/jvm.jl b/src/jvm.jl index ea250ed..2858c6f 100644 --- a/src/jvm.jl +++ b/src/jvm.jl @@ -1,24 +1,10 @@ -const JNI_VERSION_1_1 = convert(Cint, 0x00010001) -const JNI_VERSION_1_2 = convert(Cint, 0x00010002) -const JNI_VERSION_1_4 = convert(Cint, 0x00010004) -const JNI_VERSION_1_6 = convert(Cint, 0x00010006) -const JNI_VERSION_1_8 = convert(Cint, 0x00010008) - -const JNI_TRUE = convert(Cchar, 1) -const JNI_FALSE = convert(Cchar, 0) - -# Return Values -const JNI_OK = convert(Cint, 0) #/* success */ -const JNI_ERR = convert(Cint, -1) #/* unknown error */ -const JNI_EDETACHED = convert(Cint, -2) #/* thread detached from the VM */ -const JNI_EVERSION = convert(Cint, -3) #/* JNI version error */ -const JNI_ENOMEM = convert(Cint, -4) #/* not enough memory */ -const JNI_EEXIST = convert(Cint, -5) #/* VM already created */ -const JNI_EINVAL = convert(Cint, -6) #/* invalid arguments */ - const JAVA_HOME_CANDIDATES = ["/usr/lib/jvm/default-java/", "/usr/lib/jvm/default/"] +struct JavaCallError <: Exception + msg::String +end + function javahome_winreg() keys = ["SOFTWARE\\JavaSoft\\Java Runtime Environment", "SOFTWARE\\JavaSoft\\Java Development Kit", "SOFTWARE\\JavaSoft\\JDK"] @@ -262,7 +248,7 @@ else assertroottask_or_goodenv() = isgoodenv() ? nothing : throw(ROOT_TASK_ERROR) end -isloaded() = isdefined(JavaCall, :jnifunc) && isdefined(JavaCall, :penv) && penv != C_NULL +isloaded() = JNI.is_jni_loaded() && isdefined(JavaCall, :penv) && penv != C_NULL assertloaded() = isloaded() ? nothing : throw(JavaCallError("JVM not initialised. Please run init()")) assertnotloaded() = isloaded() ? throw(JavaCallError("JVM already initialised")) : nothing @@ -312,17 +298,16 @@ function _init(opts) opt = [JavaVMOption(pointer(x), C_NULL) for x in opts] ppjvm = Array{Ptr{JavaVM}}(undef, 1) ppenv = Array{Ptr{JNIEnv}}(undef, 1) - vm_args = JavaVMInitArgs(JNI_VERSION_1_6, convert(Cint, length(opts)), + vm_args = JavaVMInitArgs(JNI.JNI_VERSION_1_8, convert(Cint, length(opts)), convert(Ptr{JavaVMOption}, pointer(opt)), JNI_TRUE) res = ccall(create, Cint, (Ptr{Ptr{JavaVM}}, Ptr{Ptr{JNIEnv}}, Ptr{JavaVMInitArgs}), ppjvm, ppenv, Ref(vm_args)) res < 0 && throw(JavaCallError("Unable to initialise Java VM: $(res)")) global penv = ppenv[1] global pjvm = ppjvm[1] - jnienv = unsafe_load(penv) jvm = unsafe_load(pjvm) global jvmfunc = unsafe_load(jvm.JNIInvokeInterface_) - global jnifunc = unsafe_load(jnienv.JNINativeInterface_) #The JNI Function table + JNI.load_jni(penv) return end @@ -375,10 +360,9 @@ function init_current_vm() global pjvm = ppjvm[1] jvm = unsafe_load(pjvm) global jvmfunc = unsafe_load(jvm.JNIInvokeInterface_) - ccall(jvmfunc.GetEnv, Cint, (Ptr{Nothing}, Ptr{Ptr{JNIEnv}}, Cint), pjvm, ppenv, JNI_VERSION_1_8) + ccall(jvmfunc.GetEnv, Cint, (Ptr{Nothing}, Ptr{Ptr{JNIEnv}}, Cint), pjvm, ppenv, JNI.JNI_VERSION_1_8) global penv = ppenv[1] - jnienv = unsafe_load(penv) - global jnifunc = unsafe_load(jnienv.JNINativeInterface_) #The JNI Function table + JNI.load_jni(penv) end function destroy() diff --git a/src/make_jni2.jl b/src/make_jni2.jl new file mode 100644 index 0000000..8dd901c --- /dev/null +++ b/src/make_jni2.jl @@ -0,0 +1,126 @@ +#println("module JNI") +#println("import ..JavaCall: JNIEnv, JavaVM, jbyte, jchar, jshort, jint, jlong, jsize, jdouble, jfloat, jboolean") +#for t in ["jobject", "jclass", "jthrowable", "jweak", "jmethodID", "jfieldID", "jstring", "jarray", "JNINativeMethod"] +#println("$t = Ptr{Nothing}") +#end +#for t in ["object", "boolean", "byte", "short", "int", "long", "float", "double", "char"] +#println("j$(t)Array = Ptr{Nothing}") +#end +#println("jvalue = Int64") +#println() +println("# === Below Generated by ",PROGRAM_FILE," ===") +println("") + +function arg_name(m) + m.captures[3] +end + +function arg_value(m) + #if m.captures[2] == "*" && m.captures[1] == "char" return "String($(m.captures[3]))" end + m.captures[3] +end + +decl_arg_type(m) = decl_arg_type(m.captures[1], m.captures[2]) +ccall_arg_type(m; r=false) = ccall_arg_type(m.captures[1], m.captures[2], r=r) + +function decl_arg_type(t, s) + if s == "*" + if t == "char" + return "AnyString" + elseif t == "void" + return "Ptr{Nothing}" + elseif t == "JNIEnv" + return "Ptr{JNIEnv}" + else + return "Array{$t,1}" +# return "Ptr{$t}" + end + elseif t == "jsize" #|| t == "jint" || t == "jlong" || t == "jshort" || t == "jbyte" + return Integer + end + + if t == "void" + return "Nothing" + end + + return s == "" ? t : "Array{$t,1}" +# return s == "" ? t : "Ptr{$t}" +end + +function ccall_arg_type(t, s; r=false) + if s == "*" + if t == "char" + return "Cstring" + elseif t == "void" + return "Ptr{Nothing}" + elseif t == "JNIEnv" + return "Ptr{JNIEnv}" + else + return "Ptr{$t}" + end + end + + if t == "void" + return "Nothing" + end + + # No asterisk: type + # If return type, Ptr + # Else Array + return s == "" ? t : r ? "Ptr{$t}" : "Array{$t,1}" +end + +# julia_arg(m) = string(arg_name(m), "::", decl_arg_type(m)) +function julia_arg(m) + if arg_name(m) == "isCopy" + "isCopy::PtrIsCopy" + elseif arg_name(m) == "elems" + string(arg_name(m), "::", "Ptr{$(m.captures[1])}") + else + string(arg_name(m), "::", decl_arg_type(m)) + end +end + +for line in open(readlines, "jnienv.jl", "r") + # m: match comments + # Example: + # # jclass ( *GetSuperclass) (JNIEnv *env, jclass sub); + # Group 1: Return type ((?:void|char|j\w+)) "jclass" + # Group 2: Asterisk (\**) "" + # Group 3: Function name (\w+) "GetSuperclass" + # Group 4: Arguments \((.*)\) "JNIEnv *env, jclass sub" + m = match(r"\# \s* (?:const\s*)? ((?:void|char|j\w+)) \s* (\**) \s* \( \s* \* (\w+) \s* \) \s* \((.*)\) \s* ;"x, line) + if m === nothing continue end + + # Ignore functions with variable argument syntax + # Only process vararg functions that end in A + if occursin("...", m.captures[4]) continue end + if occursin("va_list", m.captures[4]) continue end + + # Get return type + rtype = ccall_arg_type(m.captures[1], m.captures[2], r=true) + + # Function name + fname = m.captures[3] + # Split arguments + args = split(m.captures[4], ",") + + # mm: Analyze arguments + # Example: [1] "JNIEnv *env", [2] "jclass sub" + # Group 1: Argument type ((?:void|j\w+|char|JNI\w+|JavaVM)) + # Group 2: Asterisk (\**) + # Group 3: Argument name (\w+) + mm = map(x->match(r"^\s* (?:const\s+)? \s* ((?:void|j\w+|char|JNI\w+|JavaVM)) \s*? (\**) \s* (\w+) \s*$"x, x), args) + + julia_args = join(map(julia_arg, mm), ", ") + arg_types = join(map(ccall_arg_type, mm), ", ") + arg_names = join(map(arg_value, mm), ", ") + + # Commented out export command + # print("#export $fname\n") + print("$fname($julia_args) =\n ccall(jniref[].$(fname), $rtype, ($arg_types,), $arg_names)\n\n") +end + +# println("end") +println("") +println("# === Above Generated by ",PROGRAM_FILE," ===")