Search code examples
javanashorn

Invoking a Java function taking a char[] input parameter from nashorn (JDK 8 JavaScript engine)?


I want to invoke a Java function taking a char[] input parameter from Oracle's nashorn JavaScript engine (functions with non-array parameter types work ok for me).

If I call the Java function with a JavaScript string literal, nashorn balks

javax.script.ScriptException: TypeError: Can not invoke method
[jdk.internal.dynalink.beans.SimpleDynamicMethod
void org.xml.sax.DocumentHandler.characters(char [],int,int)]
with the passed arguments; they do not match any of its
method signatures.

As you can see I'm trying to invoke a SAX 1 DocumentHandler implemented in Java from JavaScript/nashorn, and of course I'm supplying the int parameters as well.

From http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/ and http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html I get that to convert a JavaScript string into a Java char[] array I have to use code such as the following:

// laboriously converting a string into a Java char array
var text = "bla"
var charArrayType = Java.type("char[]")
var charArray = new charArrayType(text.length)
for (var i = 0; i < text.length; i++)
   charArray[i] = text.charAt(i)

But if I now invoke the Java function using charArray as parameter, I still get the above error message.


Solution

  • I believe there's some other problem with your method call, because your approach works for me:

    var docHandlerType = Java.type("org.xml.sax.HandlerBase");
    var docHandler = new docHandlerType();
    var charArrayType = Java.type("char[]");
    var chars = new charArrayType(2);
    chars[0] = "x".charAt(0);
    chars[1] = "y".charAt(0);
    docHandler.characters(chars, 0, 2);
    print("Successfully called DocumentHandler.characters");
    

    You may have something wrong with the second and third parameters to documentHandler.characters(char[], int, int): have they been omitted, or are their values not integers?

    For what it's worth, you can avoid the laborious character array loop by just using toCharArray() on a normal string literal:

    var docHandlerType = Java.type("org.xml.sax.HandlerBase");
    var docHandler = new docHandlerType();
    docHandler.characters("bla".toCharArray(), 0, 3);
    print("Successfully called DocumentHandler.characters");