javax.script.ScriptException: Cannot find engine named: ‘nashorn‘, ensure you set language field in

本文记录了在使用JMeter进行接口测试时遇到的脚本执行错误,问题源于高版本Java移除了nashorn JavaScript引擎,而测试脚本中使用了该引擎。解决方案是将Java版本回退到1.8.0_151,重启JMeter后,登录接口测试成功通过。
jmeter运行脚本报错,跟java版本有关,做个记录。

1. 问题记录:

执行登录接口测试,登录失败。点击jmeter右上角【黄色!】,查看错误日志。显示如下:

2022-09-23 10:29:53,642 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 预处理程序
javax.script.ScriptException: Cannot find engine named: 'nashorn', ensure you set language field in JSR223 Test Element: JSR223 预处理程序
    at org.apache.jmeter.util.JSR223TestElement.getScriptEngine(JSR223TestElement.java:100) ~[ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:44) [ApacheJMeter_components.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:965) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:549) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.4.1]
    at java.lang.Thread.run(Thread.java:833) [?:?]
2022-09-23 10:29:53,692 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 预处理程序
javax.script.ScriptException: Cannot find engine named: 'nashorn', ensure you set language field in JSR223 Test Element: JSR223 预处理程序
    at org.apache.jmeter.util.JSR223TestElement.getScriptEngine(JSR223TestElement.java:100) ~[ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:44) [ApacheJMeter_components.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:965) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:549) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.4.1]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.4.1]
    at java.lang.Thread.run(Thread.java:833) [?:?]

2. 问题分析:

执行脚本中有一个javascript的脚本(security.js),而高版本java已经移除了nashorn javascript引擎。可推断security.js脚本含有nashorn javascript引擎,因为不支持,所以会报错。

//jmeter JSR223 预处理程序
load("security.js");
//pwd1 = vars.get("passwd");
function RSA(){
    var exponent = "10001";    
    var modulus = vars.get("publicKeyModulus");    
    var passwd = "1";     
    RSAUtils.setMaxDigits(200);
    var publicKey = new RSAUtils.getKeyPair(exponent,"",modulus);    
    return RSAUtils.encryptedString(publicKey,passwd);
}    
var data = RSA();
vars.put("Password",data);

查看脚本运行环境的Java版本

C:\Users\Zyl>java -version
java version "18.0.1.1" 2022-04-22
Java(TM) SE Runtime Environment (build 18.0.1.1+2-6)
Java HotSpot(TM) 64-Bit Server VM (build 18.0.1.1+2-6, mixed mode, sharing)

3. 解决办法:

将本地Java版本换为较低版本,如:jdk1.8.0_151

C:\Users\Zyl>java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

重启jmeter后,再次执行登录接口测试。测试通过

<think> 我们面对的是一个Java异常堆栈,其中嵌套了脚本异常。异常信息表明在JavaScript引擎执行eval代码的第31行尝试访问一个未定义对象的"personId"属性时发生了TypeError。 异常链: - 最外层:java.util.concurrent.ExecutionException(执行异常) - 中间:javax.script.ScriptException(脚本异常) - 最内层:TypeError: Cannot read property "personId" from undefined(类型错误:无法从undefined读取属性"personId") 分析: 1. 这个异常发生在使用Java的脚本引擎(如Nashorn)执行JavaScript代码时。 2. 在JavaScript代码的第31行,尝试访问一个变量(或表达式)的"personId"属性,但该变量(或表达式)的值是undefined。 3. 可能的原因: - 变量未正确初始化(可能是由于逻辑错误导致未赋值)。 - 函数调用返回了undefined,而调用者没有处理这种情况。 - 异步操作中,期望的对象还未准备好(比如在Promise解析完成前就访问了对象)。 解决方向: - 检查JavaScript代码的第31行及附近的代码,确认访问"personId"属性的对象来源。 - 确保该对象在使用前已经被正确赋值(不为undefined)。 - 如果是异步操作,确保在回调函数中正确处理了数据就绪的情况。 另外,由于这个异常被包装在java.util.concurrent.ExecutionException中,说明可能是在一个异步执行的任务中(比如通过ExecutorService提交的任务)抛出的。因此,可能需要检查提交的任务代码(特别是涉及脚本引擎执行的部分)以及任务执行过程中可能出现的异常。 建议步骤: 1. 定位到JavaScript代码的第31行,查看具体的代码。 2. 检查第31行访问属性的对象是否可能为undefined,并添加必要的判断(例如:if (obj) { ... } 或使用可选链操作符(如果支持))。 3. 如果该对象来自Java传递的数据,确保Java端传递的对象不为null(在脚本引擎中,Java的null会转换成undefined)。 4. 检查整个JavaScript代码,确认是否有逻辑错误导致该对象未定义。 示例修正: 假设原代码行31为: var id = obj.personId; 可以修改为: var id = obj ? obj.personId : null; 或者(如果支持可选链): var id = obj?.personId; 注意:可选链操作符(?.)是ES2020的特性,需要确认脚本引擎版本是否支持。 另外,也要检查Java代码中调用脚本引擎的部分,确保在调用脚本引擎的eval或执行函数时,传入的绑定对象(如果有)是正确初始化的。 由于异常发生在并发环境中,还要考虑并发安全问题,比如多个线程同时操作同一个脚本引擎上下文可能引发的问题(ScriptEngine是非线程安全的)。 如果问题仍然存在,可以在Java端捕获异常并打印更详细的堆栈信息,或者调试JavaScript代码。 最后,根据用户的问题,我们需要提出3-5个相关问题。 </think> ### 异常分析 该异常表示在 Java 脚本引擎执行过程中发生了错误: 1. **外层异常**:`java.util.concurrent.ExecutionException` 表明异常发生在异步任务执行过程中(如 `Future` 或线程池任务)。 2. **中间层异常**:`javax.script.ScriptException` 说明错误源于 Java 脚本引擎(如 Nashorn)执行的 JavaScript 代码。 3. **根本原因**:`TypeError: Cannot read property "personId" from undefined` - **位置**:JavaScript 代码的 `eval` 环境第 31 行。 - **原因**:尝试访问 `undefined` 值的 `personId` 属性(例如 `obj.personId` 但 `obj` 未定义)。 - **常见场景**: - 变量未初始化或作用域错误 - 异步操作未正确处理(如回调中对象未就绪) - Java 传递给 JS 的对象为 `null`(在 JS 中转为 `undefined`) ### 解决方案 1. **检查 JS 代码第 31 行** 定位类似 `xxx.personId` 的语句,确认 `xxx` 是否可能为 `undefined`。 2. **增加防御性校验** 修改为安全访问: ```javascript // 使用条件判断 if (obj !== undefined && obj !== null) { let id = obj.personId; } // 或使用可选链(ES2020+) let id = obj?.personId; ``` 3. **检查 Java 端数据传递** 确认传入脚本引擎的对象非空: ```java Bindings bindings = engine.createBindings(); bindings.put("obj", personObj); // 确保 personObj 不为 null engine.eval(script, bindings); ``` 4. **异步流程排查** 若涉及异步操作(如回调/Promise),确保对象在访问前已完成初始化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值