You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 14:49:50