{"record":{"id":"ae91f1ddd1e7c2ef","repo":"Tencent/APIJSON","slug":"isempty-js-lang-engin","errorCode":null,"errorMessage":"找不到可执行 \" + (isEmpty ? \"js\" : lang) + \" 脚本的引擎！engine == null!","messagePattern":"找不到可执行 \" \\+ \\(isEmpty \\? \"js\" : lang\\) \\+ \" 脚本的引擎！engine == null!","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":1350,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tLog.i(TAG, \"parse  return real = \" + toJSONString(real));\n\t\treturn real;\n\t}\n\n\tpublic static ScriptEngine getScriptEngine(String lang) {\n\t\tif (ENABLE_SCRIPT_FUNCTION == false) {\n\t\t\tthrow new UnsupportedOperationException(\"AbstractFunctionParser.ENABLE_SCRIPT_FUNCTION\" +\n\t\t\t\t\t\" == false 时不支持执行脚本！如需支持则设置为 true ！\");\n\t\t}\n\n\t\tboolean isEmpty = StringUtil.isEmpty(lang, true);\n\t\tScriptEngine engine = isEmpty ? SCRIPT_ENGINE : SCRIPT_ENGINE_MANAGER.getEngineByName(lang);\n\n\t\tif (engine == null) {\n\t\t\tthrow new NullPointerException(\"找不到可执行 \" + (isEmpty ? \"js\" : lang) + \" 脚本的引擎！engine == null!\");\n\t\t}\n\n\t\treturn engine;\n\t}\n\n\n\t/**执行操作\n\t * @param opt\n\t * @param targetChild\n\t * @param real\n\t * @param parser\n\t * @return\n\t * @throws Exception\n\t */\n\tpublic static <T, M extends Map<String, Object>, L extends List<Object>> M operate(Operation opt, M targetChild\n            , M real, @NotNull Parser<T, M, L> parser) throws Exception {\n\t\tif (targetChild == null) {\n\t\t\treturn real;","sourceCodeStart":1332,"sourceCodeEnd":1368,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L1332-L1368","documentation":"After the ENABLE_SCRIPT_FUNCTION gate passes, getScriptEngine resolves the engine: an empty lang falls back to the default SCRIPT_ENGINE (usually JavaScript), otherwise SCRIPT_ENGINE_MANAGER.getEngineByName(lang). NullPointerException here means javax.script found no engine registered for that language in the JVM — typically 'js' on JDK 15+ where Nashorn was removed, or a non-JVM language (python/ruby) whose engine jar is absent from the classpath.","triggerScenarios":"Running on JDK 15+ (Nashorn removed) and calling any script function (lang empty or 'js' → getEngineByName returns null); or specifying lang 'python', 'kotlin', 'groovy' without the corresponding JSR-223 engine (e.g. groovy-jsr223, jython) on the classpath. Note on JDK 11-14 Nashorn is present but deprecated and warns.","commonSituations":"App worked on JDK 8, broke after upgrading to JDK 11+ without adding the standalone Nashorn (org.openjdk.nashorn:nashorn-core) + asm dependencies; declaring a custom lang in a function definition but forgetting its engine jar; minimal Docker images that strip optional modules.","solutions":["On JDK 15+, add standalone Nashorn: org.openjdk.nashorn:nashorn-core:15.4 plus org.ow2.asm:asm:9.x (and asm-util/asm-tree) to the runtime classpath — SCRIPT_ENGINE_MANAGER will then find 'js'.","For a non-JS language, add its JSR-223 engine jar (e.g. org.apache.groovy:groovy-jsr223, org.python:jython) and use the exact engine name ScriptEngineManager.getEngineByName expects.","Verify availability at startup with a guard: ScriptEngineManager().getEngineByName(lang) != null, and fail fast/log instead of at request time.","Avoid scripts entirely by registering plain Java functions via FunctionParser."],"exampleFix":"// before (JDK 17, no js engine on classpath)\n// dependencies: none -> getScriptEngine(\"js\") throws NPE\n\n// after (Maven)\n<dependency>\n  <groupId>org.openjdk.nashorn</groupId>\n  <artifactId>nashorn-core</artifactId>\n  <version>15.4</version>\n</dependency>\n<dependency>\n  <groupId>org.ow2.asm</groupId>\n  <artifactId>asm</artifactId>\n  <version>9.6</version>\n</dependency>","handlingStrategy":"validation","validationCode":"static final boolean JS_OK;\nstatic {\n  ScriptEngine e = new ScriptEngineManager().getEngineByName(\"js\");\n  JS_OK = e != null;\n}\nvoid beforeRequest() {\n  if (!JS_OK) throw new IllegalStateException(\n    \"No 'js' ScriptEngine on classpath — add org.openjdk.nashorn:nashorn-core (JDK 15+) or run on JDK 8-14\");\n}","typeGuard":null,"tryCatchPattern":"try { engine = AbstractVerifier.getScriptEngine(lang); }\ncatch (NullPointerException npe) {\n  // engine missing: report classpath/JDK mismatch instead of retrying blindly\n  throw new IllegalStateException(\"Script engine '\" + lang + \"' unavailable on this JVM (\" +\n    System.getProperty(\"java.version\") + \") — add the JSR-223 engine dependency\", npe);\n}","preventionTips":["On JDK 15+, pin org.openjdk.nashorn:nashorn-core + org.ow2.asm:asm in the runtime classpath.","Add a startup self-test that evaluates '1+1' through getScriptEngine to fail fast at boot, not at first request.","Prefer registered Java functions over scripts to remove the engine dependency entirely."],"tags":["apijson","script-execution","jdk-compatibility","nashorn","classpath"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}