def getStackTraceString(self) -> Optional[str]: """Returns this throwable and its backtrace information as string printed by printStackTrace(). """ with self.jvm as (jvm, jenv): try: if jvm is None or jenv is None or not self._jobj: return None with JFrame(jenv, 3): stringWriter = jenv.NewObject(jvm.StringWriter.Class, jvm.StringWriter.Constructor) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = stringWriter printWriter = jenv.NewObject(jvm.PrintWriter.Class, jvm.PrintWriter.Constructor, jargs) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = printWriter jenv.CallVoidMethod(self._jobj, jvm.Throwable.printStackTrace, jargs) jenv.CallVoidMethod(printWriter, jvm.PrintWriter.flush) jstr = jenv.CallObjectMethod(stringWriter, jvm.Object.toString) return JString(jenv, jstr, own=False).str if jstr else None except jni.Throwable as exc: JException.__handle_unexpected(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 setContextClassLoader(self, jcloader: Optional[JClassLoader]): with self.jvm as (jvm, jenv): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jcloader.handle if jcloader is not None else jni.NULL jenv.CallVoidMethod(self._jobj, jvm.Thread.setContextClassLoader, jargs)
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 newFloat(cls, val: float) -> Optional['JObject']: with cls.jvm as (jvm, jenv), JFrame(jenv, 1): jval = jni.new_array(jni.jvalue, 1) jval[0].f = val jobj = jenv.CallStaticObjectMethod(jvm.Float.Class, jvm.Float.valueOf, jval) return cls.jvm.JObject(jenv, jobj) if jobj else None
def newCharacter(cls, val: str) -> Optional['JObject']: with cls.jvm as (jvm, jenv), JFrame(jenv, 1): jval = jni.new_array(jni.jvalue, 1) jval[0].c = val[0] jobj = jenv.CallStaticObjectMethod(jvm.Character.Class, jvm.Character.valueOf, jval) return cls.jvm.JObject(jenv, jobj) if jobj else None
def newBoolean(cls, val: bool) -> Optional['JObject']: with cls.jvm as (jvm, jenv), JFrame(jenv, 1): jval = jni.new_array(jni.jvalue, 1) jval[0].z = val jobj = jenv.CallStaticObjectMethod(jvm.Boolean.Class, jvm.Boolean.valueOf, jval) return cls.jvm.JObject(jenv, jobj) if jobj else None
def isProtected(cls, modif: int) -> bool: """Return True if the integer argument includes the protected modifier, False otherwise.""" with cls.jvm as (jvm, jenv): jmod = jni.new_array(jni.jvalue, 1) jmod[0].i = modif return jenv.CallStaticBooleanMethod(jvm.Modifier.Class, jvm.Modifier.isProtected, jmod)
def asSubclass(self, jcls: 'JClass') -> 'JClass': with self.jvm as (jvm, jenv), JFrame(jenv, 1): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jcls.handle jccls = jenv.CallObjectMethod(self._jobj, jvm.Class.asSubclass, jargs) return self.jvm.JClass(jenv, jccls)
def getField(self, name: str) -> 'JField': with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jfld = jenv.CallObjectMethod(self._jobj, jvm.Class.getField, jargs) return self.jvm.JField(jenv, jfld)
def registerReference(self, source: 'JObject', target: object): with self.jvm as (jvm, jenv), JFrame(jenv, 1): jargs = jni.new_array(jni.jvalue, 2) jargs[0].l = source.handle jargs[1].j = id(target) jenv.CallObjectMethod(self._jobj, jvm.jt_ref_ReferenceQueue.registerReference, jargs)
def asSubclass(self, jcls: 'JClass') -> 'JClass': """Casts this Class object to represent a subclass of the class represented by the specified class object. """ with self.jvm as (jvm, jenv), JFrame(jenv, 1): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jcls.handle jccls = jenv.CallObjectMethod(self._jobj, jvm.Class.asSubclass, jargs) return self.jvm.JClass(jenv, jccls)
def findLoadedClass(self, name: str) -> Optional[JClass]: with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jcls = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.findLoadedClass, jargs) return self.jvm.JClass(jenv, jcls) if jcls else None
def getPackage(cls, name: str) -> Optional['JPackage']: with cls.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jpkg = jenv.CallStaticObjectMethod(jvm.Package.Class, jvm.Package.getPackage, jargs) return cls.jvm.JPackage(jenv, jpkg) if jpkg else None
def newProxy(self, delegate: object) -> Optional[JObject]: with self.jvm as (jvm, jenv), JFrame(jenv, 4): jargs = jni.new_array(jni.jvalue, 1) jargs[0].j = id(delegate) ihandler = jenv.NewObject(jvm.jt_reflect_ProxyHandler.Class, jvm.jt_reflect_ProxyHandler.Constructor, jargs) ihclass = jenv.CallObjectMethod( ihandler, jvm.jt_reflect_ProxyHandler.getClass) cloader = jenv.CallObjectMethod(ihclass, jvm.Class.getClassLoader) jargs = jni.new_array(jni.jvalue, 3) jargs[0].l = cloader jargs[1].l = self._jitf_array jargs[2].l = ihandler jproxy = jenv.CallStaticObjectMethod(jvm.Proxy.Class, jvm.Proxy.newProxyInstance, jargs) return self.jvm.JObject(jenv, jproxy) if jproxy else None
def getPackage(self, name: str) -> Optional[JPackage]: """Returns a Package that has been defined by this class loader or any of its ancestors.""" with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jpkg = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.getPackage, jargs) return self.jvm.JPackage(jenv, jpkg) if jpkg else None
def findClass(self, name: str) -> JClass: """Finds the class with the specified binary name.""" with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jcls = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.findClass, jargs) return self.jvm.JClass(jenv, jcls)
def findLibrary(self, libname: str) -> Optional[str]: """Returns the absolute path name of a native library.""" with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(libname) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jpath = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.findLibrary, jargs) return JString(jenv, jpath, own=False).str if jpath else None
def getField(self, name: str) -> 'JField': """Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object. """ with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jfld = jenv.CallObjectMethod(self._jobj, jvm.Class.getField, jargs) return self.jvm.JField(jenv, jfld)
def __init__(self, jvm, jenv: jni.JNIEnv, modif: int): Modif = jvm.Modifier jcls = Modif.Class jmod = jni.new_array(jni.jvalue, 1) jmod[0].i = modif self.isPublic = jenv.CallStaticBooleanMethod(jcls, Modif.isPublic, jmod) self.isProtected = jenv.CallStaticBooleanMethod(jcls, Modif.isProtected, jmod) self.isPrivate = jenv.CallStaticBooleanMethod(jcls, Modif.isPrivate, jmod) self.isFinal = jenv.CallStaticBooleanMethod(jcls, Modif.isFinal, jmod) self.isStatic = jenv.CallStaticBooleanMethod(jcls, Modif.isStatic, jmod) self.isAbstract = jenv.CallStaticBooleanMethod(jcls, Modif.isAbstract, jmod) self.modif = modif
def loadClass(self, name: str) -> JClass: """Loads the class with the specified binary name. This method searches for classes in the same manner as the loadClass(String, boolean) method. It is invoked by the Java virtual machine to resolve class references. Invoking this method is equivalent to invoking loadClass(name, false).""" with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jcls = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.loadClass, jargs) return self.jvm.JClass(jenv, jcls)
def findLoadedClass(self, name: str) -> Optional[JClass]: """Returns the class with the given binary name if this loader has been recorded by the Java virtual machine as an initiating loader of a class with that binary name. """ with self.jvm as (jvm, jenv), JFrame(jenv, 2): jchars, size, jbuf = str2jchars(name) jname = jenv.NewString(jchars, size) jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = jname jcls = jenv.CallObjectMethod(self._jobj, jvm.ClassLoader.findLoadedClass, jargs) return self.jvm.JClass(jenv, jcls) if jcls else None
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 getPropertyDescriptors(self) -> Tuple['JPropertyDescriptor', ...]: with self.jvm as (jvm, jenv), JFrame(jenv, 2): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = self._jobj jbeanInfo = jenv.CallStaticObjectMethod(jvm.Introspector.Class, jvm.Introspector.getBeanInfo, jargs) jarr = jni.cast(jenv.CallObjectMethod(jbeanInfo, jvm.BeanInfo.getPropertyDescriptors), jni.jobjectArray) jlen = jenv.GetArrayLength(jarr) with JFrame(jenv, jlen): return tuple(self.jvm.JPropertyDescriptor(jenv, jenv.GetObjectArrayElement(jarr, idx)) for idx in range(jlen))
def registerNatives(jenv: jni.JNIEnv, class_name: str, native_methods: Sequence[Callable]): if inspect.ismodule(native_methods) or inspect.isclass(native_methods): native_methods = getattr(native_methods, "__jnimethods__", ()) else: if native_methods is None: native_methods = () jenv.PushLocalFrame(1) try: jcls = jenv.FindClass(class_name.replace(".", "/").encode("utf-8")) 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 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 equals(self, other) -> bool: """Indicates whether some other object is "equal to" this one.""" if self is other: return True if not isinstance(other, JObjectBase): return False self_handle = self._jobj other_handle = other.handle if self_handle == other_handle: return True # pragma: no cover with self.jvm as (jvm, jenv): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = other_handle return (jenv.IsSameObject(self_handle, other_handle) or jenv.CallBooleanMethod(self_handle, jvm.Object.equals, jargs))
def equals(self, other) -> bool: if self is other: return True if not isinstance(other, (JObjectBase, JAnnotation)): return False self_handle = self._jobj other_handle = other.handle if self_handle == other_handle: return True # pragma: no cover with self.jvm as (jvm, jenv): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = other_handle return (jenv.IsSameObject(self_handle, other_handle) or jenv.CallBooleanMethod(self_handle, jvm.Annotation.equals, jargs))
def equals(self, other) -> bool: """Returns true if the specified object represents an annotation that is logically equivalent to this one. """ if self is other: return True if not isinstance(other, (JObjectBase, JAnnotation)): return False self_handle = self._jobj other_handle = other.handle if self_handle == other_handle: return True # pragma: no cover with self.jvm as (jvm, jenv): jargs = jni.new_array(jni.jvalue, 1) jargs[0].l = other_handle return (jenv.IsSameObject(self_handle, other_handle) or jenv.CallBooleanMethod(self_handle, jvm.Annotation.equals, jargs))