Nashorn错误:java.lang.NoSuchMethodException:没有这样的函数renderServer

时间:2015-12-03 19:56:48

标签: javascript java reactjs nashorn redux

我对Nashorn有React-redux的奇怪行为。 首先,我有一个非常简单的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应该渲染为包含所有道具的整个事物,{{1}等等,而不仅仅是Provider,否则使用React component处理函数将无效。 我在这里做错了什么以及如何让它发挥作用?

更新: 我发现问题出在babelified批处理文件中。如果我把文件放到我想要只评估React组件(JS,而不是JSX)和没有任何库的renderServer函数,Nashorn能够找到renderServer函数并调用它。 但是所有的教程都说Nashorn非常适合理解批处理文件。 所以我真的不明白问题是什么。

1 个答案:

答案 0 :(得分:1)

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