You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by an...@apache.org on 2016/08/02 15:42:44 UTC
[2/7] mesos git commit: Added native implementation for v1 Mesos
interface.
Added native implementation for v1 Mesos interface.
This change adds the native C++ implementation for the v1
Java class `JNIMesos` used for interacting with Mesos.
Review: https://reviews.apache.org/r/50252
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/bca68f63
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/bca68f63
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/bca68f63
Branch: refs/heads/master
Commit: bca68f63aa04d91cdb44b8e100f364bf981d6bd2
Parents: 5855532
Author: Anand Mazumdar <an...@apache.org>
Authored: Tue Jul 19 23:17:50 2016 -0700
Committer: Anand Mazumdar <an...@apache.org>
Committed: Tue Aug 2 08:25:48 2016 -0700
----------------------------------------------------------------------
src/Makefile.am | 9 +-
.../org_apache_mesos_v1_scheduler_JNIMesos.cpp | 317 +++++++++++++++++++
2 files changed, 325 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/bca68f63/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 3a743e4..2b02b5f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1562,6 +1562,7 @@ libjava_la_SOURCES = \
java/jni/org_apache_mesos_state_LogState.cpp \
java/jni/org_apache_mesos_state_Variable.cpp \
java/jni/org_apache_mesos_state_ZooKeeperState.cpp \
+ java/jni/org_apache_mesos_v1_scheduler_JNIMesos.cpp \
jvm/jvm.cpp \
jvm/jvm.hpp \
jvm/java/io.hpp \
@@ -1603,7 +1604,8 @@ nodist_libjava_la_SOURCES = \
java/jni/org_apache_mesos_state_LevelDBState.h \
java/jni/org_apache_mesos_state_LogState.h \
java/jni/org_apache_mesos_state_Variable.h \
- java/jni/org_apache_mesos_state_ZooKeeperState.h
+ java/jni/org_apache_mesos_state_ZooKeeperState.h \
+ java/jni/org_apache_mesos_v1_scheduler_JNIMesos.h
BUILT_SOURCES += $(nodist_libjava_la_SOURCES)
@@ -1647,6 +1649,11 @@ java/jni/org_apache_mesos_state_ZooKeeperState.h: $(MESOS_JAR)
-classpath $(MESOS_JAR):@PROTOBUF_JAR@ \
org.apache.mesos.state.ZooKeeperState
+java/jni/org_apache_mesos_v1_scheduler_JNIMesos.h: $(MESOS_JAR)
+ $(JAVA_HOME)/bin/javah -d java/jni \
+ -classpath $(MESOS_JAR):@PROTOBUF_JAR@ \
+ org.apache.mesos.v1.scheduler.JNIMesos
+
$(EXAMPLES_JAR): $(EXAMPLES_SOURCE)
@echo "Building examples.jar ..."
$(MKDIR_P) examples/java
http://git-wip-us.apache.org/repos/asf/mesos/blob/bca68f63/src/java/jni/org_apache_mesos_v1_scheduler_JNIMesos.cpp
----------------------------------------------------------------------
diff --git a/src/java/jni/org_apache_mesos_v1_scheduler_JNIMesos.cpp b/src/java/jni/org_apache_mesos_v1_scheduler_JNIMesos.cpp
new file mode 100644
index 0000000..e197b37
--- /dev/null
+++ b/src/java/jni/org_apache_mesos_v1_scheduler_JNIMesos.cpp
@@ -0,0 +1,317 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+#include <vector>
+
+#include <process/owned.hpp>
+
+#include <mesos/v1/mesos.hpp>
+
+#include <mesos/v1/scheduler.hpp>
+
+#include <mesos/v1/scheduler/scheduler.hpp>
+
+#include <stout/foreach.hpp>
+#include <stout/lambda.hpp>
+#include <stout/option.hpp>
+#include <stout/result.hpp>
+#include <stout/try.hpp>
+
+#include "jvm/jvm.hpp"
+
+#include "construct.hpp"
+#include "convert.hpp"
+#include "org_apache_mesos_v1_scheduler_JNIMesos.h"
+
+using namespace mesos::v1::scheduler;
+
+using mesos::v1::Credential;
+
+using process::Owned;
+
+using std::string;
+using std::vector;
+
+namespace v1 {
+
+class JNIMesos
+{
+public:
+ JNIMesos(
+ JNIEnv* _env,
+ jweak _jmesos,
+ const string& master,
+ const Option<Credential>& credential)
+ : jvm(nullptr), env(_env), jmesos(_jmesos)
+ {
+ env->GetJavaVM(&jvm);
+
+ mesos.reset(
+ new Mesos(master,
+ mesos::ContentType::PROTOBUF,
+ std::bind(&JNIMesos::connected, this),
+ std::bind(&JNIMesos::disconnected, this),
+ std::bind(&JNIMesos::received_, this, lambda::_1),
+ credential));
+ }
+
+ virtual ~JNIMesos() = default;
+
+ virtual void connected();
+ virtual void disconnected();
+ virtual void received(const Event& event);
+
+ void received_(std::queue<Event> events) {
+ while (!events.empty()) {
+ received(events.front());
+ events.pop();
+ }
+ }
+
+ JavaVM* jvm;
+ JNIEnv* env;
+ jweak jmesos;
+
+ Owned<Mesos> mesos;
+};
+
+
+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();
+}
+
+
+void JNIMesos::disconnected()
+{
+ 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.disconnected(mesos);
+ jmethodID disconnected =
+ env->GetMethodID(clazz, "disconnected",
+ "(Lorg/apache/mesos/v1/scheduler/Mesos;)V");
+
+ env->ExceptionClear();
+
+ env->CallVoidMethod(jscheduler, disconnected, jmesos);
+
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ jvm->DetachCurrentThread();
+ ABORT("Exception thrown during `disconnected` call");
+ }
+
+ jvm->DetachCurrentThread();
+}
+
+
+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();
+}
+
+} // namespace v1 {
+
+
+extern "C" {
+
+/*
+ * Class: org_apache_mesos_v1_JNIMesos
+ * Method: initialize
+ * Signature: ()V
+ *
+ */
+JNIEXPORT void JNICALL Java_org_apache_mesos_v1_scheduler_JNIMesos_initialize
+ (JNIEnv* env, jobject thiz)
+{
+ jclass clazz = env->GetObjectClass(thiz);
+
+ // Create a weak global reference to the Scheduler
+ // instance (we want a global reference so the GC doesn't collect
+ // the instance but we make it weak so the JVM can exit).
+ jweak jmesos = env->NewWeakGlobalRef(thiz);
+
+ // Get out the master passed into the constructor.
+ jfieldID master = env->GetFieldID(clazz, "master", "Ljava/lang/String;");
+ jobject jmaster = env->GetObjectField(thiz, master);
+
+ // Get out the credential passed into the constructor.
+ jfieldID credential =
+ env->GetFieldID(clazz, "credential",
+ "Lorg/apache/mesos/v1/Protos$Credential;");
+
+ jobject jcredential = env->GetObjectField(thiz, credential);
+
+ Option<Credential> credential_;
+ if (!env->IsSameObject(jcredential, nullptr)) {
+ credential_ = construct<Credential>(env, jcredential);
+ }
+
+ // Create the C++ scheduler and initialize `__mesos`.
+ v1::JNIMesos* mesos =
+ new v1::JNIMesos(env, jmesos, construct<string>(env, jmaster), credential_);
+
+ jfieldID __mesos = env->GetFieldID(clazz, "__mesos", "J");
+ env->SetLongField(thiz, __mesos, (jlong) mesos);
+}
+
+
+/*
+ * Class: org_apache_mesos_v1_JNIMesos
+ * Method: finalize
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_apache_mesos_v1_scheduler_JNIMesos_finalize
+ (JNIEnv* env, jobject thiz)
+{
+ jclass clazz = env->GetObjectClass(thiz);
+
+ jfieldID __mesos = env->GetFieldID(clazz, "__mesos", "J");
+ v1::JNIMesos* mesos =
+ (v1::JNIMesos*) env->GetLongField(thiz, __mesos);
+
+ env->DeleteWeakGlobalRef(mesos->jmesos);
+
+ delete mesos;
+}
+
+
+/*
+ * Class: org_apache_mesos_v1_JNIMesos
+ * Method: send
+ * Signature: (Lorg/apache/mesos/v1/scheduler/Protos/Call;)V
+ */
+JNIEXPORT void JNICALL Java_org_apache_mesos_v1_scheduler_JNIMesos_send
+ (JNIEnv* env, jobject thiz, jobject jcall)
+{
+ // Construct a C++ Call from the Java Call.
+ const Call& call = construct<Call>(env, jcall);
+
+ jclass clazz = env->GetObjectClass(thiz);
+
+ jfieldID __mesos = env->GetFieldID(clazz, "__mesos", "J");
+ v1::JNIMesos* mesos =
+ (v1::JNIMesos*) env->GetLongField(thiz, __mesos);
+
+ // It is possible that `mesos` might not be initialized in some cases due to
+ // a possible race condition. See MESOS-5926 for more details.
+ if (mesos->mesos.get() == nullptr) {
+ LOG(WARNING) << "Ignoring call " << call.type() << " as the library has "
+ << "not been initialized yet";
+ return;
+ }
+
+ mesos->mesos->send(call);
+}
+
+
+/*
+ * Class: org_apache_mesos_v1_scheduler_JNIMesos
+ * Method: reconnect
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_apache_mesos_v1_scheduler_JNIMesos_reconnect
+ (JNIEnv* env, jobject thiz)
+{
+ jclass clazz = env->GetObjectClass(thiz);
+
+ jfieldID __mesos = env->GetFieldID(clazz, "__mesos", "J");
+ v1::JNIMesos* mesos =
+ (v1::JNIMesos*) env->GetLongField(thiz, __mesos);
+
+ // It is possible that `mesos` might not be initialized in some cases due to
+ // a possible race condition. See MESOS-5926 for more details.
+ if (mesos->mesos.get() == nullptr) {
+ LOG(WARNING) << "Ignoring the reconnect request as the library has not "
+ << "been initialized yet";
+ return;
+ }
+
+ mesos->mesos->reconnect();
+}
+
+} // extern "C" {