JMeter仅通过CLI运行时出现JSONObject不在命名空间错误
JMeter CLI运行Beanshell脚本找不到JSONObject,但GUI正常的原因分析
问题描述
在MacBook上使用Java 19、Beanshell 2.0b6运行JMeter 5.4.2脚本时,出现以下差异:
- 通过GUI运行脚本无错误
- 通过CLI执行时,JSR223预处理器报错找不到
JSONObject类,错误日志如下:
2023-12-04 16:52:47,858 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor - Create tokenPayload javax.script.ScriptException: Sourced file: inline evaluation of: ``import org.apache.jmeter.protocol.http.control.CookieManager; import org.apach . . . '' : Typed variable declaration : Class: JSONObject not found in namespace : at Line: 10 : in file: inline evaluation of: ``import org.apache.jmeter.protocol.http.control.CookieManager; import org.apach . . . '' : JSONObject in inline evaluation of: ``import org.apache.jmeter.protocol.http.control.CookieManager; import org.apach . . . '' at line number 10 at bsh.engine.BshScriptEngine.evalSource(BshScriptEngine.java:93) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.engine.BshScriptEngine.eval(BshScriptEngine.java:46) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:231) ~[java.scripting:?] at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:219) ~[ApacheJMeter_core.jar:5.4.2] at org.apache.jmeter.modifiers.JSR223PreProcessor.process(JSR223PreProcessor.java:45) [ApacheJMeter_components.jar:5.4.2] at org.apache.jmeter.threads.JMeterThread.runPreProcessors(JMeterThread.java:965) [ApacheJMeter_core.jar:5.4.2] at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:549) [ApacheJMeter_core.jar:5.4.2] at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.4.2] at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.4.2] at java.lang.Thread.run(Thread.java:1589) [?:?]
已知条件:
org.json.jar已放置在JMeter的/lib目录下JMETER_HOME环境变量已正确设置为JMeter安装目录- 因Java 19与JMeter 5.4.2不兼容,无法替换为Groovy脚本,需保留Beanshell实现
需明确:为何GUI与CLI运行会出现类加载差异?
可能的原因及分析
1. Mac环境下CLI与GUI的类路径加载机制差异
JMeter的GUI启动分支和CLI启动分支在类路径拼接上存在细微差异:
- GUI模式启动时,会递归加载
lib/和lib/ext/下的所有JAR包,包括org.json.jar - CLI模式下,Mac默认shell(如zsh)可能对环境变量解析存在差异,导致
JMETER_HOME对应的类路径未完全生效,或lib/目录下的JAR未被正确添加到类路径
2. Java 19模块系统的限制
JMeter 5.4.2未适配Java 19的模块系统(JPMS):
- GUI模式下,JMeter启动脚本可能添加了
--add-opens或--add-modules等参数,绕过模块系统对未模块化JAR的访问限制 - CLI模式下,启动参数缺少对应配置,导致Beanshell引擎无法访问
org.json包中的类
3. Beanshell引擎的类加载器差异
Beanshell 2.0b6版本较老,类加载机制在不同运行模式下存在差异:
- GUI模式中,JMeter主线程类加载器会加载所有
lib/下的JAR,Beanshell引擎共享该类加载器,因此能找到JSONObject - CLI模式下,JMeter为性能优化使用了不同的类加载器策略,Beanshell脚本引擎的类加载器无法访问
org.json.jar中的类
4. Mac环境的权限问题
- CLI模式下,若使用
sudo或不同用户身份运行JMeter,可能导致lib/目录下的org.json.jar无法被读取,类加载失败 - GUI模式通常以当前用户身份运行,权限足够读取该JAR文件
验证与解决建议
- 直接在CLI启动命令中显式指定
org.json.jar路径:jmeter -n -t your_script.jmx -cp "/path/to/jmeter/lib/org.json.jar" - 检查
jmeter.sh脚本中CLI模式的类路径拼接逻辑,确认lib/*是否被正确添加到CLASSPATH变量 - 添加Java模块参数到CLI启动命令:
jmeter -n -t your_script.jmx -Jjava.opts="--add-modules=ALL-SYSTEM --add-opens java.base/java.lang=ALL-UNNAMED" - 确保CLI运行时的用户身份与GUI一致,检查
org.json.jar的文件权限:ls -l /path/to/jmeter/lib/org.json.jar
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

