Spring 中的InterruptedException

问题描述 投票:0回答:1

我有一个调用服务的 spring 控制器,它使用命令行使用 7zip 进行压缩或解压缩(这是外部要求,必须是来自命令行的 7zip)

这里有一个简化的方法:

public File zipDirInPlace(File backupDir, int timeoutTime, TimeUnit timeUnit) throws IOException, InterruptedException {
    log.info("Zipping Folder {}", backupDir.getAbsolutePath());
    File zipDir = new File(backupDir.getPath() + ".zip");
    String[] command = { sevenZip, "a", zipDir.getAbsolutePath(), backupDir.getAbsolutePath() + "\\*" };
    // Create a process builder
    ProcessBuilder processBuilder = new ProcessBuilder(command);
    processBuilder.redirectErrorStream(true);
    // Start the process
    Process process = processBuilder.start();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
        String line;
        while ((line = reader.readLine()) != null) {
            log.info("7Zip claims: {}", line);
        }
    } catch (IOException e) {
        log.error("Error reading process output", e);
    }
    // Wait for the process to complete
    try {
        if (!process.waitFor(timeoutTime, timeUnit)) {
            // If time has passed, kill it.
            process.destroy();
            // If it is not killed in 1 minute again with more force.
            process.waitFor(1, TimeUnit.MINUTES);
            process.destroyForcibly();
        }
    } catch (InterruptedException e) {
        log.error("Running 7zip was interrupted", e);
        // Thread.currentThread().interrupt(); ??
        throw new InterruptedException(e);
    }

    int exitCode = process.exitValue();

    // Check the exit code
    if (exitCode == 0) {
        log.info("Packing completed successfully");
    } else {
        log.error("Could not zip {}", exitCode);
    }
    return zipDir;
}

预期的行为是这样的: 打包 zip,如果该过程花费的时间超过 10 分钟,则终止它。 一旦进程被终止,控制器就会获取 InterruptedException 并返回自定义错误响应:

catch (InterruptedException e) {

        throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR,

                "Something went wrong using 7zip from command line", e);

    }

问题: Sonar 抱怨控制器确实消耗了异常,而没有重新抛出它或中断线程。 然而: a) 重新抛出它没有意义,因为控制器将不会返回自定义 http 消息。 b)中断线程,该线程可能是控制器线程,也可能是服务线程,具体取决于它发生的位置以及 spring 内部的工作方式,这似乎不是一个明智的举动。 (参见中断Sping线程

如何正确处理异常? 我在理解 Thread.currentThread().interrupt(); 时有错误吗?是吗?

java spring thread-safety
1个回答
0
投票

要满足声纳,只需添加删除控制器中的

catch
,然后在控制器中写入
@ExceptionHandler

@ExceptionHandler(InterruptedException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Something went wrong using 7zip from command line")
public void handleInterrupt() {}

这应该产生相同的最终结果,但满足 Sonar,因为您现在删除了

catch
子句,您也可以在服务中删除它。

© www.soinside.com 2019 - 2024. All rights reserved.