Elasticsearch 基础教程

Elasticsearch 高级教程

Elasticsearch 插件

Elasticsearch 笔记

关于 java.lang.IllegalArgumentException: lang cannot be specified for stored scripts 异常的解决方法

Elasticsearch 笔记 Elasticsearch 笔记


当我们的 Elasticsearch(es) client 升级到一定版本之后,原有的代码在使用 stored scripts 时,可能会报 java.lang.IllegalArgumentException: lang cannot be specified for stored scripts 异常,原因是升级之后的 es 客户端包的 Script 类实例化源代码有变更导致,具体原因如下。

异常原因

在 elasticsearch client 6.0.0 及之后,初始化 Script 类时,在指定加载 stored script 时,脚本语言参数 lang 应该传 null,不能传 painless 等指定的语言,具体看如下源码片段:

public Script(ScriptType type, String lang, String idOrCode, Map<String, String> options, Map<String, Object> params) {
    this.type = (ScriptType)Objects.requireNonNull(type);
    this.idOrCode = (String)Objects.requireNonNull(idOrCode);
    this.params = Collections.unmodifiableMap((Map)Objects.requireNonNull(params));
    if (type == ScriptType.INLINE) {
        this.lang = (String)Objects.requireNonNull(lang);
        this.options = Collections.unmodifiableMap((Map)Objects.requireNonNull(options));
    } else {
        if (type != ScriptType.STORED) {
            throw new IllegalStateException("unknown script type [" + type.getName() + "]");
        }

        if (lang != null) {//  变更之处,指定脚本语言反而出错,可能存储脚本里已经指定的缘故
            throw new IllegalArgumentException("lang cannot be specified for stored scripts");
        }

        this.lang = null;
        if (options != null) {
            throw new IllegalStateException("options cannot be specified for stored scripts");
        }

        this.options = null;
    }

}

解决方法

脚本语言对应的参数 lang 改为 null 即可,具体如下:

错误示例:

new Script(ScriptType.STORED, Script.DEFAULT_SCRIPT_LANG, scriptId, scriptParamsMap);

正确示例:

new Script(ScriptType.STORED, null, scriptId, scriptParamsMap);