Conversation
created init_current_vm function
Adding new conversions to convert.jl
array arg conversion did not work for empty arrays adding JConstructor
need to remove references to JavaObject from proxy.jl
|
|
||
| ## Major TODOs and Caveats | ||
|
|
||
| * Currently, only a low level interface is available, via `jcall`. As a result, this package is best suited for writing libraries that wrap around existing java packages. Writing user code direcly using this interface might be a bit tedious at present. A high level interface using reflection will eventually be built. |
There was a problem hiding this comment.
This section of the documentation should probably be rewritten
src/JavaCall.jl
Outdated
| @jimport, jcall, jfield, isnull, | ||
| getname, getclass, listmethods, getreturntype, getparametertypes, classforname, | ||
| narrow | ||
| narrow, JProxy, @class, interfacehas, staticproxy |
There was a problem hiding this comment.
I'm not sure JProxy is the best name here. Might be worth brainstorming a few alternatives
There was a problem hiding this comment.
Maybe "JavaObject", because you use it like a Java object?
There was a problem hiding this comment.
Yes, that is the most relevant name, the only trouble is that we already have a JavaObject type in JavaCall, so we'll have figure out a transition. However, I think the macro should be called @java.
test/runtests.jl
Outdated
| import Dates | ||
| using Base.GC: gc | ||
|
|
||
| const pxyptr = JavaCall.pxyptr |
There was a problem hiding this comment.
Correct, I had used that in a println in an earlier version of the test code and I forgot to remove it
There was a problem hiding this comment.
These tests will be moved to a separate sub-package.
|
|
||
| location(source) = replace(string(source.file), r"^.*/([^/]*)$" => s"\1") * ":" * string(source.line) * ": " | ||
|
|
||
| macro verbose(args...) |
There was a problem hiding this comment.
These seem debug aids. Are they needed now? In general, we should use the Base logging for output.
There was a problem hiding this comment.
yes, @verbose is just for debugging the project itself and should eventually be removed or commented out. I left some of the logging commented out so I could uncomment it at need (and I did have to uncomment some of them sometimes :) )
| jstr.ptr, buf) | ||
| jstr, buf) | ||
| return s | ||
| end |
There was a problem hiding this comment.
@aviks Could we incorporate the changes to this file convert.jl into JavaCall proper?
There was a problem hiding this comment.
Sure. Is the current code likely a bug?
There was a problem hiding this comment.
I think it was just quoted out of context. What I meant is that most of the changes to convert.jl seem acceptable to merge. It will have to be updated for the new JNI module though.
src/core.jl
Outdated
| jprimitive = Union{jboolean, jchar, jshort, jfloat, jdouble, jint, jlong} | ||
|
|
||
| struct JavaMetaClass{T} | ||
| mutable struct JavaMetaClass{T} |
There was a problem hiding this comment.
Why is it necessary to change this to a mutable struct? I haven't look very hard for the answer, but it might save time if someone could explain it.
There was a problem hiding this comment.
Might it make sense to have mutable and unmutable versions of JavaMetaClass?
There was a problem hiding this comment.
I'll look around -- I'm pretty sure I had a good reason for that. But maybe not :)
There was a problem hiding this comment.
Because the finalizer on line 84 nulls out ptr for safety. If we can guarantee that deleteref will only ever be called from finalize, it can stay immutable I think.
src/jvm.jl
Outdated
| jvm = unsafe_load(pjvm) | ||
| global jvmfunc = unsafe_load(jvm.JNIInvokeInterface_) | ||
| global jnifunc = unsafe_load(jnienv.JNINativeInterface_) #The JNI Function table | ||
| initProxy() |
There was a problem hiding this comment.
We should revert the changes to this file for now.
There was a problem hiding this comment.
Looks like init_current_vm() needs initProxy() as well -- unless you're going to remove that call from _init()
|
|
||
| public String testArrayArgs(Object[] i) { | ||
| return "java.lang.Object[]"; | ||
| } |
There was a problem hiding this comment.
The changes to Test.java and the binaries should be reverted for now and moved into a separate sub-package.
src/convert.jl
Outdated
| convert(::AbstractString, str::Type{JString}) = unsafe_string(str) | ||
| convert(::Type{JString}, str::AbstractString) = JString(str) | ||
| convert(::Type{JObject}, str::AbstractString) = convert(JObject, JString(str)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Double")}}, n::Real) = jnew(Symbol("java.lang.Double"), (jdouble,), Float64(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Float")}}, n::Real) = jnew(Symbol("java.lang.Float"), (jfloat,), Float32(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Long")}}, n::Real) = jnew(Symbol("java.lang.Long"), (jlong,), Int64(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Integer")}}, n::Real) = jnew(Symbol("java.lang.Integer"), (jint,), Int32(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Short")}}, n::Real) = jnew(Symbol("java.lang.Short"), (jshort,), Int16(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Byte")}}, n::Real) = jnew(Symbol("java.lang.Byte"), (jbyte,), Int8(n)) | ||
| convert(::Type{JavaObject{Symbol("java.lang.Character")}}, n::Real) = jnew(Symbol("java.lang.Character"), (jchar,), Char(n)) | ||
| convert(::Type{JavaObject{:int}}, n) = convert(jint, n) | ||
| convert(::Type{JavaObject{:long}}, n) = convert(jlong, n) | ||
| convert(::Type{JavaObject{:byte}}, n) = convert(jbyte, n) | ||
| convert(::Type{JavaObject{:boolean}}, n) = convert(jboolean, n) | ||
| convert(::Type{JavaObject{:char}}, n) = convert(jchar, n) | ||
| convert(::Type{JavaObject{:short}}, n) = convert(jshort, n) | ||
| convert(::Type{JavaObject{:float}}, n) = convert(jfloat, n) | ||
| convert(::Type{JavaObject{:double}}, n) = convert(jdouble, n) | ||
| convert(::Type{JavaObject{:void}}, n) = convert(jvoid, n) | ||
| convert(::Type{JavaObject{T}}, ::Nothing) where T = jnull |
There was a problem hiding this comment.
These convert methods seem fine to merge.
| function convert(::Type{JavaObject{T}}, obj::JavaObject{S}) where {T,S} | ||
| if isConvertible(T, S) #Safe static cast | ||
| ptr = ccall(jnifunc.NewLocalRef, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) | ||
| ptr === C_NULL && geterror() | ||
| return JavaObject{T}(ptr) | ||
| if isnull(obj) | ||
| return JavaObject{T}(obj.ptr) | ||
| elseif isConvertible(T, S) #Safe static cast | ||
| return JavaObject{T}(obj.ptr) | ||
| end | ||
| isnull(obj) && throw(ArgumentError("Cannot convert NULL")) | ||
| realClass = ccall(jnifunc.GetObjectClass, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing} ), penv, obj.ptr) | ||
| if isConvertible(T, realClass) #dynamic cast | ||
| ptr = ccall(jnifunc.NewLocalRef, Ptr{Nothing}, (Ptr{JNIEnv}, Ptr{Nothing}), penv, obj.ptr) | ||
| ptr === C_NULL && geterror() | ||
| return JavaObject{T}(ptr) | ||
| return JavaObject{T}(obj.ptr) | ||
| end | ||
| throw(JavaCallError("Cannot cast java object from $S to $T")) | ||
| end |
There was a problem hiding this comment.
This allows for null objects. We could probably merge this.
src/core.jl
Outdated
| const JString = JavaObject{Symbol("java.lang.String")} | ||
| const jnull = JavaObject(nothing) | ||
|
|
||
| JavaObject(ptr::Ptr{Nothing}) = ptr == C_NULL ? JavaObject(ptr) : JavaObject{Symbol(getclassname(getclass(ptr)))}(ptr) |
There was a problem hiding this comment.
This depends on functions in proxy.jl at the moment, so we will probably move it into proxy.jl
|
Folks, do you need any more information from me in order to tie this off? |
|
Hi @zot, thanks for checking in. JavaCall has undergone some major structural changes since a few weeks ago, so this will need to be updated again. Next on my list is to improve JavaCall's local/global reference management. However, I think the reorganization will make things much more manageable moving forward. For example, all the Do we have your permission to continue developing this? My plan remains making this a separate package which has JavaCall as a dependency. |
Of course! JavaCall belongs to you guys -- I wrote the proxy code in order to contribute to the project. Use and modify it as you see fit, I'd just like to see it merged in one form or another... |
|
@zot , @aviks I split the proxy code off into its own
The easiest way I found to load |
JProxies/doc/index.md
Outdated
| * Create static proxies to access static members | ||
| Primitive types and strings are converted to Julia objects on field accesses and method returns and converted back to Java types when sent as arguments to Java methods. | ||
| *NOTE: Because of this, if you need to call Java methods on a string that you got from Java, you'll have to use `JProxy(str)` to convert the Julia string to a proxied Java string* | ||
| To invoke static methods, set static to true (see below). |
There was a problem hiding this comment.
I wrote this before I added the @class macro -- I think it should change to this:
To invoke static methods, use @class (see below).
JProxies/doc/index.md
Outdated
| julia> JProxy(@jimport(java.lang.System)).getName() | ||
| "java.lang.System" | ||
|
|
||
| julia> JProxy(@jimport(java.lang.System);static=true).out.println("hello") |
There was a problem hiding this comment.
I'd change this to
julia> @class(java.lang.System).out.println("hello")
|
Can we just make this a submodule for the JavaCall module, so doing |
We could do that although the direction I was heading in was to spin it out so that it can live as its own package. Currently, you could import using JProxies
JProxies.init()Under the hood that will still use JavaCall. You made a point once that there was a lot of the proxy code to support which could make future maintenance more difficult. Dividing the code clearly like this is beneficial for maintainability I think. There is still some code I actually want to move into JavaCall itself. For example, |
That sounds like a good direction to me. That way people who just want to use JavaCall don't need to load in JProxy and people who want JProxy don't need to worry about JavaCall.
Yes, I wrote some useful utility code that could move into JavaCall but I wanted to keep my changes to the base package to a minimum so I kept as much as I could in proxy.jl. |
|
Is this dying on the vine? |
|
Most of the changes to core JavaCall were merged in b5692cc a few months ago. We're preparing for a JavaCall 0.8 release. Taro just set compatibility with 0.8. It looks like we have conflicts to fix here. The |
|
Add a JProxy subpackage |
I have updated the
JProxycode from @zot from PR #91 . Tests are now passing and there are no conflicts.