Skip to content

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

Closed
@winterbe

Description

@winterbe

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions