JuliaInterop / JavaCall.jl

Call Java from Julia
http://juliainterop.github.io/JavaCall.jl
Other
118 stars 53 forks source link

Independent JNI #120

Closed mkitti closed 4 years ago

mkitti commented 4 years ago

This is a follow up to creating the JNI module. Here we the JNI initialization code into JNI itself as well as the associated globals. Further those globals are now converted to type associated Ref. Additionally the Julia interface is also simplified since penv no longer needs to be passed

aviks commented 4 years ago

Did appveyor take out Java from their images?

mkitti commented 4 years ago

Its my commit somehow. The master branch still passes when I rerun it. https://ci.appveyor.com/project/aviks/javacall-jl-6c24s

mkitti commented 4 years ago

@aviks I fixed the appveyor issues.

Since I moved a lot of the low level functionality into the JNI submodule, I moved the Libdl import there as well. On Windows, mscrvt100.dll also needed to be loaded and that was causing the initial appveyor issues.

On further investigation into the appveyor configuration, I found that even when using the x86 platform, Julia was still trying to load the x64 JVM. By setting JAVA_HOME explicitly to the x86 JVM, and then fooling around with globals, I managed to get x86 init to work via 078278e. I don't know why that makes a difference.

mkitti commented 4 years ago

@aviks I intend to merge this this week.

mkitti commented 4 years ago

@aviks The problem with Base.@deprecated_binding is that it declares a const at compile time for jnifunc which will be invalid. We could try to update it at runtime, but then this issues a warning about redefining a const.

I've left the deprecation warning, but trying to use jnifunc will fail now.

mkitti commented 4 years ago

To summarize the net changes:

  1. Library loading and core JVM initialization, and destroy are moved into the JNI module. This means __init__() no longer loads the dynamic library. This is entirely done on init()
  2. penv is no longer a global in JavaCall and passed by default to ccall. All JNI calls from JavaCall do not require a JNIEnv pointer to be passed since that is handled entirely within JNI module now. penv can still be passed in as a named argument.
  3. JavaCall.findjvm() just returns a tuple of Strings describing the library or libraries to load rather than setting a global.
  4. Tests no longer use ccall directly but now refer to the wrapped versions in the JNI module.

As a side effect and for unknown reasons, JavaCall.init() and some functions now work on x86 Windows. This is somehow related to storing jnienv as a global.

mkitti commented 4 years ago

Thanks for the review, @aviks . Merging now.