void JNIMesos::received(const Event& event) { jvm->AttachCurrentThread(JNIENV_CAST(&env), nullptr); jclass clazz = env->GetObjectClass(jmesos); jfieldID scheduler = env->GetFieldID(clazz, "scheduler", "Lorg/apache/mesos/v1/scheduler/Scheduler;"); jobject jscheduler = env->GetObjectField(jmesos, scheduler); clazz = env->GetObjectClass(jscheduler); // scheduler.received(mesos, event); jmethodID received = env->GetMethodID(clazz, "received", "(Lorg/apache/mesos/v1/scheduler/Mesos;" "Lorg/apache/mesos/v1/scheduler/Protos$Event;)V"); jobject jevent = convert<Event>(env, event); env->ExceptionClear(); env->CallVoidMethod(jscheduler, received, jmesos, jevent); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); jvm->DetachCurrentThread(); ABORT("Exception thrown during `received` call"); } jvm->DetachCurrentThread(); }
void JNIMesos::connected() { jvm->AttachCurrentThread(JNIENV_CAST(&env), nullptr); jclass clazz = env->GetObjectClass(jmesos); jfieldID scheduler = env->GetFieldID(clazz, "scheduler", "Lorg/apache/mesos/v1/scheduler/Scheduler;"); jobject jscheduler = env->GetObjectField(jmesos, scheduler); clazz = env->GetObjectClass(jscheduler); // scheduler.connected(mesos); jmethodID connected = env->GetMethodID(clazz, "connected", "(Lorg/apache/mesos/v1/scheduler/Mesos;)V"); env->ExceptionClear(); env->CallVoidMethod(jscheduler, connected, jmesos); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); jvm->DetachCurrentThread(); ABORT("Exception thrown during `connected` call"); } jvm->DetachCurrentThread(); }
Jvm::Env::Env(bool daemon) : env(NULL), detach(false) { JavaVM* jvm = Jvm::get()->jvm; // First check if we are already attached. int result = jvm->GetEnv(JNIENV_CAST(&env), Jvm::get()->version); // If we're not attached, attach now. if (result == JNI_EDETACHED) { if (daemon) { jvm->AttachCurrentThreadAsDaemon(JNIENV_CAST(&env), NULL); } else { jvm->AttachCurrentThread(JNIENV_CAST(&env), NULL); } detach = true; } }
Try<Jvm*> Jvm::create( const std::vector<std::string>& _options, JNI::Version version, bool exceptions) { // TODO(benh): Make this thread-safe. if (instance != NULL) { return Error("Java Virtual Machine already created"); } JavaVMInitArgs vmArgs; vmArgs.version = version; vmArgs.ignoreUnrecognized = false; std::vector<std::string> options = _options; #ifdef __APPLE__ // The Apple JNI implementation requires the AWT thread to not // be the main application thread. Enabling headless mode // circumvents the issue. Further details: // https://issues.apache.org/jira/browse/MESOS-524 // http://www.oracle.com/technetwork/articles/javase/headless-136834.html if (std::find(options.begin(), options.end(), "-Djava.awt.headless=true") == options.end()) { options.push_back("-Djava.awt.headless=true"); } #endif JavaVMOption* opts = new JavaVMOption[options.size()]; for (size_t i = 0; i < options.size(); i++) { opts[i].optionString = const_cast<char*>(options[i].c_str()); } vmArgs.nOptions = options.size(); vmArgs.options = opts; JavaVM* jvm = NULL; JNIEnv* env = NULL; int result = JNI_CreateJavaVM(&jvm, JNIENV_CAST(&env), &vmArgs); if (result == JNI_ERR) { return Error("Failed to create JVM!"); } delete[] opts; return instance = new Jvm(jvm, version, exceptions); }
Try<Jvm*> Jvm::create( const std::vector<std::string>& _options, JNI::Version version, bool exceptions) { // TODO(benh): Make this thread-safe. if (instance != NULL) { return Error("Java Virtual Machine already created"); } JavaVMInitArgs vmArgs; vmArgs.version = version; vmArgs.ignoreUnrecognized = false; std::vector<std::string> options = _options; #ifdef __APPLE__ // The Apple JNI implementation requires the AWT thread to not // be the main application thread. Enabling headless mode // circumvents the issue. Further details: // https://issues.apache.org/jira/browse/MESOS-524 // http://www.oracle.com/technetwork/articles/javase/headless-136834.html if (std::find(options.begin(), options.end(), "-Djava.awt.headless=true") == options.end()) { options.push_back("-Djava.awt.headless=true"); } #endif JavaVMOption* opts = new JavaVMOption[options.size()]; for (size_t i = 0; i < options.size(); i++) { opts[i].optionString = const_cast<char*>(options[i].c_str()); } vmArgs.nOptions = options.size(); vmArgs.options = opts; JavaVM* jvm = NULL; JNIEnv* env = NULL; Option<std::string> libJvmPath = os::getenv("JAVA_JVM_LIBRARY"); if (libJvmPath.isNone()) { libJvmPath = mesos::internal::build::JAVA_JVM_LIBRARY; } static DynamicLibrary* libJvm = new DynamicLibrary(); Try<Nothing> openResult = libJvm->open(libJvmPath.get()); if (openResult.isError()) { return Error(openResult.error()); } Try<void*> symbol = libJvm->loadSymbol("JNI_CreateJavaVM"); if (symbol.isError()) { libJvm->close(); return Error(symbol.error()); } // typedef function pointer to JNI. typedef jint (*fnptr_JNI_CreateJavaVM)(JavaVM**, void**, void*); fnptr_JNI_CreateJavaVM fn_JNI_CreateJavaVM = (fnptr_JNI_CreateJavaVM)symbol.get(); int createResult = fn_JNI_CreateJavaVM(&jvm, JNIENV_CAST(&env), &vmArgs); if (createResult == JNI_ERR) { libJvm->close(); return Error("Failed to create JVM!"); } delete[] opts; return instance = new Jvm(jvm, version, exceptions); }