MADARA  3.4.1
JavaThread.cpp
Go to the documentation of this file.
1 #ifdef _MADARA_JAVA_
2 
3 #include "JavaThread.h"
4 
6 
8 
9 namespace threads = madara::threads;
10 namespace knowledge = madara::knowledge;
11 
13  : obj_(0), class_(0), run_method_(0), init_method_(0), cleanup_method_(0)
14 {
15 }
16 
18 {
19  // manage VM attachment
21 
22  if (jvm.env != 0)
23  {
25  "threads::JavaThread::destructor:"
26  " Deleting global references.\n");
27 
28  jvm.env->DeleteGlobalRef(obj_);
29  jvm.env->DeleteGlobalRef(class_);
30  }
31 }
32 
34 {
36  "threads::JavaThread::assignment:"
37  " Checking for source not being same as dest\n");
38 
39  if (this != &rhs && obj_ != rhs.obj_)
40  {
41  JNIEnv* env = ::madara_jni_get_env();
42 
43  // perform the assignment
44  if (env)
45  {
47  "threads::JavaThread::assignment:"
48  " Deleting global references from left hand side\n");
49 
50  env->DeleteGlobalRef(obj_);
51  env->DeleteGlobalRef(class_);
52 
53  obj_ = env->NewGlobalRef(rhs.obj_);
54  class_ = (jclass)env->NewGlobalRef(rhs.class_);
55  cleanup_method_ = rhs.cleanup_method_;
56  init_method_ = rhs.init_method_;
57  run_method_ = rhs.run_method_;
58  }
59  }
60 }
61 
63 {
65  JNIEnv* env = jvm.env;
66 
68  "threads::JavaThread(%s)::run:"
69  " Calling user-defined run method\n",
70  name.c_str());
71 
72  env->CallVoidMethod(obj_, run_method_);
73 }
74 
76 {
78  JNIEnv* env = jvm.env;
79 
81  "threads::JavaThread(%s)::cleanup:"
82  " Calling user-defined cleanup method\n",
83  name.c_str());
84 
85  env->CallVoidMethod(obj_, cleanup_method_);
86 }
87 
89 {
91  JNIEnv* env = jvm.env;
92 
94  "threads::JavaThread(%s)::init:"
95  " Creating Java KnowledgeBase from data plane\n",
96  name.c_str());
97 
98  jclass kb_class = madara::utility::java::find_class(
99  env, "ai/madara/knowledge/KnowledgeBase");
100 
101  jmethodID fromPointerCall = env->GetStaticMethodID(
102  kb_class, "fromPointer", "(JZ)Lai/madara/knowledge/KnowledgeBase;");
103 
104  jboolean manage(false);
105 
106  jobject jknowledge = env->CallStaticObjectMethod(
107  kb_class, fromPointerCall, (jlong)&context, manage);
108 
110  "threads::JavaThread(%s)::init:"
111  " Calling user-defined init method\n",
112  name.c_str());
113 
114  env->CallVoidMethod(obj_, init_method_, jknowledge);
115 
116  env->DeleteLocalRef(jknowledge);
117  env->DeleteWeakGlobalRef(kb_class);
118 }
119 
121 {
122  JavaThread* result = new JavaThread();
123 
124  if (!result->check_compliance(obj))
125  {
126  delete result;
127  result = 0;
128  }
129 
130  return result;
131 }
132 
134 {
136  JNIEnv* env = jvm.env;
137 
138  bool result(true);
139 
140  if (env)
141  {
143  "threads::JavaThread(%s)::check_compliance:"
144  " allocating global reference for object\n",
145  name.c_str());
146 
147  obj_ = (jobject)env->NewGlobalRef(obj);
148 
149  if (obj_)
150  {
152  "threads::JavaThread(%s)::check_compliance:"
153  " allocating global reference for object's class\n",
154  name.c_str());
155 
156  class_ = (jclass)env->NewGlobalRef(env->GetObjectClass(obj_));
157  if (class_)
158  {
160  "threads::JavaThread(%s)::check_compliance:"
161  " class and object obtained successfully\n",
162  name.c_str());
163 
164  // stash the method calls to minimize call time
165  run_method_ = env->GetMethodID(class_, "run", "()V");
166  init_method_ = env->GetMethodID(
167  class_, "init", "(Lai/madara/knowledge/KnowledgeBase;)V");
168  cleanup_method_ = env->GetMethodID(class_, "cleanup", "()V");
169 
170  if (!run_method_)
171  {
174  "threads::JavaThread(%s)::check_compliance:"
175  " ERROR: run method must be defined\n",
176  name.c_str());
177 
178  result = false;
179  }
180 
181  if (!init_method_)
182  {
185  "threads::JavaThread(%s)::check_compliance:"
186  " ERROR: init method must be defined\n",
187  name.c_str());
188 
189  result = false;
190  }
191 
192  if (!cleanup_method_)
193  {
196  "threads::JavaThread(%s)::check_compliance:"
197  " ERROR: cleanup method must be defined\n",
198  name.c_str());
199 
200  result = false;
201  }
202  }
203  else
204  {
207  "threads::JavaThread(%s)::check_compliance:"
208  " ERROR: class object inaccessible\n",
209  name.c_str());
210 
211  result = false;
212  }
213  }
214  else
215  {
217  "threads::JavaThread(%s)::check_compliance:"
218  " ERROR: object is invalid\n",
219  name.c_str());
220 
221  result = false;
222  }
223  }
224  else
225  {
227  "threads::JavaThread(%s)::check_compliance:"
228  " ERROR: unable to acquire JAVA environment\n",
229  name.c_str());
230 
231  result = false;
232  }
233 
234  return result;
235 }
236 
238 {
239  // Initialize the underlying control variables
241 
242  // setup the Java variables
244  JNIEnv* env = ::madara_jni_get_env();
245 
247  "threads::JavaThread(%s)::init_control_vars:"
248  " Populating user control plane variables\n",
249  name.c_str());
250 
251  // obtain fromPointer method for ai.madara.knowledge.containers.Integer
252  jclass i_class = madara::utility::java::find_class(
253  env, "ai/madara/knowledge/containers/Integer");
254  jmethodID fromPointerCall = env->GetStaticMethodID(
255  i_class, "fromPointer", "(JZ)Lai/madara/knowledge/containers/Integer;");
256 
257  // the user thread should not manage C++ memory. We'll do that.
258  jboolean manage(false);
259 
260  // create java objects for the underlying containers
261  jobject jterminate = env->CallStaticObjectMethod(
262  i_class, fromPointerCall, (jlong)&terminated, manage);
263  jobject jpaused = env->CallStaticObjectMethod(
264  i_class, fromPointerCall, (jlong)&paused, manage);
265 
266  // set the user-defined threads's containers to these new containers
267  jfieldID fieldId = env->GetFieldID(
268  class_, "terminated", "Lai/madara/knowledge/containers/Integer;");
269  env->SetObjectField(obj_, fieldId, jterminate);
270 
271  fieldId = env->GetFieldID(
272  class_, "paused", "Lai/madara/knowledge/containers/Integer;");
273  env->SetObjectField(obj_, fieldId, jpaused);
274 
275  jvm.env->DeleteWeakGlobalRef(i_class);
276  jvm.env->DeleteLocalRef(jterminate);
277  jvm.env->DeleteLocalRef(jpaused);
278 }
279 
280 #endif // _MADARA_JAVA_
#define madara_logger_ptr_log(loggering, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:41
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
virtual void init_control_vars(knowledge::KnowledgeBase &control)
Initializes the thread implementation's control plane variables.
Definition: BaseThread.h:78
A facade for a user-defined Java thread class.
Definition: JavaThread.h:28
virtual void init(knowledge::KnowledgeBase &context)
Initializes Java thread with MADARA context.
Definition: JavaThread.cpp:88
jmethodID cleanup_method_
handle to the cleanup method
Definition: JavaThread.h:95
jmethodID init_method_
handle to the init method
Definition: JavaThread.h:92
void operator=(const JavaThread &rhs)
Assignment operator.
Definition: JavaThread.cpp:33
jclass class_
the class of the Java object obj_
Definition: JavaThread.h:86
static JavaThread * create(jobject obj)
Creates a JavaThread.
Definition: JavaThread.cpp:120
virtual void run(void)
Executes the Java thread's logic.
Definition: JavaThread.cpp:62
virtual void init_control_vars(knowledge::KnowledgeBase &control)
Initializes the Java thread implementation's control plane variables.
Definition: JavaThread.cpp:237
bool check_compliance(jobject obj)
Checks a Java object for compliance with ai.madara.threads.BaseThread.
Definition: JavaThread.cpp:133
virtual void cleanup(void)
Calls the Java cleanup method.
Definition: JavaThread.cpp:75
jmethodID run_method_
handle to the run method
Definition: JavaThread.h:89
jobject obj_
the Java thread implementation of ai.madara.threads.BaseThread
Definition: JavaThread.h:83
This class encapsulates attaching and detaching to a VM.
Definition: Acquire_VM.h:25
JNIEnv * env
The Java environment.
Definition: Acquire_VM.h:58
Provides functions and classes for the distributed knowledge base.
T get(const KnowledgeRecord &kr)
Get the value of a KnowlegeRecord.
Definition: GetRecord.h:121
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
Provides a quality-of-service-enabled threading library.
Definition: BaseThread.h:28