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

React doesn't eval on Java 8 Nashorn JavaScript Engine #3037

Closed
winterbe opened this Issue Feb 4, 2015 · 7 comments

Comments

Projects
None yet
5 participants
@winterbe

winterbe commented Feb 4, 2015

Nashorn is the new JavaScript Engine shipped with Java 8. Nashorn compiles JavaScript to Java Bytecode, so it runs natively on the JVM.

Unfortunately React doesn't evaluate properly on Nashorn due to the fact that Nashorn doesn't support any kind of module system like AMD out of the box.

This code creates a new nashorn engine and evaluates React on the JVM:

ScriptEngine nashorn = new ScriptEngineManager().getEngineByName("nashorn");
nashorn.eval("load('https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js')");

Running the above code results in the following error:

Caused by: https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js:4 TypeError: Cannot set property "React" of undefined
    at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:58)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:214)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:186)
    at jdk.nashorn.internal.runtime.ECMAErrors.typeError(ECMAErrors.java:173)
    at jdk.nashorn.internal.runtime.Undefined.lookupTypeError(Undefined.java:128)
    at jdk.nashorn.internal.runtime.Undefined.lookup(Undefined.java:119)
    at jdk.nashorn.internal.runtime.linker.NashornLinker.getGuardedInvocation(NashornLinker.java:98)
    at jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker.getGuardedInvocation(CompositeTypeBasedGuardingDynamicLinker.java:176)
    at jdk.internal.dynalink.support.CompositeGuardingDynamicLinker.getGuardedInvocation(CompositeGuardingDynamicLinker.java:124)
    at jdk.internal.dynalink.support.LinkerServicesImpl.getGuardedInvocation(LinkerServicesImpl.java:144)
    at jdk.internal.dynalink.DynamicLinker.relink(DynamicLinker.java:232)
    at jdk.nashorn.internal.scripts.Script$react.L:4(https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js:4)
    at jdk.nashorn.internal.scripts.Script$react.runScript(https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js:4)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
    at jdk.nashorn.internal.runtime.Context.evaluateSource(Context.java:983)
    at jdk.nashorn.internal.runtime.Context.load(Context.java:680)
    at jdk.nashorn.internal.objects.Global.load(Global.java:877)
    at jdk.nashorn.internal.scripts.Script$\^eval\_.runScript(<eval>:1)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:535)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:209)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:378)
    at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:568)
    ... 34 more

Simple workaround is to create a variable window referencing the the global context this:

ScriptEngine nashorn = new ScriptEngineManager().getEngineByName("nashorn");
nashorn.eval("var window = this;");     // workaround
nashorn.eval("load('https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js')");

BTW: Here's a fully working isomorphic java example of your CommentBox tutorial:

https://github.com/winterbe/spring-react-example

The CommentBox is initially rendered on the server with Nashorn.

@brigand

This comment has been minimized.

Show comment
Hide comment
@brigand

brigand Feb 4, 2015

Contributor

The root of this issue is in the build tool: browserify's dependency browser-pack's dependency umd. In template.js it only checks for window, global, or self. You can send a PR there to fall back to this as a last resort.

For now, I'd recommend using var global = this; instead, because typeof window !== 'undefined' is often used to determine a if a script is being run in the browser.

Contributor

brigand commented Feb 4, 2015

The root of this issue is in the build tool: browserify's dependency browser-pack's dependency umd. In template.js it only checks for window, global, or self. You can send a PR there to fall back to this as a last resort.

For now, I'd recommend using var global = this; instead, because typeof window !== 'undefined' is often used to determine a if a script is being run in the browser.

@winterbe

This comment has been minimized.

Show comment
Hide comment
@winterbe

winterbe Feb 4, 2015

Thanks for the hint. I've filed another issue.

winterbe commented Feb 4, 2015

Thanks for the hint. I've filed another issue.

@winterbe

This comment has been minimized.

Show comment
Hide comment
@winterbe

winterbe Feb 9, 2015

FYI: The issue is fixed in UMD.

In the meanwhile I've found another incompatibility between React and Nashorn: There's no console available in Nashorn. Instead Nashorn defines a global function print. I'm using this simple workaround to get my React example working on the JVM:

var global = this;

var console = {};
console.debug = print;
console.warn = print;
console.log = print;

https://github.com/winterbe/spring-react-example/blob/master/src/main/resources/static/nashorn-polyfill.js

Dunno if this fixes all possible issues but that's what I found out so far.

winterbe commented Feb 9, 2015

FYI: The issue is fixed in UMD.

In the meanwhile I've found another incompatibility between React and Nashorn: There's no console available in Nashorn. Instead Nashorn defines a global function print. I'm using this simple workaround to get my React example working on the JVM:

var global = this;

var console = {};
console.debug = print;
console.warn = print;
console.log = print;

https://github.com/winterbe/spring-react-example/blob/master/src/main/resources/static/nashorn-polyfill.js

Dunno if this fixes all possible issues but that's what I found out so far.

@sophiebits

This comment has been minimized.

Show comment
Hide comment
@sophiebits

sophiebits Feb 26, 2015

Member

In the docs we do say that we require a console polyfill for browsers(/engines) that don't support it:

http://facebook.github.io/react/docs/working-with-the-browser.html#browser-support-and-polyfills

Doesn't sound like there's anything else we need to do here so I'm closing this.

Member

sophiebits commented Feb 26, 2015

In the docs we do say that we require a console polyfill for browsers(/engines) that don't support it:

http://facebook.github.io/react/docs/working-with-the-browser.html#browser-support-and-polyfills

Doesn't sound like there's anything else we need to do here so I'm closing this.

@sophiebits sophiebits closed this Feb 26, 2015

@winterbe

This comment has been minimized.

Show comment
Hide comment
@winterbe

winterbe Feb 27, 2015

Thanks for pointing that out.

winterbe commented Feb 27, 2015

Thanks for pointing that out.

@worldsayshi

This comment has been minimized.

Show comment
Hide comment
@worldsayshi

worldsayshi Dec 5, 2015

Also, don't forget console.error = print;. This took me a while to figure out. Hope it helps someone.

sdeleuze/spring-react-isomorphic#3

worldsayshi commented Dec 5, 2015

Also, don't forget console.error = print;. This took me a while to figure out. Hope it helps someone.

sdeleuze/spring-react-isomorphic#3

@david-mark

This comment has been minimized.

Show comment
Hide comment
@david-mark

david-mark Nov 18, 2016

The root of this issue is fixed in this pull request:

#8341

Suggested workarounds are just dodging the real problem.

david-mark commented Nov 18, 2016

The root of this issue is fixed in this pull request:

#8341

Suggested workarounds are just dodging the real problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment