Optimistic Typing in Nashorn

in javascript •  9 months ago

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.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

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???

@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. :)

·

Thank you.

·
·

@ghasemkiani You are most welcome.

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.

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.

Informative post.

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

Good Post.

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.

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

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

keep it up dear
@ghasemkiani

that's pretty cool to know

Fabulous one!!!

fabulous one

so informative post

Great blog like this @ghasemkiani

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

Informative .... Thanks for sharing

So you are a good programmer too.

very informative post...thanks

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

resteemed

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

nice post .

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

you always have the best content

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

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