可能会抛出“NullPointerException”; “setCredentials()”可以返回null

时间:2018-06-06 09:40:34

标签: java nullpointerexception sonarqube

为什么声纳会将此标记为可能的NullPointerException?

public void credentialSetter(@Headers Map<String, Object> headersMap) {

    SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            setCredentials(USERNAMETOKEN, this.username).getDocumentElement());

    SoapHeader pTxt = new SoapHeader(new QName(NAMESPACE_URL, P), 
            setCredentials(P, this.pas).getDocumentElement());

它同时在“setCredentials”处展开,我尝试使用if语句来检查它是否为空,还尝试检查它是否在实际方法中为空以覆盖所有基础。

private Document setCredentials(String credential, String value) {
    StringWriter writer = new StringWriter();
    JAXBContext context;
    try {
        if (null != credential && null != value) {
            context = JAXBContext.newInstance(value.getClass());
            QName qName = new QName(NAMESPACE_URL, credential);
            JAXBElement<String> root = new JAXBElement<>(qName, String.class, value);
            context.createMarshaller().marshal(root, writer);
            return DocumentBuilderFactory.newInstance().newDocumentBuilder()
                    .parse(new InputSource(new StringReader(writer.toString())));
        }
    } catch (Exception e) {
        LOG.error("Error converting {} to XML {}", credential, e);
    }
    return null;
}

3 个答案:

答案 0 :(得分:0)

您在getDocumentElement()返回值上调用setCredentials's,可以是null。如果是这样的话,你会得到一个例外。这就是Sonar警告你的原因。

好的,您已将setCredentials的主要逻辑包含在try-catch中,但如果出现错误,您仍会返回null

就像一般概念一样,你可以这样做:

Document credentials = setCredentials(USERNAMETOKEN, this.username);
if (null != credentials){
    SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            credentials.getDocumentElement());
}

答案 1 :(得分:0)

setCredentials()的最后一行返回null,因此以下两行可能会抛出NullPointerException。将您的逻辑包装在空检查中并不会对此有所帮助,因为它仍有可能返回null

SoapHeader uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
        setCredentials(USERNAMETOKEN, this.username).getDocumentElement());

SoapHeader pTxt = new SoapHeader(new QName(NAMESPACE_URL, P), 
        setCredentials(P, this.pas).getDocumentElement());

解决方案是使用以下

SoapHeader uName;
Document document = setCredentials(USERNAMETOKEN, this.username);
if (document != null) {
    uName = new SoapHeader(new QName(NAMESPACE_URL, USERNAMETOKEN), 
            document.getDocumentElement());
} else {
    // whatever you need to do
}

答案 2 :(得分:0)

您的setCredentials()方法可以返回null:return null;

Sonar正在检测这个+你使用返回的对象到.getDocumentElement()的事实,这会在NPE中推断,因为它是一个空引用。

如果要覆盖它(不建议这样做)返回Document的新实例而不是null(假设方法newInstance()实际返回一个新实例):

private Document setCredentials(String credential, String value) {
StringWriter writer = new StringWriter();
JAXBContext context;
try {
    if (null != credential && null != value) {
        context = JAXBContext.newInstance(value.getClass());
        QName qName = new QName(NAMESPACE_URL, credential);
        JAXBElement<String> root = new JAXBElement<>(qName, String.class, value);
        context.createMarshaller().marshal(root, writer);
        return DocumentBuilderFactory.newInstance().newDocumentBuilder()
                .parse(new InputSource(new StringReader(writer.toString())));
    }
} catch (Exception e) {
    LOG.error("Error converting {} to XML {}", credential, e);
}
return DocumentBuilderFactory.newInstance();

}