Optimistic Typing in Nashorn

in #javascript3 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.

Very good teaching.I appreciate this part.Thanks a lot for your helpful blog

mashti belakhare post gozashti damet garm
good luck

Use your smile to change this world.dont let this world change your amile..

Nice tutorial. I always follow your tutorial. Resteem the post.

this very nice post i like it thank for sharing this technology.best of luck..

that's pretty cool to know

Fabulous one!!!

Great blog like this @ghasemkiani

So you are a good programmer too.

very informative post...thanks

Informative .... Thanks for sharing

wow nice post sir,,,great information.........our technology can do everything what we want.your programming news is good.........

resteemed

nice post .

your post is so helpful for me .I will try it.
thanks for sharing.

A long time, you don't see. Many busy are appears. Technology about thanks for writing.

a very perfect and great program, thanks to have shared this great information, it is a useful science.

wow that's quite great work thanks for sharing the code

so informative post

you always have the best content

great post dear @ghasemkiani and good job.i like your post all time.but very miss you dear

keep it up dear
@ghasemkiani

@ghasemkiani السلام عليكم
Thanks for the information, this is very useful for me,

Hi my brother
Please teach me to use stemiit better and useful.
So my work gets a lot of votes like you
Thank you

Coin Marketplace

STEEM 0.20
TRX 0.03
JST 0.030
BTC 36868.36
ETH 1248.30
USDT 1.00
SBD 3.23