Disable a particular Checkstyle rule for a particular line of code?
Asked Answered
T

9

228

I have a Checkstyle validation rule configured in my project, that prohibits to define class methods with more than 3 input parameters. The rule works fine for my classes, but sometimes I have to extend third-party classes, which do not obey this particular rule.

Is there a possibility to instruct Checkstyle that a certain method should be silently ignored?

BTW, I ended up with my own wrapper of Checkstyle: qulice.com (see Strict Control of Java Code Quality)

Towbin answered 26/10, 2010 at 11:32 Comment(0)
P
350

Check out the use of the supressionCommentFilter at https://checkstyle.sourceforge.io/filters/suppressioncommentfilter.html. You'll need to add the module to your checkstyle.xml

<module name="SuppressionCommentFilter"/>

and it's configurable. Thus you can add comments to your code to turn off checkstyle (at various levels) and then back on again through the use of comments in your code. E.g.

//CHECKSTYLE:OFF
public void someMethod(String arg1, String arg2, String arg3, String arg4) {
//CHECKSTYLE:ON

Or even better, use this more tweaked version:

<module name="SuppressionCommentFilter">
    <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
    <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
    <property name="checkFormat" value="$1"/>
</module>

which allows you to turn off specific checks for specific lines of code:

//CHECKSTYLE.OFF: IllegalCatch - Much more readable than catching 7 exceptions
catch (Exception e)
//CHECKSTYLE.ON: IllegalCatch

*Note: you'll also have to add the FileContentsHolder:

<module name="FileContentsHolder"/>

See also

<module name="SuppressionFilter">
    <property name="file" value="docs/suppressions.xml"/>
</module>

under the SuppressionFilter section on that same page, which allows you to turn off individual checks for pattern matched resources.

So, if you have in your checkstyle.xml:

<module name="ParameterNumber">
   <property name="id" value="maxParameterNumber"/>
   <property name="max" value="3"/>
   <property name="tokens" value="METHOD_DEF"/>
</module>

You can turn it off in your suppression xml file with:

<suppress id="maxParameterNumber" files="YourCode.java"/>

Another method, now available in Checkstyle 5.7 is to suppress violations via the @SuppressWarnings java annotation. To do this, you will need to add two new modules (SuppressWarningsFilter and SuppressWarningsHolder) in your configuration file:

<module name="Checker">
   ...
   <module name="SuppressWarningsFilter" />
   <module name="TreeWalker">
       ...
       <module name="SuppressWarningsHolder" />
   </module>
</module> 

Then, within your code you can do the following:

@SuppressWarnings("checkstyle:methodlength")
public void someLongMethod() throws Exception {

or, for multiple suppressions:

@SuppressWarnings({"checkstyle:executablestatementcount", "checkstyle:methodlength"})
public void someLongMethod() throws Exception {

NB: The "checkstyle:" prefix is optional (but recommended). According to the docs the parameter name have to be in all lowercase, but practice indicates any case works.

Phylogeny answered 26/10, 2010 at 11:52 Comment(11)
Remember to add FileContentsHolder on the TreeWalter. See https://mcmap.net/q/120055/-checkstyle-suppressioncommentfilter-not-ignoring-specified-ruleAdularia
if you use //CHECKSTYLE.OFF: and then forget to turn it on again, will it remain checked off only in the file containing //CHECKSTYLE.OFF: or all subsequently processed files also?Concentration
@Roland, it remains off just for the duration of that test class.Phylogeny
@ChrisKnight is there some documentation where I can read this specific info?Concentration
@Roland, I am aware of this from personal experience and am not sure if or where it is documented.Phylogeny
Using checkstyle 6.0, I have to wrap the parameter name in curly braces, as per checkstyle.sourceforge.net/config.html#SuppressWarningsFilterConny
For SuppressionCommentFilter to work, make sure you add the FileContentHolder to TreeWalkerFielding
how can I determine which particular check is generating the warning, so I know which one to turn off?Invincible
"the parameter name have to be in all lowercase." @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance") worked just as well for me as the lower-case equivalent.Potty
Since checkstyle 8.1 the SuppressionCommentFilter should be under the TreeWalker, and the FileContentHolder is not necessary (available) anymore.Beadruby
The docs that I'm seeing for SuppressWarningsFilter say that the parameter names are case-insensitive, not that they have to be all lowercase (checkstyle.sourceforge.net/…): "Name of check in annotation is case-insensitive".Labored
A
84

If you prefer to use annotations to selectively silence rules, this is now possible using the @SuppressWarnings annotation, starting with Checkstyle 5.7 (and supported by the Checkstyle Maven Plugin 2.12+).

First, in your checkstyle.xml, add the SuppressWarningsHolder module to the TreeWalker:

<module name="TreeWalker">
    <!-- Make the @SuppressWarnings annotations available to Checkstyle -->
    <module name="SuppressWarningsHolder" />
</module>

Next, enable the SuppressWarningsFilter there (as a sibling to TreeWalker):

<!-- Filter out Checkstyle warnings that have been suppressed with the @SuppressWarnings annotation -->
<module name="SuppressWarningsFilter" />

<module name="TreeWalker">
...

Now you can annotate e.g. the method you want to exclude from a certain Checkstyle rule:

@SuppressWarnings("checkstyle:methodlength")
@Override
public boolean equals(Object obj) {
    // very long auto-generated equals() method
}

The checkstyle: prefix in the argument to @SuppressWarnings is optional, but I like it as a reminder where this warning came from. The rule name must be lowercase.

Lastly, if you're using Eclipse, it will complain about the argument being unknown to it:

Unsupported @SuppressWarnings("checkstyle:methodlength")

You can disable this Eclipse warning in the preferences if you like:

Preferences:
  Java
  --> Compiler
  --> Errors/Warnings
  --> Annotations
  --> Unhandled token in '@SuppressWarnings': set to 'Ignore'
Areopagus answered 21/3, 2014 at 10:36 Comment(1)
I nominate this as the checked answer, as I think this is the solution that should work best in most cases.Beadruby
N
35

What also works well is the SuppressWithNearbyCommentFilter which uses individual comments to suppress audit events.

For example

// CHECKSTYLE IGNORE check FOR NEXT 1 LINES
public void onClick(View view) { ... }

To configure a filter so that CHECKSTYLE IGNORE check FOR NEXT var LINES avoids triggering any audits for the given check for the current line and the next var lines (for a total of var+1 lines):

<module name="SuppressWithNearbyCommentFilter">
    <property name="commentFormat" value="CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES"/>
    <property name="checkFormat" value="$1"/>
    <property name="influenceFormat" value="$2"/>
</module>

http://checkstyle.sourceforge.net/config.html

Nutritionist answered 17/2, 2012 at 21:51 Comment(3)
I'd change the regex to CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES? which will make the ignore command more readable. (You'll be able to use "CHECKSTYLE IGNORE check FOR NEXT 1 LINE" and "CHECKSTYLE IGNORE check FOR NEXT 3 LINES").Pacesetter
@matt3o12 CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINE also works for me (it matches both line and lines).Joost
Updated link - that current one doesn't reference it any more. checkstyle.sourceforge.io/apidocs/com/puppycrawl/tools/…Doby
C
8

Every answer refering to SuppressWarningsFilter is missing an important detail. You can only use the all-lowercase id if it's defined as such in your checkstyle-config.xml. If not you must use the original module name.

For instance, if in my checkstyle-config.xml I have:

<module name="NoWhitespaceBefore"/>

I cannot use:

@SuppressWarnings({"nowhitespacebefore"})

I must, however, use:

@SuppressWarnings({"NoWhitespaceBefore"})

In order for the first syntax to work, the checkstyle-config.xml should have:

<module name="NoWhitespaceBefore">
  <property name="id" value="nowhitespacebefore"/>
</module>

This is what worked for me, at least in the CheckStyle version 6.17.

Charwoman answered 22/4, 2016 at 12:22 Comment(1)
you are a lifesaver! Your answer plus Henrik's solved my problem! Heaps of thanks to you guys!Seaward
R
2

I had difficulty with the answers above, potentially because I set the checkStyle warnings to be errors. What did work was SuppressionFilter: http://checkstyle.sourceforge.net/config_filters.html#SuppressionFilter

The drawback of this is that the line range is stored in a separate suppresssions.xml file, so an unfamiliar developer may not immediately make the connection.

Ranch answered 3/11, 2016 at 14:42 Comment(0)
D
1
<module name="Checker">
    <module name="SuppressionCommentFilter"/>
    <module name="TreeWalker">
        <module name="FileContentsHolder"/>
    </module>
</module>

To configure a filter to suppress audit events between a comment containing line BEGIN GENERATED CODE and a comment containing line END GENERATED CODE:

<module name="SuppressionCommentFilter">
  <property name="offCommentFormat" value="BEGIN GENERATED CODE"/>
  <property name="onCommentFormat" value="END GENERATED CODE"/>
</module>

//BEGIN GENERATED CODE
@Override
public boolean equals(Object obj) { ... } // No violation events will be reported

@Override
public int hashCode() { ... } // No violation events will be reported
//END GENERATED CODE

See more

Deliadelian answered 18/8, 2017 at 14:38 Comment(0)
H
1

In case if you are using checkstyle from qulice mvn plugin (https://github.com/teamed/qulice) you may use the following suppresion:

// @checkstyle <Rulename> (N lines)
... code with violation(s)

or


/**
 * ...
 * @checkstyle <Rulename> (N lines)
 * ...
 */
 ... code with violation(s)
Helping answered 28/1, 2021 at 21:1 Comment(0)
K
0

Try https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathFilter

You can configure it as:


<module name="SuppressionXpathFilter">
  <property name="file" value="suppressions-xpath.xml"/>
  <property name="optional" value="false"/>
</module>
        

Generate Xpath suppressions using the CLI with the -g option and specify the output using the -o switch.

https://checkstyle.sourceforge.io/cmdline.html#Command_line_usage

Here's an ant snippet that will help you set up your Checkstyle suppressions auto generation; you can integrate it into Maven using the Antrun plugin.


<target name="checkstyleg">
    <move file="suppressions-xpath.xml"
      tofile="suppressions-xpath.xml.bak"
      preservelastmodified="true"
      force="true"
      failonerror="false"
      verbose="true"/>
    <fileset dir="${basedir}"
                    id="javasrcs">
    <include name="**/*.java" />
    </fileset>
    <pathconvert property="sources"
                            refid="javasrcs"
                            pathsep=" " />
    <loadfile property="cs.cp"
                        srcFile="../${cs.classpath.file}" />
    <java classname="${cs.main.class}"
                logError="true">
    <arg line="-c ../${cs.config} -p ${cs.properties} -o ${ant.project.name}-xpath.xml -g ${sources}" />
    <classpath>
        <pathelement path="${cs.cp}" />
        <pathelement path="${java.class.path}" />
    </classpath>
</java>
<condition property="file.is.empty" else="false">
     <length file="${ant.project.name}-xpath.xml" when="equal" length="0" />
   </condition>
   <if>
     <equals arg1="${file.is.empty}" arg2="false"/>
     <then>
     <move file="${ant.project.name}-xpath.xml"
      tofile="suppressions-xpath.xml"
      preservelastmodified="true"
      force="true"
      failonerror="true"
  verbose="true"/>
   </then>
</if>
    </target>

The suppressions-xpath.xml is specified as the Xpath suppressions source in the Checkstyle rules configuration. In the snippet above, I'm loading the Checkstyle classpath from a file cs.cp into a property. You can choose to specify the classpath directly.

Or you could use groovy within Maven (or Ant) to do the same:


import java.nio.file.Files
import java.nio.file.StandardCopyOption  
import java.nio.file.Paths

def backupSuppressions() {
  def supprFileName = 
      project.properties["checkstyle.suppressionsFile"]
  def suppr = Paths.get(supprFileName)
  def target = null
  if (Files.exists(suppr)) {
    def supprBak = Paths.get(supprFileName + ".bak")
    target = Files.move(suppr, supprBak,
        StandardCopyOption.REPLACE_EXISTING)
    println "Backed up " + supprFileName
  }
  return target
}

def renameSuppressions() {
  def supprFileName = 
      project.properties["checkstyle.suppressionsFile"]
  def suppr = Paths.get(project.name + "-xpath.xml")
  def target = null
  if (Files.exists(suppr)) {
    def supprNew = Paths.get(supprFileName)
    target = Files.move(suppr, supprNew)
    println "Renamed " + suppr + " to " + supprFileName
  }
  return target
}

def getClassPath(classLoader, sb) {
  classLoader.getURLs().each {url->
     sb.append("${url.getFile().toString()}:")
  }
  if (classLoader.parent) {
     getClassPath(classLoader.parent, sb)
  }
  return sb.toString()
}

backupSuppressions()

def cp = getClassPath(this.class.classLoader, 
    new StringBuilder())
def csMainClass = 
      project.properties["cs.main.class"]
def csRules = 
      project.properties["checkstyle.rules"]
def csProps = 
      project.properties["checkstyle.properties"]

String[] args = ["java", "-cp", cp,
    csMainClass,
    "-c", csRules,
"-p", csProps,
"-o", project.name + "-xpath.xml",
"-g", "src"]

ProcessBuilder pb = new ProcessBuilder(args)
pb = pb.inheritIO()
Process proc = pb.start()
proc.waitFor()

renameSuppressions()

The only drawback with using Xpath suppressions---besides the checks it doesn't support---is if you have code like the following:

package cstests;

public interface TestMagicNumber {
  static byte[] getAsciiRotator() {
    byte[] rotation = new byte[95 * 2];
    for (byte i = ' '; i <= '~'; i++) {
      rotation[i - ' '] = i;
      rotation[i + 95 - ' '] = i;
    }
    return rotation;
  }
}

The Xpath suppression generated in this case is not ingested by Checkstyle and the checker fails with an exception on the generated suppression:

<suppress-xpath
       files="TestMagicNumber.java"
       checks="MagicNumberCheck"
       query="/INTERFACE_DEF[./IDENT[@text='TestMagicNumber']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='getAsciiRotator']]/SLIST/LITERAL_FOR/SLIST/EXPR/ASSIGN[./IDENT[@text='i']]/INDEX_OP[./IDENT[@text='rotation']]/EXPR/MINUS[./CHAR_LITERAL[@text='' '']]/PLUS[./IDENT[@text='i']]/NUM_INT[@text='95']"/>

Generating Xpath suppressions is recommended when you have fixed all other violations and wish to suppress the rest. It will not allow you to select specific instances in the code to suppress. You can , however, pick and choose suppressions from the generated file to do just that.

SuppressionXpathSingleFilter is better suited to identify and suppress a specific rule, file or error message. You can configure multiple filters identifying each one by the id attribute.

https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathSingleFilter

Klimesh answered 27/11, 2019 at 13:15 Comment(0)
B
0

You can also surround the code for which you want to disable a particular warning with these special comments:

// CHECKSTYLE:DISABLE:<CheckName>
<Your code goes here>
// CHECKSTYLE:ENABLE:<CheckName>

e.g: // CHECKSTYLE:DISABLE:ParameterNumberCheck

You can find the full list of supported checks here (see Direct Known Subclasses).

Burnsides answered 16/8, 2021 at 6:31 Comment(1)
Your solution doesn't work. See accepted answerWhitmer

© 2022 - 2024 — McMap. All rights reserved.