JSR223预处理器用TimeShift函数仅部分迭代触发无效八进制数错误
JSR223 PreProcessor生成随机日期时出现"Invalid octal number"错误
问题场景
在JSR223 PreProcessor中尝试用JMeter的__timeShift函数生成指定范围内的随机日期,代码如下:
${__timeShift(yyyy-MM-dd,${__time(yyyy-MM-dd,)},P${__Random(0,90)}D,,entryDate)}; log.info("entryDate " + "${entryDate}"); ${__timeShift(yyyy-MM-dd,${entryDate},P${__Random(0,90)}D,,exitDate)}; log.info("exitDate " + "${exitDate}");
测试时1个线程循环运行120秒,部分迭代能正常打印日期,但部分迭代抛出编译错误:
2023-01-04 21:01:31,903 ERROR o.a.j.m.JSR223PreProcessor: Problem in JSR223 script, JSR223 PreProcessor javax.script.ScriptException: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: Script472.groovy: 1: Invalid octal number @ line 1, column 9 @ line 1, column 9. 2023-02-08; ^ 1 error ...(省略堆栈信息)
问题原因
JMeter会优先解析JSR223脚本中的内置函数,将函数替换成执行结果后,再把完整内容交给Groovy编译执行。当生成的日期包含以0开头且后续数字为8或9的日/月(比如2023-08-09)时,替换后的脚本行变成2023-08-09;,Groovy会把08、09识别为八进制数,但八进制数仅允许0-7的数字,因此触发"Invalid octal number"编译错误。只有当日期的日/月是01-07时不会触发错误,这就是部分迭代正常、部分报错的根本原因。
规避方案
方案1:使用Groovy原生API生成随机日期(推荐)
完全用Groovy的日期类实现,避免JMeter函数与Groovy语法冲突,同时性能更优:
import java.time.LocalDate import java.time.format.DateTimeFormatter // 定义日期格式 def dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") // 生成当前日期往后0-90天的entryDate def entryDate = LocalDate.now().plusDays(new Random().nextInt(91)).format(dateFormatter) vars.put("entryDate", entryDate) log.info("entryDate " + entryDate) // 基于entryDate生成往后0-90天的exitDate def exitDate = LocalDate.parse(entryDate, dateFormatter).plusDays(new Random().nextInt(91)).format(dateFormatter) vars.put("exitDate", exitDate) log.info("exitDate " + exitDate)
方案2:正确调用JMeter函数(避免直接嵌入脚本)
如果需要保留JMeter函数的使用方式,不要直接在脚本中写${变量},而是通过vars.get()获取变量值,并用evaluate()执行函数调用:
// 生成entryDate evaluate('${__timeShift(yyyy-MM-dd,${__time(yyyy-MM-dd,)},P${__Random(0,90)}D,,entryDate)}') def entryDate = vars.get("entryDate") log.info("entryDate " + entryDate) // 生成exitDate evaluate('${__timeShift(yyyy-MM-dd,' + entryDate + ',P${__Random(0,90)}D,,exitDate)}') def exitDate = vars.get("exitDate") log.info("exitDate " + exitDate)
内容的提问来源于stack exchange,提问作者JustNatural
相关产品推荐
相关产品推荐

