Regression: Painless script fails for BinaryOperator lamdba

Hey there,

we noticed previously working painless scripts that make use of the Java Stream API passing lamdbas for BinaryOperator parameters to fail with Elasticsearch 7.16.0 onwards.

E.g. the following sample works fine on Elasticsearch 7.15.2

curl --location --request POST 'localhost:9200/_scripts/painless/_execute' \
--header 'Content-Type: application/json' \
--data-raw '{
  "script": {
    "source": "def list = new ArrayList(); list.add(1); list.add(2); list.stream().reduce((i1, i2) -> i1).orElse(0)"
  }
}'

returning:

{
    "result": "1"
}

but fails on 7.16.0 onwards with:

{
    "error": {
        "root_cause": [
            {
                "type": "script_exception",
                "reason": "runtime error",
                "script_stack": [
                    "(i1, i2) -> i1).orElse(0)",
                    "^---- HERE"
                ],
                "script": "def list = new ArrayList(); list.add(1); list.add(2); list.stream().reduce((i1, i2) -> i1).orElse(0)",
                "lang": "painless",
                "position": {
                    "offset": 75,
                    "start": 75,
                    "end": 100
                }
            }
        ],
        "type": "script_exception",
        "reason": "runtime error",
        "script_stack": [
            "(i1, i2) -> i1).orElse(0)",
            "^---- HERE"
        ],
        "script": "def list = new ArrayList(); list.add(1); list.add(2); list.stream().reduce((i1, i2) -> i1).orElse(0)",
        "lang": "painless",
        "position": {
            "offset": 75,
            "start": 75,
            "end": 100
        },
        "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "cannot convert function reference [this::lambda$synthetic$0] to a non-functional interface [java.util.function.BinaryOperator]"
        }
    },
    "status": 400
}

I haven't tracked down the particular change in 7.16 that causes this.
The issue is currently blocking us from adding support for Elasticsearch 7.16.

Any hints on syntax workarounds or confimration of this being a regression so I can raise a bug are appreciated!

Best
Sebastian

Hi @Sebastian_Bathke, this is indeed a regression. It would normally fail at runtime, so thankfully it failed at compile time for you.

Unfortunately, the only mitigation is to avoid the functional interface by rewriting in imperative style.

Thank you for the reproduction, it was very helpful in diagnosing the issue.

We are working on a fix. You can track this in Painless: Failed resolution of subclasses of functional interfaces · Issue #81696 · elastic/elasticsearch · GitHub

Many thanks for the fast verification!

I investigated and created a draft fix PR, see Fix use functional method from superInterface if exists by megglos · Pull Request #81697 · elastic/elasticsearch · GitHub .

Hope this may be helpful.

1 Like

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.