Optimistic Typing in Nashorn

in #javascript6 years ago (edited)

I have a bunch of programs written in JavaScript for Nashorn, the fast JavaScript engine shipped with JDK 8 and later. Since I had been working on a NodeJS project for the last couple of months, I hadn't used these programs in the last month or so.

Today I was running a simple program to do some automatic changes on a big HTML file, when I encountered a java.lang.invoke.WrongMethodTypeException error. The error was triggered by a part of the program that was trying to copy a string into the clipboard.

Here is a sample program to explore this issue:

    (function () {
        try {
            var cb = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard();
            var textPlain = "Hello world!";
            var textHtml = "<html><h1>" + textPlain + "</h1></html>";
            var items = [{
                    data: textPlain,
                    dataFlavor: new java.awt.datatransfer.DataFlavor("text/plain;class=java.lang.String"),
                }, {
                    data: textHtml,
                    dataFlavor: new java.awt.datatransfer.DataFlavor("text/html;class=java.lang.String"),
                },
            ];
            let owner = new java.awt.datatransfer.ClipboardOwner({
                    lostOwnership: function (clipboard, contents) {
                        print("OK. Lost ownership...");
                    },
                });
            let contents = new java.awt.datatransfer.Transferable({
                    getTransferData: function (dataFlavor) {
                        var item;
                        items.some(function (itm) {
                            if (itm.dataFlavor.equals(dataFlavor)) {
                                item = itm;
                                return true;
                            }
                        });
                        if (!item) {
                            throw new java.awt.datatransfer.UnsupportedFlavorException(dataFlavor);
                        }
                        return item.data;
                    },
                    getTransferDataFlavors: function () {
                        return items.map(function (item) {
                            return item.dataFlavor;
                        });
                    },
                    isDataFlavorSupported: function (dataFlavor) {
                        return items.some(function (item) {
                            return item.dataFlavor.equals(dataFlavor);
                        });
                    }
                });
            cb.setContents(contents, owner);
        } catch (e) {
            print(e);
        }
    })();

This program tries to copy a string (in text/plain and text/html flavors) into the clipboard.

The program (assuming it is saved in a file called program.js) should be run with a command like this:

    java jdk.nashorn.tools.Shell --language=es6 program.js --

This program would have executed perfectly a few months ago, but since I recently updated my Java instance to version 9.0.1 (and now to 9.0.4), it produces the following error:

    java.lang.invoke.WrongMethodTypeException: cannot convert MethodHandle(ScriptFunction,Object)int to (ScriptFunction,Object)DataFlavor[]

I have not included the stack trace here, but the problem seems to be in the getTransferDataFlavors method. The method should return DataFlavor[] but Nashorn thinks it returns int.

I looked around in Google and found this thread from Dec. 2017 on nashorn-dev mailing list that mentioned a similar problem.

It turns out the problem has started because of Optimistic Typing in Nashorn, which has been implemented to boost execution speed in Nashorn. Apparently, Nashorn makes assumptions about specific types in methods. In this case, the engine assumes that a method returns int, while in fact it should return DataFlavor[].

For the time being, (as advised in the above-mentioned thread) I could work around this problem by turning off optimistic typing. Here is the command:

    java -Dnashorn.args=-ot=false jdk.nashorn.tools.Shell --language=es6 program.js --

With this flag (-Dnashorn.args=-ot=false), the program runs perfectly and the strings are copied into the clipboard.

There are various ways for implementing Java interfaces in Nashorn code. I tried all of them (using JavaAdapter which was actually introduced in Rhino and is also offered for Nashorn and also using Java.extend). In all cases, however, this error was thrown. It appears that if we want to use optimistic typing in Nashorn, we may need a new mechanism for specifying the method signature (including the return type) when implementing interfaces. I am not aware of any methods to do this for the time being so I am sticking with the turned-off flag. I will have to explore more resources to find out more about this bug.

Sort:  

Thanks for sharing. Its very helpful for new programmer.

It seems you were fully tied up to solve this bug
by the way stackoverflow.com has a great ways for solving most kind of problems in prorgamming
good luck with your job ...

Assalamu alaikum. How are you sir? Watching your post after a long time. What happen sir? Now a days you post very often. In last 10 days only 1 post???

Thank you, @sam1210. I have decided to post mostly about programming and some other subjects that I find interesting. Right now, I am preparing a new post on NodeJS programming that I will publish in a few hours.

That's great. I was thinking the same thing. And I will do the same thing. Hope for the best.

Long time no see???

who is Nashorn? You are quite expert in programming languages. Good keep it up.

Nashorn is a JavaScript engine that runs on top of Java.

I am seeing your blog after a long time, and I am happy that you are still posting good and positive things. I appreciated you for doing such a great work.

Just for curiosity, do you have skills in blockchain developement? or even just dapp with ethereum?

Not really. I have only worked with steem.js so far.

@ghasemkiani Hey, how are you? I was missing from a couple of days. I was missed your javascript tutorial badly. Now, I am back to read and follow all of your tutorials. :)

@ghasemkiani You are most welcome.

Good Post.

Informative post.

Coin Marketplace

STEEM 0.25
TRX 0.11
JST 0.032
BTC 63478.09
ETH 3067.28
USDT 1.00
SBD 3.81