无日志上的空指针异常

huangapple go评论87阅读模式
英文:

No NullPointerException on the logs

问题

在我的Java代码中,我遇到了奇怪的行为,我想请教一些建议。
在我编写的多线程应用程序中,我有以下代码:

scratchDir.resolve(directoryTree).toFile().mkdirs();

由于一个错误,scratchDir 对象为null,我本来希望在日志中看到堆栈跟踪,但是关于错误的信息却没有任何记录。
我已经检查了代码,我从未尝试捕获NullPointerException。

以下是完整的方法代码:

@Override
public void write(JsonObject jsonObject) throws FileSystemException {
    Path directoryTree = getRelativePath();
    scratchDir.resolve(directoryTree).toFile().mkdirs();
    String newFileName = getHashFileName(jsonObject);
    Path filePath = scratchDir.resolve(directoryTree).resolve(newFileName);
    logger.debug("Write new file Json {} to persistent storage dir {}", newFileName, scratchDir);
    File outputFile = filePath.toFile();
    if (outputFile.exists()) {
        throw new FileAlreadyExistsException(filePath.toString());
    }
    try (FileWriter fileWriter = new FileWriter(outputFile)) {
        fileWriter.write(jsonObject.toString());
        fileWriter.flush();
    } catch (Exception e) {
        logger.error(e);
    }
}

为什么我的日志中没有异常信息?

英文:

I have a strange behaviour in my java code I would like to ask some advice.
In a multithreading application I wrote this code:

scratchDir.resolve(directoryTree).toFile().mkdirs();

For a bug the Object scratchDir is null, I was expecting a stack trace on the logs but there's nothing about the error.
I have checked the code and I never try to catch the NullPointerException.

Here is the complete method code:

    @Override
    public void write(JsonObject jsonObject) throws FileSystemException {
        Path directoryTree = getRelativePath();
        scratchDir.resolve(directoryTree).toFile().mkdirs();
        String newFileName = getHashFileName(jsonObject);
        Path filePath = scratchDir.resolve(directoryTree).resolve(newFileName);
        logger.debug("Write new file Json {} to persistent storage dir {}", newFileName, scratchDir);
        File outputFile = filePath.toFile();
        if (outputFile.exists()) {
            throw new FileAlreadyExistsException(filePath.toString());
        }
        try (FileWriter fileWriter = new FileWriter(outputFile)) {
            fileWriter.write(jsonObject.toString());
            fileWriter.flush();
        } catch (Exception e) {
            logger.error(e);
        }
    }

Why I don't have the exception in my logs?

答案1

得分: 1

为什么你要这么做?

正确的方法是:

Files.createDirectories(scratchDir.resolve(directoryTree));

不要混合使用旧的和新的 API。旧的 mkdirs() API 要求你检查返回值;如果返回值为 false,操作失败,而且你不会获得异常来告诉你失败的原因。这也是为什么首次引入新 API 的主要原因。

你确定你没有弄混 - 这是真正的问题吗?你提供的那一行代码将什么都不做(既不创建目录,也不记录日志或抛出异常)。上面的代码在无法创建目录时会抛出异常,所以首先检查这个。

然后,如果确实运行了这行代码,但没有记录任何内容,那么你可能在某个你没有粘贴的地方捕获了 NPE(NullPointerException)并将其丢弃。

英文:

Why are you doing this?

The proper way to do this is:

Files.createDirectories(scratchDir.resolve(directoryTree));

don't mix old and new API. The old mkdirs() api DEMANDS that you check the return value; if it is false, the operation failed, and you do not get the benefit of an exception to tell you why. This is the primary reason for why there is a new API in the first place.

Are you sure you aren't confused - and that is the actual problem? The line as you have it will happily do absolutely nothing whatsoever (no directories, and no logs or exceptions). The line above will throw if it can't make the directories, so start there.

Then, if that line IS being run and nothing is logged, then you've caught the NPE and discarded it, someplace you didn't paste.

huangapple
  • 本文由 发表于 2020年8月7日 21:39:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/63303043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定