【问题标题】:Nashorn Error: java.lang.NoSuchMethodException: No such function renderServerNashorn 错误:java.lang.NoSuchMethodException:没有这样的函数 renderServer
【发布时间】:2016-03-08 14:23:35
【问题描述】:

我对使用 React-redux 的 Nashorn 有奇怪的行为。 首先,我有一个非常简单的 javascript,它在部署之前被 babelified(我把 JSX 放在这里,因为结果 babelified 文件很大):

var React = require('react');
var ReactDOM = require('react-dom');
var connect = require('react-redux').connect;
var Link = require('react-router').Link;

function mapStateToProps(state) {
    console.log("mapStateToProps ", state);
    return {options: state.options};
};

var IndexContainer = React.createClass({
    render: function () {
        console.log(this.props.options);
        return (
            <div>
                <Link to="r">Link!</Link>
            </div>
        );
    }
});

var Index = connect(mapStateToProps)(IndexContainer);

var renderServer = function (data) {
    var data = Java.from(data);
    return React.renderToString(
        React.createElement(Index, {data: data})
    );
};

第二,我有Java代码:

@Component
@SuppressWarnings("restriction")
public class ReactRenderer {
    private ThreadLocal<NashornScriptEngine> engineHolder = new ThreadLocal<NashornScriptEngine>() {
        @Override
        protected NashornScriptEngine initialValue() {
            NashornScriptEngine nashornScriptEngine = (NashornScriptEngine) new ScriptEngineManager()
                    .getEngineByName("nashorn");
            try {
                nashornScriptEngine.eval(read("static/nashorn-polyfill.js"));
                nashornScriptEngine.eval(read("/WEB-INF/resources/js/main.js"));
            } catch (ScriptException e) {
                throw new RuntimeException(e);
            }
            return nashornScriptEngine;
        } 
    };

    private Reader read(String path) {
        InputStream in = getClass().getClassLoader().getResourceAsStream(path);
        return new InputStreamReader(in);
    }

    public String render(List<Object> objects) {
        try {
            Object html = engineHolder.get().invokeFunction("renderServer", objects);
            return String.valueOf(html); 
        } catch (Exception e) {
            throw new IllegalStateException("failed to render react component", e);
        }
    }
}

当我在 java 中调用 render(objects) 时,我得到:

java.lang.NoSuchMethodException: No such function renderServer
    jdk.nashorn.api.scripting.ScriptObjectMirror.callMember(ScriptObjectMirror.java:204)
    jdk.nashorn.api.scripting.NashornScriptEngine.invokeImpl(NashornScriptEngine.java:383)
    jdk.nashorn.api.scripting.NashornScriptEngine.invokeFunction(NashornScriptEngine.java:190)

如果我删除

function mapStateToProps(state) {
    console.log("mapStateToProps ", state);
    return {options: state.options};
};

它确实找到了 renderServer 函数,但是由于那里没有 mapStateToProps 而无法评估,并且根据 redux 的说法,tutorial 应该被渲染为使用所有道具、Provider 等将整个事物串起来,而不仅仅是React component,否则使用this.store.dispatch 的处理函数将不起作用。 我在这里做错了什么以及如何使它起作用?


更新: 我发现问题出在 babelified 批处理文件上。如果我将文件放入我只想评估 React 组件(JS,而不是 JSX)和 renderServer 函数而没有任何库,Nashorn 能够找到 renderServer 函数并调用它。 但是所有的教程都说 Nashorn 在理解批处理文件方面是完美的。 所以我真的不明白问题出在哪里。

【问题讨论】:

  • 您使用的是什么 JDK/Nashorn 版本?在早期的 JDK8 版本中,使用 Nashorn 运行 React 存在问题。也许尝试使用 early access snapshot 的最新更新版本
  • @HannesWallnöfer 我用的是8u65 Oracle,没发现这种错误。
  • 8u65 应该没问题。 “批处理文件”是什么意思? Nashorn 只能处理 JS 文件。
  • 我的意思是它是一个包含所有库代码的已处理文件,而不是“require”或“import”语句。对不起,我是一个JS新手,可能我混淆了那个文件的一个词。

标签: javascript java reactjs nashorn redux


【解决方案1】:

由于您可能正在使用 webpack,因此您的 var renderServer 最终会成为 webpack 函数中的局部变量。 global.renderServer = ....应该可以工作

【讨论】:

  • 看来你是对的。感谢那。一会儿我会回到这段代码,一定要试试。
猜你喜欢
  • 2012-08-05
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2016-02-15
  • 2018-06-21
  • 2011-07-11
相关资源
最近更新 更多