JuliaInterop / JuliaInterop/JavaCall.jl

Proposal: jdcall and jtypeforclass

Open
#93 12 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Julia
Stars
125
Forks
53
PR merge metrics
No merged PRs in 30d

Description

  1. Now the get class for name is compatible with Array and primitive types

https://github.com/JuliaInterop/JavaCall.jl/blob/d6c3678d3a93fae903fb3ab1cb1ea7ea1fc91f92/src/convert.jl#L321-L325
https://github.com/JuliaInterop/JavaCall.jl/blob/d6c3678d3a93fae903fb3ab1cb1ea7ea1fc91f92/src/reflect.jl#L163-L168
This method may help

function jtypeforclass(cls::JClass)
    isarray(cls) = jcall(cls, "isArray", jboolean, ()) != 0x00
    if isarray(cls)
        jcomponentcls = jcall(cls, "getComponentType", JClass, ())
        return Array{jtypeforclass(jcomponentcls), 1}
    end
    name = getname(cls)
    if name == "void"
        Nothing
    elseif name == "boolean"
        jboolean
    elseif name == "char"
        jchar
    elseif name == "short"
        jshort
    elseif name == "float"
        jfloat
    elseif name == "double"
        jdouble
    elseif name == "int"
        jint
    elseif name == "long"
        jlong
    else
        JavaObject{Symbol(name)}
    end
end

and the narrow would be

function narrow(obj::JavaObject)
    c = jcall(obj,"getClass", JClass, ())
    return convert(jtypeforclass(c), obj)
end
narrow(obj::JavaCall.jprimitive) = obj
  1. And it would be possible to call functions without specific return type and argument type
convertible(javatype::Type, juliatype::Type) = hasmethod(convert, Tuple{Type{javatype}, juliatype})

function findmethod(obj::Union{JavaObject{C}, Type{JavaObject{C}}}, name::AbstractString, args...) where C
    allmethods = listmethods(obj, name)
    filter(allmethods) do m
        params = getparametertypes(m)
        if length(params) != length(args)
            return false
        end
        all([convertible(jtypeforclass(c), typeof(a)) for (c, a) in zip(getparametertypes(m), args)])
    end
end

function jdcall(obj::Union{JavaObject{C}, Type{JavaObject{C}}}, name::AbstractString, args...) where C
    matchmethods = findmethod(obj, name, args...)
    if length(matchmethods) == 0
        allmethods = listmethods(obj, name)
        candidates = join(allmethods, "\n  ")
        error("no match methods $name for $obj, candidates are:\n  $candidates")
    elseif length(matchmethods) > 1
        candidates = join(matchmethods, "\n  ")
        error("multiple methods $name for $obj, candidates are:\n  $candidates")
    end
    matchmethod = matchmethods[1]
    rettype = jtypeforclass(getreturntype(matchmethod))
    argstype = tuple(map(jtypeforclass, getparametertypes(matchmethod))...)
    # println("type: $rettype ($argstype)")
    return jcall(obj, name, rettype, argstype, args...)
end

Since narrow and classforname are both exported, so this may be a breaking change, although I think the behavior of the two methods now is strange when it comes to array and/or jint.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the referenced sections of src/convert.jl and src/reflect.jl, along with the exported narrow and classforname entry points. Define and validate the intended array and primitive conversions, inferred return and argument types, overload matching, and compatibility impact before implementing jdcall and jtypeforclass.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, julia
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.