Correct.
Act on doc::Annotation using CoreMap’s “get” method to obtain a List called, e.g., sentences.
Not quite. Let’s break it down.
// Java
document.get(...)
Here we call method get of object document which has type Annotation in Java. In Julia we have a handle to such an object in doc.jann and its type, again in our Julia application, is JAnnotation (while Julia’s Annotation is a wrapper around this handle). In other words:
struct Annotation # <-- this is a Julia wrapper
jann::JAnnotation # <-- this is the handle to Java object or type edu.stanford.nlp.pipeline.Annotation
# which we aliased in Julia as JAnnotation
end
So the basic call should be:
jcall(
doc.jann, # <-- handle to Java object
"get", # <-- method name
..., # return type, ignore for now,
(...), # argument types
... # actual arguments
)
Note, that get is a method inherited from ArrayCoreMap and is defined here. It has signature:
<VALUE> VALUE get(Class<? extends Key<VALUE>> key)
Whoa! Looks unreadable for non-Java people, right? Let’s further break it down:
<VALUE> is a type parameter, similar to <typename VALUE> in C++ templates or ... where VALUE in Julia
VALUE means that we return this exact type
Class<VALUE> (I simplified a bit) means that get takes a single argument of Java type Class<VALUE>
We pass SentencesAnnotation.class to this get which is a value of type Class<SentencesAnnotation>. From it we can infer that VALUE in this case is SentencesAnnotation! Method signature thus is:
SentencesAnnotation get(Class<SentencesAnnotation> key)
It’s interesting to note that SentencesAnnotation actually implements interface List<CoreMap> which we see as a return type in Java code:
List<CoreMap> sentences = document.get(SentencesAnnotation.class)
Ok, we understood what it all means in Java, but how should it look like in Julia? It’s a bit more tricky question that boils down to:
- what signature this method has in JVM itself (because type parameters don’t actually exist after compilation)
- how to specify type of
Class<SentencesAnnotation> since JavaCall doesn’t support generics too
To answer these questions I need to inspect JAnnotation object that I can’t do right now. Would you mind running the following for me?
JavaCall.listmethods(doc.jann, "get")
And while I wait for the result of the previous code I will address your questions (3) and (4) (I hope previous explanation shed some light on questions (1) and (2)).
How to distinguish between document.get, sentence.get, etc in the jcall?
As simple as
jcall(jann, ...)
jcall(jsentence, ...)
# etc.
The first argument is always an object you call method on. Literally, obj.method(...) is translated into jcall(jobj, "method", ...).
How to construct the jcall so that it accepts a List< CoreMap > in return?
It depends on the actual method signature in JVM. The tricky part is that what you see in Java code doesn’t always correspond one-to-one to what is really created in JVM. As I mentioned earlier, JVM knows nothing about type parameters, so definitely there’s no information about CoreMap in there. Moreover, there may be nothing about List in JVMs signature for that method, but instead any interface that extends List or any class that implements it.
It’s not the easiest part of working with JVM. Fortunately, it’s actually rarely needed to dive so deep - as you will see soon, most of the time you just construct objects and call jcall on clear method signature from Java docs.