TJClassRef::TJClassRef(jclass classHandle, TJRefType refType, bool makeCopy): TJRef<jclass>(classHandle, refType, makeCopy), mClassName("") { JNIEnv* jniEnv = TJGetEnvironment(); if (jniEnv == nullptr) throw TJNIException(kThreadDetached, "Failed to get jni environment"); TJMethodID methodNameId = jniEnv->GetMethodID(mHandle, "toString", "()Ljava/lang/String;"); TJ_ASSERT (methodNameId != nullptr); ScopedLocalRef<jstring> name(static_cast<jstring>(jniEnv->CallObjectMethod(mHandle, methodNameId))); if (name != nullptr) { const char* chars = jniEnv->GetStringUTFChars(name, nullptr); if (chars == nullptr) GenerateJavaException(jniEnv, jniEnv->ExceptionOccurred(), "GetStringUTFChars failed in TJClassRef::TJClassRef"); size_t length = static_cast<size_t>(jniEnv->GetStringUTFLength(name)); // chars is in form of "class a.b.c" std::string fullName(chars, chars + length); std::string::size_type pos = fullName.rfind(' '); if (pos != std::string::npos) { mClassName.assign(chars + pos + 1, length - pos - 1); // convert a.b.c form to La/b/c class name form std::replace(mClassName.begin(), mClassName.end(), '.', '/'); mClassName = std::string("L") + mClassName; } jniEnv->ReleaseStringUTFChars(name, chars); } }
bool TJClassRef::operator == (const TJClassRef& rht) const { JNIEnv* environment = TJGetEnvironment(); if (environment == NULL) throw TJNIException(kThreadDetached, "Failed to get jnienv pointer in TJClassRef::operator =="); return environment->IsSameObject(mHandle, rht.mHandle) == JNI_TRUE; }
JNIEnv* TJGetEnvironmentExc() { TJInt resCode = kNoError; JNIEnv* environment = TJGetEnvironment(&resCode); if (environment == NULL) throw TJNIException(resCode, "Failed to get jnienv"); return environment; }
void TJClassRef::setField(const std::string& fieldName, jstring string) { if (string == nullptr) throw TJInvalidArgument("Invalid string argument in setStringField"); JNIEnv* environment = TJGetEnvironment(); if (environment == nullptr) throw TJNIException(kThreadDetached, "Failed to get jnienv in TJClassRef::setStringField"); jfieldID fieldDescriptor = environment->GetStaticFieldID(mHandle, fieldName.c_str(), "Ljava/lang/String;"); if (fieldDescriptor == nullptr) GenerateJavaException(environment, environment->ExceptionOccurred(), "GetStaticFieldID failed in TJClassRef::setObjectField"); }
void TJClassRef::setField(const std::string& fieldName, jobject value) { JNIEnv* environment = TJGetEnvironment(); if (environment == nullptr) throw TJNIException(kThreadDetached, "Failed to get jnienv in TJClassRef::setObjectField"); if (value == nullptr) throw TJInvalidArgument("Null value in setField"); TJClassRef classRef(environment->GetObjectClass(value), kLocalRef); jfieldID fieldDescriptor = environment->GetStaticFieldID(mHandle, fieldName.c_str(), classRef.descriptor().c_str()); if (fieldDescriptor == nullptr) GenerateJavaException(environment, environment->ExceptionOccurred(), "GetStaticFieldID failed in TJClassRef::setObjectField"); environment->SetStaticObjectField(mHandle, fieldDescriptor, value); }
TJObjectRef TJClassRef::field(const std::string& name, const std::string& objClassDescriptor, TJRefType refType) { JNIEnv* environment = TJGetEnvironment(); if (environment == nullptr) throw TJNIException(kThreadDetached, "Failed to get jnienv in TJClassRef::getObjectField"); jfieldID fieldDescriptor = environment->GetStaticFieldID(mHandle, name.c_str(), objClassDescriptor.c_str()); if (fieldDescriptor == nullptr) GenerateJavaException(environment, environment->ExceptionOccurred(), "GetStaticFieldID failed in TJClassRef::getObjectField"); jobject resObject = environment->GetStaticObjectField(mHandle, fieldDescriptor); if (refType == kLocalRef) return TJObjectRef(resObject, false, kLocalRef); else { ScopedLocalRef<jobject> cleaner(resObject); return TJObjectRef(resObject, true, refType); } };
TJClassRef TJClassRef::FindClass(const std::string& className, TJRefType refType) { // get JNI environment JNIEnv* environment = TJGetEnvironment(); if (environment == NULL) throw TJNIException(kThreadDetached, "Failed to get jnienv pointer in TJClassRef::FindClass"); // try to find appropriate class jclass localHandle = environment->FindClass(className.c_str()); if (localHandle == NULL) GenerateJavaException(environment, environment->ExceptionOccurred(), "Failed to find class in TJClassRef::FindClass"); if (refType == kLocalRef) return TJClassRef(localHandle, kLocalRef, false); else { ScopedLocalRef<jclass> cleaner(localHandle); TJClassRef resultClassRef(localHandle, refType, true); return resultClassRef; } }
TJClassRef TJClassRef::DefineClass(const std::string& className, const TJObjectRef& loader, const TJByte* buffer, TJSize bufLength, TJRefType refType) { // get JNI environment JNIEnv* environment = TJGetEnvironment(); if (environment == NULL) throw TJNIException(kThreadDetached, "Failed to get jnienv pointer in TJClassRef::FindClass"); if ((loader.get() == NULL) || (buffer == NULL) || (bufLength == 0)) throw TJInvalidArgument("Invalid params in TJClassRef::DefineClass"); jclass localClassHandle = environment->DefineClass(className.c_str(), loader.get(), buffer, bufLength); if (localClassHandle == NULL) GenerateJavaException(environment, environment->ExceptionOccurred(), "Failed to find class in TJClassRef::FindClass"); if (refType == kLocalRef) return TJClassRef(localClassHandle, kLocalRef, false); else { ScopedLocalRef<jclass> cleaner(localClassHandle); return TJClassRef(localClassHandle, refType, true); } }
JNIEnv* TJCreateJavaVm(const std::string& libPath, TJJNIVersion version, const TJStringArray& args) { // check if vm already exists if (sJavaVM != nullptr) return TJGetEnvironment(); #ifdef _WIN32 sVMLibrary = ::LoadLibraryA(libPath.c_str()); if (sVMLibrary == nullptr) return nullptr; // get appropriate function pointers pCreateFunc = reinterpret_cast<JNI_CreateJavaVMPtr>(::GetProcAddress(sVMLibrary, "JNI_CreateJavaVM")); if (pCreateFunc == nullptr) { ::FreeLibrary(sVMLibrary); sVMLibrary = nullptr; return nullptr; } pGetDefaultArgFunc = reinterpret_cast<JNI_GetDefaultJavaVMInitArgsPtr>(::GetProcAddress(sVMLibrary, "JNI_GetDefaultJavaVMInitArgs")); if (pGetDefaultArgFunc == nullptr) { ::FreeLibrary(sVMLibrary); sVMLibrary = nullptr; return nullptr; } sGetCreatedJavaVMsPtr = reinterpret_cast<JNI_GetCreatedJavaVMsPtr>(::GetProcAddress(sVMLibrary, "JNI_GetCreatedJavaVMs")); if (sGetCreatedJavaVMsPtr == NULL) { ::FreeLibrary(sVMLibrary); sVMLibrary = nullptr; return nullptr; } #else sVMLibrary = dlopen(libPath.c_str(), RTLD_NOW); if (sVMLibrary == NULL) return NULL; pCreateFunc = reinterpret_cast<JNI_CreateJavaVMPtr>(dlsym(sVMLibrary, "JNI_CreateJavaVM")); if (pCreateFunc == NULL) { dlclose(sVMLibrary); sVMLibrary = NULL; return NULL; } pGetDefaultArgFunc = reinterpret_cast<JNI_GetDefaultJavaVMInitArgsPtr>(dlsym(sVMLibrary, "JNI_GetDefaultJavaVMInitArgs")); if (pGetDefaultArgFunc == NULL) { dlclose(sVMLibrary); sVMLibrary = NULL; return NULL; } #endif JavaVMInitArgs vm_args = {0}; vm_args.version = static_cast<TJInt>(version); std::vector<JavaVMOption> optionsArray; if (!args.empty()) { size_t optionCount = args.size(); vm_args.nOptions = static_cast<jint>(optionCount); optionsArray.resize(optionCount); for (size_t i = 0; i < optionCount; ++i) { optionsArray[i].optionString = (char*)args[i].c_str(); optionsArray[i].extraInfo = NULL; } vm_args.options = &optionsArray[0]; vm_args.ignoreUnrecognized = JNI_TRUE; } /* Get the default initialization arguments and set the class path */ //pGetDefaultArgFunc(&vm_args); /* load and initialize a Java VM, return a JNI interface pointer in env */ JNIEnv* env = NULL; pCreateFunc(&sJavaVM, reinterpret_cast<void**>(&env), &vm_args); sCreatedVersion = version; return env; }