ACT-CV - Machine Vision for Cognitive Modeling
JVM.cpp
Go to the documentation of this file.
1 // -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; coding: iso-8859-1; -*-
2 
3 /*
4 ACT-CV - Machine Vision for Cognitive Modeling
5 Copyright (c) 2008 Marc Halbruegge
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21 
27 #include <string.h>
28 #include <iostream>
29 #if HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include <mhexcptn.h>
34 #include <stdexcept>
35 #include "JVM.h"
36 
37 #include <GCString.h>
38 
39 using namespace std;
40 
41 // MH 20110313 TODO check OS X compability
42 
43 #ifdef _WINDOWS
44 class JvmDllFinder {
45 
46  GCPointer<GCString> jvmDllPath;
47 
48  void GetJvmPath(const char *vendor) {
49  HKEY jreKey=0;
50  HKEY curJreKey=0;
51  char buf[10240];
52  DWORD bufLen=10240;
53  try {
54  strcpy(buf, "SOFTWARE\\");
55  strcat(buf, vendor);
56  strcat(buf, "\\Java Runtime Environment");
57 
58  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
59  (LPCSTR) buf,
60  0, KEY_READ, &jreKey) != ERROR_SUCCESS) {
61  throw runtime_error("jre key not found");
62  }
63 
64  if (RegQueryValueEx(jreKey, TEXT("CurrentVersion"), nullptr,
65  nullptr, (LPBYTE) buf, &bufLen) != ERROR_SUCCESS) {
66  throw runtime_error("jre current version not found");
67  }
68  buf[bufLen]=0;
69  //cout << "Current JRE version: " << buf << endl;
70 
71  if (RegOpenKeyEx(jreKey,
72  (LPCSTR) buf,
73  0, KEY_READ, &curJreKey) != ERROR_SUCCESS) {
74  throw runtime_error("jre current version key not found");
75  }
76 
77  bufLen=10240;
78  if (RegQueryValueEx(curJreKey, TEXT("RunTimeLib"), nullptr,
79  nullptr, (LPBYTE) buf, &bufLen) != ERROR_SUCCESS) {
80  throw runtime_error("run time lib not found");
81  }
82  buf[bufLen]=0;
83  //cout << "Runtim Lib: " << buf << endl;
84 
85  jvmDllPath = new GCString(buf);
86 
87  } catch(runtime_error &e) {
88  cerr << e.what() << endl;
89  }
90  if (curJreKey) RegCloseKey(curJreKey);
91  if (jreKey) RegCloseKey(jreKey);
92  }
93 public:
94  JvmDllFinder() {
95  GetJvmPath("JRockit");
96  if (&*jvmDllPath == 0) {
97  GetJvmPath("JavaSoft");
98  }
99  if (&*jvmDllPath == 0) {
100  throw runtime_error("No Java Runtime Environment found");
101  }
102  }
103 
104  const char* GetJvmDll() const {
105  if (&*jvmDllPath != 0) {
106  return jvmDllPath->GetString();
107  } else {
108  return 0;
109  }
110  }
111 };
112 #endif
113 
115 #ifdef _WINDOWS
116  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
117  if (jvmInstance==0) {
118 
119  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
120  JvmDllFinder finder;
121 
122  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
123  jvmInstance = LoadLibrary( finder.GetJvmDll() );
124 
125  if (jvmInstance==0) {
126  throw runtime_error("could not locate a java virtual machine");
127  }
128 
129  FARPROC proc = GetProcAddress (jvmInstance, "JNI_CreateJavaVM");
130  if (proc == nullptr) {
131  throw runtime_error("could not locate a usable java virtual machine");
132  }
133  jniCreateJavaVM = (jint (__stdcall *) (JavaVM **, void **, void *)) proc;
134 
135  proc = GetProcAddress (jvmInstance, "JNI_GetCreatedJavaVMs");
136  if (proc == nullptr) {
137  throw runtime_error("could not locate a usable java virtual machine");
138  }
139 
140  jniGetCreatedJavaVMs = (jint (__stdcall *)(JavaVM **, jsize, jsize *)) proc;
141  }
142  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
143 #else
144  // Linux
145  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
146  if (jvmInstance==0) {
147  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
148  jvmInstance = dlopen ("libjvm.so", RTLD_LAZY | RTLD_LOCAL); // RTLD_LAZY //RTLD_NOW | RTLD_GLOBAL
149 
150  if (jvmInstance==0) {
151  throw runtime_error("could not locate a java virtual machine");
152  }
153 
154  jniCreateJavaVM = (jint (__stdcall *) (JavaVM **, void **, void *))
155  dlsym(jvmInstance, "JNI_CreateJavaVM");
156  if (jniCreateJavaVM == 0) {
157  throw runtime_error("could not locate a usable java virtual machine");
158  }
159 
160  jniGetCreatedJavaVMs = (jint (__stdcall *)(JavaVM **, jsize, jsize *))
161  dlsym(jvmInstance, "JNI_GetCreatedJavaVMs");
162  if (jniGetCreatedJavaVMs == 0) {
163  throw runtime_error("could not locate a usable java virtual machine");
164  }
165 
166  }
167  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
168 
169 #endif
170 }
171 
172 
180  if (mustDestroyVM) {
181  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
182  jvm->DestroyJavaVM();
183 #ifndef _WINDOWS
184  dlclose(jvmInstance);
185 #endif
186  }
187  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
188 }
189 
200 void JVM::CreateJVM(const char *classpath) {
201  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
202 
203  char *buf = new char[10240];
204  strcpy(buf,"-Djava.class.path=");
205  strcat(buf, classpath);
206  options[0].optionString = buf;
207 
208  options[1].optionString = (char*)"-verbose:gc,class,jni";
209 
210  //options[2].optionString = "-Xcheck:jni"; // doesn't work because of a bug in the jre
211  options[2].optionString = (char*)"-Xdebug";
212 
213  vm_args.version = JNI_VERSION_1_2;
214  vm_args.options = options;
215 #ifdef NDEBUG
216  vm_args.nOptions = 1;
217 #else
218  vm_args.nOptions = 3;
219 #endif
220  vm_args.ignoreUnrecognized = JNI_FALSE;
221 
222  JNIEnv *env;
223  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
224  int result = (*jniCreateJavaVM)(&jvm, (void**)&env, &vm_args);
225 
226  delete[] buf;
227 
228  if (result!=JNI_OK) throw FileLineException(__FILE__,__LINE__);
229  MHDBGMSG_P(__FILE__,__LINE__,"env:",env);
230 
231  threadSpecificEnvs[GetThreadId()]=env;
232 
233  mustDestroyVM=true;
234 }
235 
237 JVM::JVM() : jvm(nullptr), mustDestroyVM(false), jvmInstance(0) {
238  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
239  LoadJvmLib();
240 
241  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
242  JavaVM *alreadyCreated = GetCreatedJavaVM();
243  if (alreadyCreated) {
244  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
245  jvm = alreadyCreated;
246  JNIEnv *env;
247  jvm->GetEnv((void**)&env,JNI_VERSION_1_2);
248  if (env==nullptr) {
249  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
250  // thread is not attached
252  } else {
253  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
255  }
256  } else {
257  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
258  CreateJVM(".");
259  }
260 }
261 
263 JVM::JVM(const char *cp) : jvm(nullptr), mustDestroyVM(false), jvmInstance(0) {
264  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
265  LoadJvmLib();
266 
267  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
268  JavaVM *alreadyCreated = GetCreatedJavaVM();
269  if (alreadyCreated) {
270  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
271  jvm = alreadyCreated;
272  JNIEnv *env;
273  jvm->GetEnv((void**)&env,JNI_VERSION_1_2);
274  if (env==nullptr) {
275  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
276  // thread is not attached
278  } else {
279  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
281  }
282  } else {
283  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
284  CreateJVM(cp);
285  }
286 }
287 
289 jclass JVM::CreateGlobalRef(jclass obj) {
290  return (jclass)GetEnv()->NewGlobalRef(obj);
291 }
292 
294 jobject JVM::CreateGlobalRef(jobject obj) {
295  return GetEnv()->NewGlobalRef(obj);
296 }
297 
301 
302  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
303  JavaVMAttachArgs args;
304  args.version=JNI_VERSION_1_2;
305  args.name=0;
306  args.group=0;
307  JNIEnv *env;
308  jvm->AttachCurrentThread((void**)&env,&args);
309  MHDBGMSG(__FILE__,__LINE__,__PRETTY_FUNCTION__);
310 
312 }
313 
317  jvm->DetachCurrentThread();
318 }
319 
321  JavaVM *result = 0;
322  int bufLen=10;
323  jsize numVms=0;
324  JavaVM** vmBuf = new JavaVM*[bufLen];
325  jint res = (*jniGetCreatedJavaVMs)(vmBuf, bufLen, &numVms);
326  if (res!=0) {
327  throw FileLineException(__FILE__,__LINE__);
328  }
329  cout << numVms << " java virtual machine(s) currently created" << endl;
330  if (numVms>0) result=vmBuf[0];
331  delete vmBuf;
332  return result;
333 }
334 


ACT-CV - Machine Vision for Cognitive Modeling
© 2015 Marc Halbruegge (actcvlibrary@googlemail.com)