Affects PMD Version:
6.27.0
Description:
With PMD 6.26.0 no warning is show, updating PMD to 6.27.0 throws this warning:
Exception Stacktrace:
[INFO] --- maven-pmd-plugin:3.13.0:pmd (pmd) @ cm-api ---
[WARNING] Exception applying rule CloseResource on file /cm-api/src/main/java/com/demo/ex/problem/DataAccessExceptionMapper.java, continuing with next rule
java.lang.NullPointerException: Cannot invoke "net.sourceforge.pmd.lang.java.ast.TypeNode.getType()" because "refType" is null
at net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule.isResourceTypeOrSubtype (CloseResourceRule.java:336)
at net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule.getResourceVariables (CloseResourceRule.java:178)
at net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule.checkForResources (CloseResourceRule.java:159)
at net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule.visit (CloseResourceRule.java:153)
at net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration.jjtAccept (ASTMethodDeclaration.java:37)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:220)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:267)
at net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration.jjtAccept (ASTClassOrInterfaceBodyDeclaration.java:44)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:220)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:262)
at net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBody.jjtAccept (ASTClassOrInterfaceBody.java:35)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:220)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:232)
at net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration.jjtAccept (ASTClassOrInterfaceDeclaration.java:56)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:220)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:417)
at net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration.jjtAccept (ASTTypeDeclaration.java:39)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:220)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visit (AbstractJavaRule.java:392)
at net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit.jjtAccept (ASTCompilationUnit.java:44)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.visitAll (AbstractJavaRule.java:163)
at net.sourceforge.pmd.lang.java.rule.AbstractJavaRule.apply (AbstractJavaRule.java:157)
at net.sourceforge.pmd.lang.rule.AbstractDelegateRule.apply (AbstractDelegateRule.java:336)
at net.sourceforge.pmd.RuleSet.apply (RuleSet.java:575)
at net.sourceforge.pmd.RuleSets.apply (RuleSets.java:148)
at net.sourceforge.pmd.SourceCodeProcessor.processSource (SourceCodeProcessor.java:194)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache (SourceCodeProcessor.java:107)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode (SourceCodeProcessor.java:89)
at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode (SourceCodeProcessor.java:51)
at net.sourceforge.pmd.processor.PmdRunnable.call (PmdRunnable.java:78)
at net.sourceforge.pmd.processor.PmdRunnable.call (PmdRunnable.java:24)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.Executors$RunnableAdapter.call (Executors.java:515)
at java.util.concurrent.FutureTask.run (FutureTask.java:264)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:630)
at java.lang.Thread.run (Thread.java:832)
[WARNING] There are 1 PMD processing errors:
[WARNING] /cm-api/src/main/java/com/demo/ex/problem/DataAccessExceptionMapper.java: NullPointerException: Cannot invoke "net.sourceforge.pmd.lang.java.ast.TypeNode.getType()" because "refType" is null
Running PMD through: Maven
Thanks for reporting. Would you mind to share the file /cm-api/src/main/java/com/demo/ex/problem/DataAccessExceptionMapper.java so that we can verify the fix on our side?
Thanks for reporting. Would you mind to share the file
/cm-api/src/main/java/com/demo/ex/problem/DataAccessExceptionMapper.javaso that we can verify the fix on our side?
Sure, here is it:
package com.demo.ex.problem;
import java.net.URI;
import java.sql.SQLException;
import java.util.UUID;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.jooq.exception.DataAccessException;
import org.postgresql.util.PSQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
@Provider
public class DataAccessExceptionMapper implements ExceptionMapper<DataAccessException> {
private static final Logger log = LoggerFactory.getLogger(DataAccessExceptionMapper.class);
@Context
UriInfo uriInfo;
@Override
public Response toResponse(DataAccessException exception) {
boolean uniqueViolation = false;
var cause = exception.getCause();
if (cause instanceof SQLException) {
var sqlex = (SQLException) cause;
uniqueViolation = sqlex.getSQLState().equals("23505");
}
ProblemBuilder builder = Problem.builder()
.withStatus(uniqueViolation ? Status.CONFLICT : Status.INTERNAL_SERVER_ERROR)
.withTitle(uniqueViolation ? "Duplicate resource creation" : "A data access error occurred")
.withInstance(URI.create(uriInfo.getPath()));
UUID uuid = UUID.randomUUID();
if (log.isDebugEnabled()) {
String format = "Code %s: %s";
if (exception.getCause() != null) {
if (exception.getCause().getCause() != null) {
builder.withDetail(String.format(format, uuid,
exception.getCause().getCause().getMessage()));
} else {
builder.withDetail(String.format(format, uuid,
exception.getCause().getMessage()));
}
} else {
builder.withDetail(String.format(format, uuid,
exception.getMessage()));
}
} else {
builder.withDetail(String.format("Code: %s", uuid));
}
if (log.isInfoEnabled()) {
String logMessage = "[{}] Data access error occurred: {}";
if (cause instanceof PSQLException) {
var pgsqlex = (PSQLException) cause;
log.info(logMessage, uuid, pgsqlex.getServerErrorMessage());
} else {
log.info(logMessage, uuid, cause.getMessage());
}
}
return ProblemResponse.toResponse(builder.build());
}
}
It turns out, this is actually a duplicate of #2755
It's the same NPE (at at net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule.isResourceTypeOrSubtype (CloseResourceRule.java:336)).
I just was confused about the new NPE message from jdk14 (JEP 358: Helpful NullPointerExceptions) ...