Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question about integration of GraalJSScriptEngine as default script engine in FXMLLoader #83

Closed
jvaca92 opened this issue Dec 11, 2018 · 4 comments
Assignees

Comments

@jvaca92
Copy link

jvaca92 commented Dec 11, 2018

I would have question if would be possible integration of GraalJSScriptEngine as default javascript engine instead of Nashorn into FXMLLoader. Nowadays there is not possibilities to change script engine in FXMLLoader related to javascript.

Thanks is advance.

@wirthi wirthi self-assigned this Dec 18, 2018
@jvaca92
Copy link
Author

jvaca92 commented Dec 20, 2018

So after little playing I downloaded version of GraalVM 1.0.0-rc10 and then create small test application to test integration of GraalJSScriptEngine with JavaFX. Actually I could see that FXMLLoader really taking GraalJSScriptEngine as default javascript engine instead of Nashorn (see pic.1 ). Anway throw exception when I try to call function with the basic javascript code. Let me explain the example.

Pic.1
screenshot from 2018-12-20 21-42-39

I have fxml file where I have create dummy FXML view with javascript which should set up text to label after the button in clicked. The example of FXML can be seen below.

<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" > <fx:script> function clickTest() { lbTestMsg.text = "This is the text of my label."; } </fx:script> <children> <ButtonBar prefHeight="40.0" prefWidth="600.0" /> <Button fx:id="btnTest" onAction="clickTest()" alignment="CENTER" contentDisplay="RIGHT" layoutX="272.0" layoutY="186.0" minWidth="48.0" mnemonicParsing="false" prefHeight="29.0" prefWidth="77.0" text="Test" /> <Label fx:id="lbTestMsg" layoutX="295.0" layoutY="269.0"> <font> <Font size="24.0" /> </font> </Label> </children> </AnchorPane>

After trying to load fxml view by FXMLoader is everything fine but when I click on test button I got this kind of error. Its seems that GraalJSScriptEngine does not work properly as Nashorn.

Exception`` in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: The value 'com.oracle.truffle.js.runtime.truffleinterop.InteropBoundFunction@4040779c' cannot be passed from one context to another. The current context is 0x1ce9096c and the argument value originates from context 0x71b3cc9c. at com.oracle.truffle.polyglot.PolyglotLanguageContext.migrateValue(PolyglotLanguageContext.java:695) at com.oracle.truffle.polyglot.PolyglotLanguageContext.migrateHostWrapper(PolyglotLanguageContext.java:706) at com.oracle.truffle.polyglot.PolyglotLanguageContext.toGuestValue(PolyglotLanguageContext.java:669) at com.oracle.truffle.polyglot.PolyglotLanguageContext$ToGuestValueNode.slowPath(PolyglotLanguageContext.java:553) at com.oracle.truffle.polyglot.PolyglotLanguageContext$ToGuestValueNode.apply(PolyglotLanguageContext.java:548) at com.oracle.truffle.polyglot.PolyglotMap$Cache$Put.executeImpl(PolyglotMap.java:604) at com.oracle.truffle.polyglot.PolyglotMap$Cache$Put.executeImpl(PolyglotMap.java:570) at com.oracle.truffle.polyglot.HostRootNode.execute(HostRootNode.java:94) at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:98) at com.oracle.truffle.polyglot.PolyglotMap.put(PolyglotMap.java:130) at com.oracle.truffle.js.scriptengine.GraalJSBindings.put(GraalJSBindings.java:84) at com.oracle.truffle.js.scriptengine.GraalJSBindings.put(GraalJSBindings.java:53) at java.util.AbstractMap.putAll(AbstractMap.java:281) at javafx.fxml.FXMLLoader$ScriptEventHandler.handle(FXMLLoader.java:1677) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Node.fireEvent(Node.java:8411) at javafx.scene.control.Button.fire(Button.java:185) at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.event.Event.fireEvent(Event.java:198) at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431) at com.sun.glass.ui.View.handleMouseEvent(View.java:555) at com.sun.glass.ui.View.notifyMouse(View.java:937) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication.lambda$null$48(GtkApplication.java:139) at java.lang.Thread.run(Thread.java:748) Caused by: Attached Guest Language Frames (1)

Thank in advance for any hints from your side.

@wirthi
Copy link
Member

wirthi commented Dec 21, 2018

Hi @jvaca92

thanks for your question. I am unfamiliar with FXML - can you provide the code you are using somewhere so we can replicate?

On the concrete error message you get: Graal.js does not allow to arbitrarily exchange data between threads, as this can lead to all kinds of data races. That is what the message is telling you: a value (a function) is passed from one Context (one instance of the JS engine) to another, which we don't allow like that. I am sure there is a solution to that problem, but again, it would be helpful if we could inspect your code (for instance, we allow sharing of code between context so you don't have to re-evaluate them in each single one, see https://www.graalvm.org/docs/graalvm-as-a-platform/embed/#enable-source-caching). For a more in-depth discussion, see e.g. #59. We are also working on more documentation how safe multithreading can be achieved on Graal.js, it should be available mid-January.

Best,
Christian

@jvaca92
Copy link
Author

jvaca92 commented Jan 14, 2019

Hi @wirthi,

Thank you for your response. Sorry for little delay but anyway I have created the sample project where you can replicate the error. You can find it here
The main scenario is happened after click of the button. When you setup attribute language to nashorn in the file Main.fxml which is located in resources dir, everything works perfectly, because FXMLaoder using Nashorn as native javascript engine but when the value is changed to js then FXMLoader working with GraalJS but the error is thrown.
I would expect for future that GraalJS will be working with JavaFX because the Nashorn will be deprecated.

Best regards,
Jan

See

screenshot from 2019-01-14 10-43-02

screenshot from 2019-01-14 10-44-10

@jvaca92
Copy link
Author

jvaca92 commented Jan 24, 2019

Hello there,

I would like inform you that after doing some research I have reached solution how can be achieved to implement GraalJS as script engine for FXML. The solution can be seen in my example. Actually I have reached by LoaderListener where I have picked up all nodes which has attribute fx:id and then stored them in map. Then I have used Graal context where I have configure javascript engine with attribute to -Dpolyglot.js.nashorn-compat=true and inject stored nodes as member and then evaluate the js script with inejcted members. The result works as expected. I have also created the enhancement issue on Oracle here where can be expected that the GraalJS will be implemented in FXMLLoader in future, but its question of time when would be done. Anyway if somebody would be interested about the solution, then can be found here see.
For now I am closing the issue. Anyway I can say that the performance of GraalJS its really fulfill my expectation.
Thanks guys that doing this great job.

@jvaca92 jvaca92 closed this as completed Jan 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants