开发者

Java error: New exception is thrown in catch block, original stack trace may be lost

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    logger.error("Custom message", sqlex);
    **throw new CustomApplicationException("Custom message", sqlex);**
}

In the above example, on the bold line, I am getting PMD error as "New exception i开发者_StackOverflow中文版s thrown in catch block, original stack trace may be lost". I know this question has been asked many times also there are many online references available for the same. I have tried all the ways possible. But still I am not able to remove this PMD error. Please let me know whats wrong in this code slice. Thanks in advance!


I don't think there's anything wrong with that code.

But I also, don't think that PMD will / should give that error for that code. IIRC, you get that error with something like this:

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    throw new CustomApplicationException("Custom message");  // no cause!
}

It is possible that you have an old version of PMD or that someone has been "improving" the PMD rules that you are using.


Need to modify exception class as follow to preserve original stack trace

try {
    // code which throws exception.
} catch (SQLException sqlex) {
    throw new CustomApplicationException("Any Message", sqlex);
}

CustomApplicationException.java

public class CustomApplicationException extends RuntimeException {

  public CustomApplicationException() {
  }

  public CustomApplicationException(String message) {
    super(message);
  }

  public CustomApplicationException(String message, Throwable cause) {
    super(message, cause);
  }

}


Code checkers are great things for picking up problems. However in this case your code is fine and PMD probably being over protective. Check the documentation in PMD about the error and see if there is anything else you may need to consider. Then if your are still happy with your code you can add a //NOPMD tag to it to get PMD to ignore the line. I cannot remember if this is automatic or you have to configure PMD to look for //NOPMD.

Note that inline exceptions to PMD checks like this is not really recommended either and certainly should not be regarded as a best practice. But with code checkers like PMD there will be the occasional flag which you want to ignore for some reason.


What version of PMD are you using? You may be seeing a false positive that is fixed in a newer version. (The link is just to one place where such a false positive is fixed. There may be more than one.)

Depending on what version of Java you are using and exactly how you throw another Exception in a catch block, it is indeed possible to lose the full stack trace information. If you are using the latest PMD version and you get this complaint, you may want to report an error with PMD on the sourceforge page and then temporarily disable that specific instance of that complaint as others have said.


I have the same issue, we ignore the PMD issue in the pmd config file like below.

<?xml version="1.0" encoding="UTF-8"?>
<description>Custom Rulesets for production code</description>
<exclude-pattern>.*/src/test/java/.*</exclude-pattern>
<ruleset xmlns="http://pmd.sourceforge.net/ruleset/5.5.3">    
<rule ref="category/java/bestpractices.xml/PreserveStackTrace">
        <exclude name="PreserveStackTrace"/>
    </rule>
</ruleset>

we use maven, so used this config file in the maven plugin.

Ref : https://pmd.github.io/pmd-6.0.1/pmd_rules_java_bestpractices.html#preservestacktrace


It is necessary to throw the exception that has been triggered:

try {
        // code which throws exception.
    } catch (SQLException sqlex) {
        /* You can show a specific log here (See below) */
        throw sqlex;
    }

If you want to show an specific log, you can use a logger:

/* Use this imports */
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
/* Declare as global variable */
private Logger logger = LoggerFactory.getLogger(this.getClass());
public Logger getLogger() {
    return logger;
}
public void setLogger(Logger logger) {
    this.logger = logger;
}
/* Use in any place */
logger.error(" an error ");
logger.trace(" operational trace ");
logger.debug(" specific trace for debugging ");

If you are using Maven, declare in your pom.xml:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-simple</artifactId>
                <version>1.5.2</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜