Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
707 views
in Technique[技术] by (71.8m points)

elasticsearch - Null pointer exception in ES painless script?

I am using painless script in ES and encountering a null pointer exception, here is my script and also I have added the response for better understanding, I use ES v7.3.

POST test_script/_update/1
{
  "scripted_upsert": true,
  "script": {
    "lang": "painless",
    "source": "int getBrowsersObjectIndex(def x, def y){for (int i = 0; i < x.length; i++) {if (x[i].deviceType == y.deviceType) {if (x[i].osName == y.osName) {if(x[i].browserName == y.browserName) {return i}}}}return -1} int getDevicesObjectIndex(def x, def y){for (int i = 0; i < x.length; i++) {if (x[i].deviceId == y.deviceId) {if (x[i].appName == y.appName) {if (x[i].appNameSpace == y.appNameSpace){return i}}}}return -1}if (!ctx._source.containsKey('browsers')) {ctx._source['browsers'] = []}if (!ctx._source.containsKey('devices')) {ctx._source['devices'] = []}for (int index = 0; index < params.iterate.length; index++) {if (params.iterate[index].browserObject) {int browserIndex = getBrowsersObjectIndex(ctx._source.browsers, params.iterate[index].browserObject);if (browserIndex >= 0) {ctx._source.browsers.remove(browserIndex);}ctx._source.browsers.add(params.iterate[index].browserObject);}if (params.iterate[index].deviceObject) {int deviceIndex = getDevicesObjectIndex(ctx._source.devices, params.iterate[index].deviceObject);if (deviceIndex >= 0) {ctx._source.devices.remove(deviceIndex);}ctx._source.devices.add(params.iterate[index].deviceObject);}}",
    "params": {
      "iterate": [
        {
          "deviceObject": {
            "deviceId": "162c04e48832e338",
            "appName": "test_app",
            "appNameSpace": "com.test",
            "appBuild": 55,
            "appVersion": "4.6.3",
            "deviceName": "OP4B80L1",
            "manufacturer": "OPPO",
            "model": "CPH1937",
            "networkCarrier": "Jio",
            "os": "Android",
            "platform": "Android",
            "timezone": "Asia/Kolkata",
            "version": "10"
          }
        },
        {
          "browserObject": {
            "deviceType": "mobile",
            "osName": "Android",
            "browserName": "Chrome",
            "osVersion": 10,
            "browserVersion": "80.0.3987.99"
          }
        }
      ]
    }
  },
  "upsert": {}
}

Error is:

{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[connecto][192.168.36.235:9300][indices:data/write/update[s]]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "failed to execute script",
    "caused_by": {
      "type": "script_exception",
      "reason": "runtime error",
      "script_stack": [
        "if (params.iterate[index].browserObject) {int ",
        "                         ^---- HERE"
      ],
      "script": "int getBrowsersObjectIndex(def x, def y){for (int i = 0; i < x.length; i++) {if (x[i].deviceType == y.deviceType) {if (x[i].osName == y.osName) {if(x[i].browserName == y.browserName) {return i}}}}return -1} int getDevicesObjectIndex(def x, def y){for (int i = 0; i < x.length; i++) {if (x[i].deviceId == y.deviceId) {if (x[i].appName == y.appName) {if (x[i].appNameSpace == y.appNameSpace){return i}}}}return -1}if (!ctx._source.containsKey('browsers')) {ctx._source['browsers'] = []}if (!ctx._source.containsKey('devices')) {ctx._source['devices'] = []}for (int index = 0; index < params.iterate.length; index++) {if (params.iterate[index].browserObject) {int browserIndex = getBrowsersObjectIndex(ctx._source.browsers, params.iterate[index].browserObject);if (browserIndex >= 0) {ctx._source.browsers.remove(browserIndex);}ctx._source.browsers.add(params.iterate[index].browserObject);}if (params.iterate[index].deviceObject) {int deviceIndex = getDevicesObjectIndex(ctx._source.devices, params.iterate[index].deviceObject);if (deviceIndex >= 0) {ctx._source.devices.remove(deviceIndex);}ctx._source.devices.add(params.iterate[index].deviceObject);}}",
      "lang": "painless",
      "caused_by": {
        "type": "null_pointer_exception",
        "reason": null
      }
    }
  },
  "status": 400
}

Seems like the error is in the if statement where I am checking if either of browserObject or deviceObject exists inside the iterate array of objects.

question from:https://stackoverflow.com/questions/65934735/null-pointer-exception-in-es-painless-script

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to perform an explicit null-check, i.e.

if (params.iterate[index].browserObject != null)

Besides, in Kibana Dev Tools, you can use triple quotes """ to properly format your code so it's more legible and easier to read/maintain:

POST test_script/_update/1
{
  "scripted_upsert": true,
  "script": {
    "lang": "painless",
    "source": """
    int getBrowsersObjectIndex(def x, def y){
      for (int i = 0; i < x.length; i++) {
        if (x[i].deviceType == y.deviceType) {
          if (x[i].osName == y.osName) {
            if(x[i].browserName == y.browserName) {
              return i
            }
          }
        }
      }
      return -1
    }
    int getDevicesObjectIndex(def x, def y){
      for (int i = 0; i < x.length; i++) {
        if (x[i].deviceId == y.deviceId) {
          if (x[i].appName == y.appName) {
            if (x[i].appNameSpace == y.appNameSpace){
              return i
            }
          }
        }
      }
      return -1
    }
    if (!ctx._source.containsKey('browsers')) {
      ctx._source['browsers'] = []
    }
    if (!ctx._source.containsKey('devices')) {
      ctx._source['devices'] = []
    }
    for (int index = 0; index < params.iterate.length; index++) {
      if (params.iterate[index].browserObject != null) {
        int browserIndex = getBrowsersObjectIndex(ctx._source.browsers, params.iterate[index].browserObject);
        if (browserIndex >= 0) {
          ctx._source.browsers.remove(browserIndex);
        }
        ctx._source.browsers.add(params.iterate[index].browserObject);
      }
      if (params.iterate[index].deviceObject != null) {
        int deviceIndex = getDevicesObjectIndex(ctx._source.devices, params.iterate[index].deviceObject);
        if (deviceIndex >= 0) {
          ctx._source.devices.remove(deviceIndex);
        }
        ctx._source.devices.add(params.iterate[index].deviceObject);
      }
    }
    """,
    "params": {
      "iterate": [
        {
          "deviceObject": {
            "deviceId": "162c04e48832e338",
            "appName": "test_app",
            "appNameSpace": "com.test",
            "appBuild": 55,
            "appVersion": "4.6.3",
            "deviceName": "OP4B80L1",
            "manufacturer": "OPPO",
            "model": "CPH1937",
            "networkCarrier": "Jio",
            "os": "Android",
            "platform": "Android",
            "timezone": "Asia/Kolkata",
            "version": "10"
          }
        },
        {
          "browserObject": {
            "deviceType": "mobile",
            "osName": "Android",
            "browserName": "Chrome",
            "osVersion": 10,
            "browserVersion": "80.0.3987.99"
          }
        }
      ]
    }
  },
  "upsert": {}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...