Azure负载测试JMeter调用外部JAR遇java.nio.file.NoSuchFileException问题
问题解决:Azure负载测试中JMeter脚本的DICOM转换路径错误
问题背景
执行基于JMeter的Azure负载测试时,通过自定义Dicom.jar将JPG转换为DICOM格式,该JAR本地单独运行正常,但在Azure负载测试中出现文件找不到的错误,导致转换失败。
问题分析
从日志可明确以下关键问题:
- JMeter工作目录为
/,但上传的配置文件(Dicom.jar、Images-1-min.jpg)实际存放于/root/artifacts目录 - 脚本中使用相对路径调用
Dicom.jar和输入JPG,导致进程无法找到文件 - 脚本生成随机文件名的DCM文件,但后续尝试读取固定的
output.dcm,与实际生成的文件名不匹配
解决方案
1. 修改Groovy前置处理器脚本
更新脚本,使用绝对路径访问所有文件,并确保读取的DCM文件与生成的文件名一致:
import java.nio.file.Files; import java.nio.file.Paths; import org.apache.commons.lang3.RandomStringUtils; // 定义Azure负载测试中配置文件的固定存放目录 def artifactsDir = "/root/artifacts" String ext = "dcm"; String outputFileName = String.format("%s.%s", RandomStringUtils.randomAlphanumeric(8), ext); // 生成输出文件的绝对路径 String outputFilePath = Paths.get(artifactsDir, outputFileName).toString(); try { log.error("Current Path : " + System.getProperty("user.dir")); // 使用绝对路径引用所有文件 String command = String.format("java -jar %s %s %s", Paths.get(artifactsDir, "Dicom.jar").toString(), Paths.get(artifactsDir, "Images-1-min.jpg").toString(), outputFilePath); log.error("Command is: " + command); def process = command.execute(); // 同时捕获标准输出和错误输出 def output = new StringBuilder(); def errorOutput = new StringBuilder(); process.waitForProcessOutput(output, errorOutput); process.waitFor(); // 日志输出进程的所有输出,便于排查转换错误 log.error("Process output: " + output.toString()); log.error("Process error output: " + errorOutput.toString()); try { // 读取生成的随机文件名的DCM文件 byte[] binaryData = Files.readAllBytes(Paths.get(outputFilePath)); sampler.getArguments().removeAllArguments(); sampler.addNonEncodedArgument('', new String(binaryData), ''); // 设置请求体为原始二进制格式 sampler.setPostBodyRaw(true); // 可选:设置Content-Type为DICOM对应的MIME类型 sampler.getHeaderManager().add(new org.apache.jmeter.protocol.http.control.Header("Content-Type", "application/dicom")); } catch (Exception ex) { log.error("Error modifying and sending DICOM file: " + ex.getMessage()); throw ex; } finally { // 可选:清理临时生成的DCM文件,避免磁盘占用 try { Files.deleteIfExists(Paths.get(outputFilePath)); } catch (cleanupEx) { log.error("Error cleaning up temporary file: " + cleanupEx.getMessage()); } } } catch (Exception e) { log.error("Error executing command: " + e.toString()); }
关键修改点:
- 固定使用
/root/artifacts作为配置文件根目录(Azure负载测试的默认存放路径) - 所有文件引用均使用绝对路径,避免工作目录差异导致的找不到文件问题
- 捕获进程的错误输出,便于排查
Dicom.jar执行时的内部错误 - 读取脚本生成的随机文件名DCM文件,而非固定的
output.dcm - 添加临时文件清理逻辑,避免负载测试过程中磁盘空间耗尽
2. 调整Config.yaml配置
移除configurationFiles中的output.dcm,因为它是脚本生成的临时文件,无需提前上传:
displayName: DICOM testPlan: DICOM Load Test.jmx description: '' engineInstances: 1 testId: fcba51b1-b4fd-4ae7-a3c2-694080bfd662 splitAllCSVs: False configurationFiles: - Dicom.jar - Images-1-min.jpg failureCriteria: [] env: - name: SUBSCRIPTION_KEY value: xxxxxxx - name: APIM_FHIR_URL value: xxxxxxx.azure-api.net - name: TENANT_ID value: xxxx - name: THREADS_NUM value: 1 - name: THREADS_LOOP value: 1 autoStop: errorPercentage: 90 timeWindow: 60
3. 额外验证点
- 确保
Dicom.jar在/root/artifacts目录下有可执行权限(Azure负载测试通常会自动处理,但如果仍有问题,可在脚本中添加chmod +x /root/artifacts/Dicom.jar命令) - 检查
Dicom.jar的依赖是否完整,确保在Azure负载测试环境中所有依赖都能被加载
内容的提问来源于stack exchange,提问作者One Developer
相关产品推荐
相关产品推荐

