JMeter中JSR223断言调用方法时触发空指针异常求助
JMeter JSR223 Assertion 空指针错误排查与解决
问题背景
在JMeter脚本中使用两个JSON Extractor(Match No均设为-1)收集数据到dependentFeatID和featureIDs变量,通过JSR223 Assertion验证featureIDs是否包含dependentFeatID中的数据。执行时出现Null Pointer in Method Invocation错误,但已确认两个变量均可正常获取值。
原代码
// Get the value of dependentFeatID variable from JMeter variables String dependentFeatID = vars.get("dependentFeatID") // Check if dependentFeatID is not null if (dependentFeatID != null) { // Split the dependentFeatID into an array of IDs String[] dependentFeatIDs = dependentFeatID.split(",") // Check if dependentFeatIDs array is not empty if (dependentFeatIDs.length > 0) { // Get the first ID from dependentFeatIDs array String searchString = dependentFeatIDs[0] log.info("searchString: $searchString") log.info(dependentFeatIDs[1]+"AND "+dependentFeatIDs[2]) // Get the value of featureIDs variable from JMeter variables String featureIDs = vars.get("featureIDs") // Check if featureIDs is not null if (featureIDs != null) { // Split the featureIDs into an array of IDs String[] ids = featureIDs.split(",") log.info(ids[0]+"AND "+ids[1]+"AND "+ids[2]+"AND "+ids[3]) boolean idFound = false // Iterate over each ID in the array for (String id : ids) { // Trim any leading or trailing whitespace from the ID id = id.trim() // Check if the current ID matches the search string if (id.equals(searchString)) { // If the ID is found, set idFound to true and break out of the loop idFound = true break } } // Set the assertion result based on whether the ID is found AssertionResult.setFailure(!idFound) if (!idFound) { AssertionResult.setFailureMessage("ID not found in var_id: $searchString") } } else { // Log an error if featureIDs is null log.error("featureIDs variable is null") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("featureIDs variable is null") } } else { // Log an error if dependentFeatIDs array is empty log.error("dependentFeatIDs array is empty") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("dependentFeatIDs array is empty") } } else { // Log an error if dependentFeatID is null log.error("dependentFeatID variable is null") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("dependentFeatID variable is null") }
错误日志
org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: `String dependentFeatID = ""; dependentFeatID = vars.get("dependentFeatID"); St . . . '' : Typed variable declaration at org.apache.jmeter.util.BeanShellInterpreter.bshInvoke(BeanShellInterpreter.java:179) ~[ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.util.BeanShellInterpreter.eval(BeanShellInterpreter.java:185) ~[ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.util.BeanShellTestElement.processFileOrScript(BeanShellTestElement.java:174) ~[ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.util.BeanShellTestElement.processFileOrScript(BeanShellTestElement.java:140) ~[ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.assertions.BeanShellAssertion.getResult(BeanShellAssertion.java:106) [ApacheJMeter_components.jar:5.6.3] at org.apache.jmeter.threads.JMeterThread.processAssertion(JMeterThread.java:949) [ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.threads.JMeterThread.checkAssertions(JMeterThread.java:918) [ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:586) [ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:501) [ApacheJMeter_core.jar:5.6.3] at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:268) [ApacheJMeter_core.jar:5.6.3] at java.base/java.lang.Thread.run(Thread.java:834) [?:?] Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.apache.jmeter.util.BeanShellInterpreter.bshInvoke(BeanShellInterpreter.java:162) ~[ApacheJMeter_core.jar:5.6.3] ... 10 more Caused by: bsh.TargetError: Sourced file: inline evaluation of: `String dependentFeatID = ""; dependentFeatID = vars.get("dependentFeatID"); St . . . '' : Typed variable declaration at bsh.UtilTargetError.toEvalError(UtilTargetError.java:64) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.UtilEvalError.toEvalError(UtilEvalError.java:84) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:93) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:96) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:41) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHVariableDeclarator.eval(BSHVariableDeclarator.java:80) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHTypedVariableDeclaration.eval(BSHTypedVariableDeclaration.java:78) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:659) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:750) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:739) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.apache.jmeter.util.BeanShellInterpreter.bshInvoke(BeanShellInterpreter.java:162) ~[ApacheJMeter_core.jar:5.6.3] ... 10 more Caused by: java.lang.NullPointerException: Null Pointer in Method Invocation at bsh.Name.invokeMethod(Name.java:838) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHMethodInvocation.eval(BSHMethodInvocation.java:69) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:96) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHPrimaryExpression.eval(BSHPrimaryExpression.java:41) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHVariableDeclarator.eval(BSHVariableDeclarator.java:80) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.BSHTypedVariableDeclaration.eval(BSHTypedVariableDeclaration.java:78) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:659) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:750) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at bsh.Interpreter.eval(Interpreter.java:739) ~[bsh-2.0b6.jar:2.0b6 2016-02-05 05:16:19] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.apache.jmeter.util.BeanShellInterpreter.bshInvoke(BeanShellInterpreter.java:162) ~[ApacheJMeter_core.jar:5.6.3] ... 10 more
问题原因
- 字符串插值语法错误:BeanShell不支持
$变量名的字符串插值写法,log.info("searchString: $searchString")会被解析为普通字符串,若后续逻辑依赖此插值可能引发异常。 - 数组越界访问:直接访问
dependentFeatIDs[1]、dependentFeatIDs[2]以及ids[0]至ids[3],未判断数组长度是否足够,当变量值数量不足时会触发数组越界,进而表现为空指针错误。 - 未处理空字符串:仅判断变量是否为
null,未处理变量为空字符串的情况,若变量值为空,split(",")会生成包含空字符串的数组,后续逻辑仍会执行导致异常。
解决方法与修正代码
修正要点
- 替换字符串插值为字符串拼接,或改用Groovy语言支持的
${变量名}插值(需在JSR223 Assertion中选择Groovy语言)。 - 访问数组固定索引前先判断数组长度,避免越界。
- 增加对变量是否为空字符串的判断。
- 对匹配的ID做trim处理,避免空格导致匹配失败。
修正后的代码(推荐使用Groovy语言)
// 获取dependentFeatID变量值 String dependentFeatID = vars.get("dependentFeatID") // 同时判断null和空字符串 if (dependentFeatID != null && !dependentFeatID.isEmpty()) { String[] dependentFeatIDs = dependentFeatID.split(",") if (dependentFeatIDs.length > 0) { // 先trim去除前后空格,避免匹配失败 String searchString = dependentFeatIDs[0].trim() log.info("searchString: " + searchString) // 访问数组索引前先判断长度,避免越界 if (dependentFeatIDs.length >= 3) { log.info(dependentFeatIDs[1].trim() + " AND " + dependentFeatIDs[2].trim()) } String featureIDs = vars.get("featureIDs") if (featureIDs != null && !featureIDs.isEmpty()) { String[] ids = featureIDs.split(",") if (ids.length >= 4) { log.info(ids[0].trim() + " AND " + ids[1].trim() + " AND " + ids[2].trim() + " AND " + ids[3].trim()) } boolean idFound = false for (String id : ids) { // 遍历的每个ID也做trim处理 if (id.trim().equals(searchString)) { idFound = true break } } AssertionResult.setFailure(!idFound) if (!idFound) { AssertionResult.setFailureMessage("ID not found in var_id: " + searchString) } } else { log.error("featureIDs变量为空或null") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("featureIDs变量为空或null") } } else { log.error("dependentFeatIDs数组为空") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("dependentFeatIDs数组为空") } } else { log.error("dependentFeatID变量为空或null") AssertionResult.setFailure(true) AssertionResult.setFailureMessage("dependentFeatID变量为空或null") }
额外配置建议
在JSR223 Assertion的Language下拉框中选择Groovy,Groovy对Java语法兼容性更好,性能远高于BeanShell,且支持更灵活的字符串插值写法(如log.info("searchString: ${searchString}"))。
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

