Open DrChainsaw opened 3 years ago
Did you set the environmental variable JULIA_COPY_STACKS=1
?
Oh, you're on Windows... hmm.
Also we may need to do something with AttachCurrentThread
: https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html
I'm going to drop some hints here. Essentially to get this to work, you'll have to tap the lower level JNI interface in JavaCall: JavaCall.JNI
.
using JavaCall
JavaCall.init()
# The following is a pointer to the AttachCurrentThread function of the JVM. Use ccall or @ccall to call that.
JavaCall.JNI.jvmfunc[].AttachCurrentThread
The C definition of that is
jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);
The call to that is going to look a lot like https://github.com/JuliaInterop/JavaCall.jl/blob/master/src/JNI.jl#L145-L146
So something like:
using JavaCall.JNI
import JavaCall.JNI: JavaVMInitArgs
ppenv_this_thread = Ref(Ptr{JNIEnv}(C_NULL))
ppjvm = JavaCall.JNI.ppjvm
res < 0 && throw(JavaCall.JNI.JNIError("Unable to initialise Java VM: $(res)"))
JavaCall.JNI.ppenv[] = ppenv_this_thread[]
When using JavaCall from a new thread:
empty!(JavaCall._jmc_cache) # You might need to do @jimport anew
JavaCall.JNI.ppenv[] = ppenv_this_thread[]
There are synchronization issues there. The real solution is to to figure out the new thread specific ppenv
into the individual JNI calls:
GetVersion(penv=ppenv[]) =
ccall(jniref[].GetVersion, jint, (Ptr{JNIEnv},), penv)
DefineClass(name::AnyString, loader::jobject_arg, buf::Array{jbyte,1}, len::Integer, penv=ppenv[]) =
ccall(jniref[].DefineClass, jclass, (Ptr{JNIEnv}, Cstring, jobject, Ptr{jbyte}, jsize,), penv, name, loader, buf, len)
[...]
I started an experimental branch to push multithreading forwards on Linux / MacOS: https://github.com/JuliaInterop/JavaCall.jl/tree/multithreading
Trying to run jcall in a separate thread kills the julia session: