mirror of https://github.com/kivy/pyjnius.git
Add control of JVM startup options
This commit is contained in:
parent
19d4ddc45d
commit
2910e2fddc
|
@ -327,3 +327,19 @@ example::
|
|||
Signature: ()V
|
||||
}
|
||||
|
||||
|
||||
JVM options and the class path
|
||||
------------------------------
|
||||
|
||||
JVM options need to be set before `import jnius` is called, as they cannot be changed after the VM starts up.
|
||||
To this end, you can::
|
||||
|
||||
import jnius_config
|
||||
jnius_config.add_options('-Xrs', '-Xmx4096')
|
||||
jnius_config.set_classpath('.', '/usr/local/fem/plugins/*')
|
||||
import jnius
|
||||
|
||||
If a classpath is set with these functions, it overrides any CLASSPATH environment variable.
|
||||
Multiple options or path entries should be supplied as multiple arguments to the `add_` and `set_` functions.
|
||||
If no classpath is provided and CLASSPATH is not set, the path defaults to `'.'`.
|
||||
This functionality is not available on Android.
|
||||
|
|
|
@ -4,11 +4,13 @@ cdef JNIEnv *default_env = NULL
|
|||
cdef extern int gettid()
|
||||
cdef JavaVM *jvm = NULL
|
||||
|
||||
cdef JNIEnv *get_jnienv():
|
||||
cdef JNIEnv *get_jnienv() except NULL:
|
||||
global default_env
|
||||
# first call, init.
|
||||
if default_env == NULL:
|
||||
default_env = get_platform_jnienv()
|
||||
if default_env == NULL:
|
||||
return NULL
|
||||
default_env[0].GetJavaVM(default_env, &jvm)
|
||||
|
||||
# return the current env attached to the thread
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
cdef extern jint __stdcall JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args)
|
||||
cdef extern from "jni.h":
|
||||
int JNI_VERSION_1_4
|
||||
int JNI_OK
|
||||
jboolean JNI_FALSE
|
||||
ctypedef struct JavaVMInitArgs:
|
||||
jint version
|
||||
|
@ -16,52 +17,36 @@ cdef extern from "jni.h":
|
|||
|
||||
cdef JNIEnv *_platform_default_env = NULL
|
||||
|
||||
def classpath():
|
||||
import platform
|
||||
from glob import glob
|
||||
from os import environ
|
||||
from os.path import realpath, dirname, join
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
split_char = ';'
|
||||
else:
|
||||
split_char = ':'
|
||||
|
||||
paths = [realpath('.'), join(dirname(__file__), 'src'), ]
|
||||
if 'CLASSPATH' not in environ:
|
||||
return split_char.join(paths)
|
||||
|
||||
cp = environ.get('CLASSPATH')
|
||||
pre_paths = paths + cp.split(split_char)
|
||||
# deal with wildcards
|
||||
for path in pre_paths:
|
||||
if not path.endswith('*'):
|
||||
paths.append(path)
|
||||
else:
|
||||
paths.extend(glob(path + '.jar'))
|
||||
paths.extend(glob(path + '.JAR'))
|
||||
result = split_char.join(paths)
|
||||
return result
|
||||
|
||||
cdef void create_jnienv():
|
||||
cdef void create_jnienv() except *:
|
||||
cdef JavaVM* jvm
|
||||
cdef JavaVMInitArgs args
|
||||
cdef JavaVMOption options[1]
|
||||
cdef JavaVMOption *options
|
||||
cdef int ret
|
||||
cdef bytes py_bytes
|
||||
import jnius_config
|
||||
|
||||
cp = classpath()
|
||||
py_bytes = <bytes>('-Djava.class.path={0}'.format(cp))
|
||||
options[0].optionString = py_bytes
|
||||
options[0].extraInfo = NULL
|
||||
optarr = jnius_config.options
|
||||
optarr.append("-Djava.class.path=" + jnius_config.expand_classpath())
|
||||
|
||||
options = <JavaVMOption*>malloc(sizeof(JavaVMOption) * len(optarr))
|
||||
for i, opt in enumerate(optarr):
|
||||
options[i].optionString = <bytes>(opt)
|
||||
options[i].extraInfo = NULL
|
||||
|
||||
args.version = JNI_VERSION_1_4
|
||||
args.options = options
|
||||
args.nOptions = 1
|
||||
args.nOptions = len(optarr)
|
||||
args.ignoreUnrecognized = JNI_FALSE
|
||||
|
||||
JNI_CreateJavaVM(&jvm, <void **>&_platform_default_env, &args)
|
||||
ret = JNI_CreateJavaVM(&jvm, <void **>&_platform_default_env, &args)
|
||||
free(options)
|
||||
|
||||
cdef JNIEnv *get_platform_jnienv():
|
||||
if ret != JNI_OK:
|
||||
raise SystemError("JVM failed to start")
|
||||
|
||||
jnius_config.vm_running = True
|
||||
|
||||
cdef JNIEnv *get_platform_jnienv() except NULL:
|
||||
if _platform_default_env == NULL:
|
||||
create_jnienv()
|
||||
return _platform_default_env
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
__all__ = ('set_options', 'add_options', 'get_options',
|
||||
'set_classpath', 'add_classpath', 'get_classpath',
|
||||
'expand_classpath')
|
||||
|
||||
import platform
|
||||
if platform.system() == 'Windows':
|
||||
split_char = ';'
|
||||
else:
|
||||
split_char = ':'
|
||||
|
||||
vm_running = False
|
||||
options = []
|
||||
classpath = None
|
||||
|
||||
def set_options(*opts):
|
||||
"Sets the list of options to the JVM. Removes any previously set options."
|
||||
if vm_running:
|
||||
raise ValueError("VM is already running, can't set options")
|
||||
globals()['options'] = opts
|
||||
|
||||
def add_options(*opts):
|
||||
"Appends options to the list of VM options."
|
||||
if vm_running:
|
||||
raise ValueError("VM is already running, can't set options")
|
||||
global options
|
||||
options.extend(opts)
|
||||
|
||||
def get_options():
|
||||
"Retrieves the current list of VM options."
|
||||
global options
|
||||
return list(options)
|
||||
|
||||
|
||||
def set_classpath(*path):
|
||||
"""
|
||||
Sets the classpath for the JVM to use. Replaces any existing classpath, overriding the CLASSPATH environment variable.
|
||||
"""
|
||||
if vm_running:
|
||||
raise ValueError("VM is already running, can't set classpath")
|
||||
global classpath
|
||||
classpath = path
|
||||
|
||||
def add_classpath(*path):
|
||||
"""
|
||||
Appends items to the classpath for the JVM to use.
|
||||
Replaces any existing classpath, overriding the CLASSPATH environment variable.
|
||||
"""
|
||||
if vm_running:
|
||||
raise ValueError("VM is already running, can't set classpath")
|
||||
global classpath
|
||||
if classpath is None:
|
||||
classpath = list(path)
|
||||
else:
|
||||
classpath.extend(path)
|
||||
|
||||
def get_classpath():
|
||||
"Retrieves the classpath the JVM will use."
|
||||
from os import environ
|
||||
from os.path import realpath
|
||||
global classpath
|
||||
|
||||
if classpath is not None:
|
||||
return list(classpath)
|
||||
|
||||
if 'CLASSPATH' in environ:
|
||||
return environ['CLASSPATH'].split(split_char)
|
||||
|
||||
return [realpath('.')]
|
||||
|
||||
def expand_classpath():
|
||||
from glob import glob
|
||||
paths = []
|
||||
# deal with wildcards
|
||||
for path in get_classpath():
|
||||
if not path.endswith('*'):
|
||||
paths.append(path)
|
||||
else:
|
||||
paths.extend(glob(path + '.[Jj][Aa][Rr]'))
|
||||
return split_char.join(paths)
|
Loading…
Reference in New Issue