def attach(self, pjvm: Optional[object] = None): # -> Tuple['_JVM', jni.JNIEnv]: if_bind = pjvm is not None try: if if_bind and not pjvm: raise JVMException(EStatusCode.EINVAL, "First paramter must be a JNI jvm handle") penv = jni.obj(jni.POINTER(jni.JNIEnv)) if if_bind: self._jvm.jnijvm = jni.cast(pjvm, jni.POINTER(jni.JavaVM))[0] self._jvm.jnijvm.AttachCurrentThread(penv) else: self._jvm.jnijvm.GetEnv(penv, JVM.JNI_VERSION) jenv = jni.JEnv(penv) self._jvm._initialize(jenv) return self._jvm, jenv except Exception as exc: try: self.handleException(exc) finally: if if_bind: self._jvm.jnijvm = None
def start(self, *jvmoptions, **jvmargs): ignoreUnrecognized = jvmargs.get("ignoreUnrecognized", True) try: pjvm = jni.obj(jni.POINTER(jni.JavaVM)) penv = jni.obj(jni.POINTER(jni.JNIEnv)) jvm_args = jni.obj(jni.JavaVMInitArgs) jvm_args.version = JVM.JNI_VERSION jvm_args.nOptions = len(jvmoptions) jvm_args.options = joptions = jni.new_array( jni.JavaVMOption, jvm_args.nOptions) _keep = [] for i, option in enumerate(jvmoptions): optionString = jni.new_cstr(option if isinstance( option, bytes) else str(option).encode("utf-8")) _keep.append(optionString) jvm_args.options[i].optionString = optionString jvm_args.options[i].extraInfo = jni.NULL jvm_args.ignoreUnrecognized = jni.JNI_TRUE if ignoreUnrecognized else jni.JNI_FALSE err = self._JNI.CreateJavaVM(pjvm, penv, jvm_args) del _keep, joptions, jvm_args if err != jni.JNI_OK or jni.isNULL(pjvm): raise jni.JNIException( err if err != jni.JNI_OK else jni.JNI_ERR, info="JNI_CreateJavaVM") self._jnijvm = jni.JVM(pjvm) return self._jnijvm, jni.JEnv(penv) except Exception as exc: try: self.handleException(exc) finally: self._jnijvm = None
def releaseDoubleBuffer(self, buf: object, mode: Optional[bool] = None): with self.jvm as (jvm, jenv): if mode is None: jenv.ReleaseDoubleArrayElements( self._jobj, jni.cast(buf, jni.POINTER(jni.jdouble))) else: jenv.ReleaseDoubleArrayElements( self._jobj, jni.cast(buf, jni.POINTER(jni.jdouble)), jni.JNI_COMMIT if mode else jni.JNI_ABORT)
def start(self, *jvmoptions, **jvmargs): # -> Tuple['_JVM', jni.JNIEnv]: jvmoptions = tuple([ "-Djava.class.path=" + os.pathsep.join([ item.partition("=")[2] for item in jvmoptions if item.lstrip().startswith("-Djava.class.path=") ] + [str(path) for path in INTERNAL_CLASSPATHS]) ] + [ item for item in jvmoptions if not item.lstrip().startswith("-Djava.class.path=") ]) ignoreUnrecognized = jvmargs.get("ignoreUnrecognized", True) try: pjvm = jni.obj(jni.POINTER(jni.JavaVM)) penv = jni.obj(jni.POINTER(jni.JNIEnv)) jvm_args = jni.obj(jni.JavaVMInitArgs) jvm_args.version = JVM.JNI_VERSION jvm_args.nOptions = len(jvmoptions) jvm_args.options = joptions = jni.new_array( jni.JavaVMOption, jvm_args.nOptions) _keep = [] for i, option in enumerate(jvmoptions): optionString = jni.new_cstr(option if isinstance( option, bytes) else str(option).encode("utf-8")) _keep.append(optionString) jvm_args.options[i].optionString = optionString jvm_args.options[i].extraInfo = jni.NULL jvm_args.ignoreUnrecognized = jni.JNI_TRUE if ignoreUnrecognized else jni.JNI_FALSE err = self._jvm.JNI.CreateJavaVM(pjvm, penv, jvm_args) del _keep, joptions, jvm_args if err != jni.JNI_OK or jni.isNULL(pjvm): raise jni.JNIException( err if err != jni.JNI_OK else jni.JNI_ERR, info="JNI_CreateJavaVM") self._jvm.jnijvm = jni.JVM(pjvm) jenv = jni.JEnv(penv) try: self._jvm._initialize(jenv) except Exception as exc: try: self._jvm.jnijvm.DestroyJavaVM() except Exception: pass raise exc return self._jvm, jenv except Exception as exc: try: self.handleException(exc) finally: self._jvm.jnijvm = None
def __init__(self, jenv: jni.JNIEnv=None, jstr: jni.jobject=jni.obj(jni.POINTER(jni.jchar)), own: bool = True): self.__jstr = jni.cast(jstr, jni.jstring) self.__size = 0 self.__jchars = jni.obj(jni.POINTER(jni.jchar)) if jenv is not None and jstr: length = jenv.GetStringLength(self.__jstr) jchars = jenv.GetStringChars(self.__jstr) try: self.__jchars = jni.new_array(jni.jchar, length + 1) jni.memmove(self.__jchars, jchars, length * jni.sizeof(jni.jchar)) self.__jchars[length] = "\0" finally: jenv.ReleaseStringChars(self.__jstr, jchars) self.__size = length
def setCharSlice(self, start: int, stop: int, step: int, val: Union[Sequence[str], str]): with self.jvm as (jvm, jenv): size = JArray.size(start, stop, step) jarr = self._jobj if step == 1 and is_memview(val) and val.itemsize == jni.sizeof( jni.jchar): val = val.as_ctypes if isinstance( val, memview) else memview(val).as_ctypes jenv.SetCharArrayRegion(jarr, start, size, jni.cast(val, jni.POINTER(jni.jchar))) else: if is_memview(val): val = val.obj jels = jenv.GetCharArrayElements(jarr) try: if isinstance( val, str) and step == 1 and JArray._jchar_equiv_unicode: print("UUUUUUUUUUUUUUUUU") jni.memmove( jni.byref(jels.contents, start * jni.sizeof(jni.jchar)), val, JArray.size(start, stop) * jni.sizeof(jni.jchar)) else: for ix, idx in enumerate(range(start, stop, step)): jels[idx] = val[ix] jenv.ReleaseCharArrayElements(jarr, jels) except Exception as exc: jenv.ReleaseCharArrayElements(jarr, jels, jni.JNI_ABORT) raise exc
def setByteSlice(self, start: int, stop: int, step: int, val: Union[Sequence[Union[int, bytes]], bytes, bytearray]): """???.""" with self.jvm as (jvm, jenv): size = JArray.size(start, stop, step) jarr = self._jobj if step == 1 and is_memview(val) and val.itemsize == jni.sizeof(jni.jbyte): val = val.as_ctypes if isinstance(val, memview) else memview(val).as_ctypes jenv.SetByteArrayRegion(jarr, start, size, jni.cast(val, jni.POINTER(jni.jbyte))) else: if is_memview(val): val = val.obj jels = jenv.GetByteArrayElements(jarr) try: if isinstance(val, (bytes, bytearray)): if step == 1 and JArray._jbyte_equiv_byte: if isinstance(val, bytearray): val = jni.from_buffer(val) # print(("RRRRRRRRRRRRRRRRRR", # type(jels), type(jels.contents), type(val))) jni.memmove(jni.byref(jels.contents, start), val, JArray.size(start, stop)) else: for ix, idx in enumerate(range(start, stop, step)): jels[idx] = val[ix] else: for ix, idx in enumerate(range(start, stop, step)): v = val[ix] jels[idx] = v[0] if isinstance(v, bytes) else v jenv.ReleaseByteArrayElements(jarr, jels) except Exception as exc: jenv.ReleaseByteArrayElements(jarr, jels, jni.JNI_ABORT) raise exc
def registerClass(jenv: jni.JNIEnv, class_name: str, class_code, native_methods: Optional[Sequence[Callable]] = None, class_loader=None): if inspect.ismodule(class_code) or inspect.isclass(class_code): if native_methods is None: native_methods = getattr(class_code, "__jnimethods__", ()) class_code = class_code.__javacode__ else: if native_methods is None: native_methods = () jenv.PushLocalFrame(3) try: if class_loader is None: jcls = jenv.FindClass(b"java/lang/ClassLoader") jmid = jenv.GetStaticMethodID(jcls, b"getSystemClassLoader", b"()Ljava/lang/ClassLoader;") class_loader = jenv.CallStaticObjectMethod(jcls, jmid) try: jcls = jenv.FindClass(class_name.replace(".", "/").encode("utf-8")) except Exception: size = len(class_code) jcls = jenv.DefineClass(class_name.replace(".", "/").encode("utf-8"), class_loader, jni.cast(jni.from_buffer(class_code), jni.POINTER(jni.jbyte)), size) methods = jni.new_array(jni.JNINativeMethod, len(native_methods)) for idx, method in enumerate(native_methods): methods[idx] = method jenv.RegisterNatives(jcls, methods, len(methods)) finally: jenv.PopLocalFrame(jni.NULL)
def attachThread(self, daemon: bool = False): try: penv = jni.obj(jni.POINTER(jni.JNIEnv)) if not daemon: self._jvm.jnijvm.AttachCurrentThread(penv) else: self._jvm.jnijvm.AttachCurrentThreadAsDaemon(penv) return self._jvm, jni.JEnv(penv) except Exception as exc: self.handleException(exc)
def __enter__(self): if self._jvm is None: raise JVMException( EStatusCode.EDETACHED, "Unable to use JVM: thread detached from the VM") if self._jvm.jnijvm: penv = jni.obj(jni.POINTER(jni.JNIEnv)) self._jvm.jnijvm.AttachCurrentThread(penv) return self._jvm, jni.JEnv(penv) else: return self._jvm, None
def shutdown(self): if self._jnijvm is None: return try: penv = jni.obj(jni.POINTER(jni.JNIEnv)) self._jnijvm.AttachCurrentThread(penv) self._jnijvm.DestroyJavaVM() except Exception as exc: try: self.handleException(exc) finally: self._jnijvm = None
def isThreadAttached(self) -> bool: try: penv = jni.obj(jni.POINTER(jni.JNIEnv)) self._jvm.jnijvm.GetEnv(penv, JVM.JNI_VERSION) except jni.JNIException as exc: if exc.getError() == jni.JNI_EDETACHED: return False self.handleException(exc) except Exception as exc: self.handleException(exc) else: return not jni.isNULL(penv)
def __init__(self, jenv: Optional[jni.JNIEnv] = None): if jenv is None: from .jconstants import EStatusCode from .jvm import JVMException raise JVMException(EStatusCode.EDETACHED, "Unable to use JVM: thread detached from the VM") pjvm = jni.obj(jni.POINTER(jni.JavaVM)) jenv.GetJavaVM(pjvm) from .jvm import _JVM jvm = _JVM() jvm.jnijvm = jni.JVM(pjvm) self.jvm = jvm # jvm._JVM self.jenv = jenv # jni.JNIEnv
def createdJVMs(self) -> Tuple['_JVM', ...]: njvm = jni.new(jni.jsize) err = self._jvm.JNI.GetCreatedJavaVMs(None, 0, njvm) if err != jni.JNI_OK: raise jni.JNIException(err, info="JNI_GetCreatedJavaVMs") pjvm = jni.new_array(jni.POINTER(jni.JavaVM), njvm[0]) err = self._jvm.JNI.GetCreatedJavaVMs(pjvm, len(pjvm), njvm) if err != jni.JNI_OK: raise jni.JNIException(err, info="JNI_GetCreatedJavaVMs") jvms = [] for i in range(njvm[0]): jvm = _JVM() jvm.JNI = self._jvm.JNI jvm.jnijvm = pjvm[0][i] jvms.append(jvm) return tuple(jvms)
def setFloatSlice(self, start: int, stop: int, step: int, val: Sequence[float]): """???.""" with self.jvm as (jvm, jenv): size = JArray.size(start, stop, step) jarr = self._jobj if step == 1 and is_memview(val) and val.itemsize == jni.sizeof(jni.jfloat): val = val.as_ctypes if isinstance(val, memview) else memview(val).as_ctypes jenv.SetFloatArrayRegion(jarr, start, size, jni.cast(val, jni.POINTER(jni.jfloat))) else: if is_memview(val): val = val.obj jels = jenv.GetFloatArrayElements(jarr) try: for ix, idx in enumerate(range(start, stop, step)): jels[idx] = val[ix] jenv.ReleaseFloatArrayElements(jarr, jels) except Exception as exc: jenv.ReleaseFloatArrayElements(jarr, jels, jni.JNI_ABORT) raise exc
def str2jchars(val): jbuf = val.encode("utf-16")[jni.sizeof(jni.jchar):] # skip byte-order mark jchars = jni.cast(jni.as_cstr(jbuf), jni.POINTER(jni.jchar)) size = len(jbuf) // jni.sizeof(jni.jchar) return jchars, size, jbuf
def __init__(self, size: int, own: bool = True): self._own = own self.__jvalues = (jni.new_array(jni.jvalue, size) if size > 0 else jni.obj(jni.POINTER(jni.jvalue))) self.__jtypes = [EJavaType.VOID] * max(size, 0)
def releaseFloatBuffer(self, buf: object, mode: Optional[bool] = None): """???.""" with self.jvm as (jvm, jenv): jenv.ReleaseFloatArrayElements(self._jobj, jni.cast(buf, jni.POINTER(jni.jfloat)), 0 if mode is None else jni.JNI_COMMIT if mode else jni.JNI_ABORT)