JuliaInterop / JavaCall.jl

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

Calling java.lang.String constructor doesn't return reference to String object #146

Closed amserra closed 2 years ago

amserra commented 3 years ago

Good afternoon. I've been working on a project with JavaCall and may have stumbled across a bug. Calling the constructor of the wrapper class Integer, I get a reference to the object on variable _intobj, which I can use to call instance methods.

> j_integer = @jimport java.lang.Integer
> int_obj = j_integer((jint, ), Int32(9))
> jcall(int_obj, "floatValue", Float32, ())
> 9.0

However, calling the constructor of class String, this results not in a reference to the String object (as expected), but in the String value itself.

> j_string = @jimport java.lang.String
> str = j_string((JString, ), "foo")
> jcall(str, "trim", JString, ())
> ERROR: LoadError: MethodError: no method matching jcall(::String, ::String, ::Type{JavaCall.JavaObject{Symbol("java.lang.String")}}, ::Tuple{})

I'm running this on a 64-bit Julia version in Mac OS with _JULIA_COPYSTACKS on. I use the code in the documentation to initialize the JVM:

using JavaCall
JavaCall.init(["-Xmx128M"])
mkitti commented 3 years ago

You probably want JString("foo"):

julia> using JavaCall

julia> JavaCall.init()

julia> JString("foo")
JString(JavaCall.JavaLocalRef(Ptr{Nothing} @0x000000000258c710))

julia> jcall(ans, "length", jint, ())
3
mkitti commented 2 years ago

@amserra does the JString("foo") work for you?

amserra commented 2 years ago

It does

mkitti commented 2 years ago

I will close this then. I'll also look into calling jcall directly on String in the future.

@ahnlabb suggested a mechanism here: https://github.com/JuliaInterop/JavaCall.jl/pull/149#issuecomment-887341326