Basic Rules ("rulesets/basic.xml")

AddEmptyString Rule

New in CodeNarc 0.13

Finds empty string literals which are being added. This is an inefficient way to convert any type to a String.

Examples:

    // do not add empty strings to things
    def a = '' + 123
    def b = method('' + property)

    // these examples are OK and do not trigger violations
    def c = 456.toString()
    def d = property?.toString() ?: ""

AssignmentInConditional Rule

New in CodeNarc 0.13

An assignment operator (=) was used in a conditional test. This is usually a typo, and the comparison operator (==) was intended.

Example of violations:

    if ((value = true)) {
        // should be ==
    }

    while (value = true) {
        // should be ==
    }

    (value = true) ? x : y
    (value = true) ?: x

    // the following code has no violations
    if (value == true) {
    }

    value == true ? x : y
    value == true ?: x

BigDecimalInstantiation Rule

Checks for calls to the java.math.BigDecimal constructors that take a double value as the first parameter. As described in the BigDecimal javadoc, the results from these constructors can be somewhat unpredictable, and their use is generally not recommended. This is because some numbers, such as 0.1, cannot be represented exactly as a double.

For instance, executing println new BigDecimal(0.1) prints out 0.1000000000000000055511151231257827021181583404541015625.

Here is an example of code that produces a violation:

    def b1 = new BigDecimal(0.1)               // violation
    def b2 = new java.math.BigDecimal(23.45d)  // violation

BooleanGetBoolean Rule

New in CodeNarc 0.13

This rule catches usages of java.lang.Boolean.getBoolean(String) which reads a boolean from the System properties. It is often mistakenly used to attempt to read user input or parse a String into a boolean. It is a poor piece of API to use; replace it with System.properties['prop̈́'].

Example of violations:

    // produces violation
    Boolean.getBoolean(value)

    // zero or two parameters is OK, must be different method
    Boolean.getBoolean(value, 1)
    Boolean.getBoolean()

BooleanMethodReturnsNull Rule

Since CodeNarc 0.11

Checks for a method with Boolean return type that returns an explicit null. A method that returns either Boolean.TRUE, Boolean.FALSE or null is an accident waiting to happen. This method can be invoked as though it returned a value of type boolean, and the compiler will insert automatic unboxing of the Boolean value. If a null value is returned, this will result in a NullPointerException.

BrokenOddnessCheck Rule

New in CodeNarc 0.13

The code uses x % 2 == 1 to check to see if a value is odd, but this won't work for negative numbers (e.g., (-5) % 2 == -1). If this code is intending to check for oddness, consider using x & 1 == 1, or x % 2 != 0.

Examples:

    if (x % 2 == 1) { }             // violation
    if (method() % 2 == 1) { }      // violation

    if (x & 1 == 1) { }             // OK
    if (x % 2 != 0) { }             // OK

CloneableWithoutClone Rule

Checks for classes that implement the java.lang.Cloneable interface without implementing the clone() method.

Here is an example of code that produces a violation:

    class BadClass implements Cloneable {
        def someMethod()
    }

ConfusingTernary Rule

Since CodeNarc 0.12

In a ternary expression avoid negation in the test. For example, rephrase: (x != y) ? diff : same as: (x == y) ? same : diff. Consistent use of this rule makes the code easier to read. Also, this resolves trivial ordering problems, such as "does the error case go first?" or "does the common case go first?".

Example:

    (x != y) ? diff : same      // triggers violation
    (!x) ? diff : same          // triggers violation

    (x == y) ? same : diff      // OK
    (x) ? same : diff           // OK
    
    // this is OK, because of GroovyTruth there is no inverse of != null
    (x != null) ? diff : same

    // this is OK, because of GroovyTruth there is no inverse of != true
    (x != true) ? diff : same

    // this is OK, because of GroovyTruth there is no inverse of != false
    (x != false) ? diff : same

CompareToWithoutComparable Rule

Since CodeNarc 0.12

If you implement a compareTo method then you should also implement the Comparable interface. If you don't then you could possibly get an exception if the Groovy == operator is invoked on your object. This is an issue fixed in Groovy 1.8 but present in previous versions.

Here is an example of code that produces a violation:

    class BadClass {
        int compareTo(Object o) { ... }
    }

ConsecutiveLiteralAppends Rule

New in CodeNarc 0.13

Violations occur when method calls to append(Object) are chained together with literals as parameters. The chained calls can be joined into one invocation.

Example of violations:

    writer.append('foo').append('bar')      // strings can be joined
    writer.append('foo').append(5)          // string and number can be joined
    writer.append('Hello').append("$World") // GString can be joined

Example of passing code:

    // usage not chained invocation
    writer.append('Hello')
    writer.append('World')

    writer.append(null).append(5)           // nulls cannot be joined

    writer.append().append('Hello')             // no arg append is unknown
    writer.append('a', 'b').append('Hello')     // two arg append is unknown

ConsecutiveStringConcatenation Rule

New in CodeNarc 0.13

Catches concatenation of two string literals on the same line. These can safely by joined. In Java, the Java compiler will join two String literals together and place them in the Constant Pool. However, Groovy will not because the plus() method may override the + operator.

Examples:

    // Violations
    def a = 'Hello' + 'World'   // should be 'HelloWorld'
    def b = "$Hello" + 'World'  // should be "${Hello}World"
    def c = 'Hello' + "$World"  // should be "Hello${World}"
    def d = 'Hello' + 5         // should be 'Hello5'
    def e = 'Hello' + '''
                        world   // should be joined
                      '''
    def f = '''Hello
                  ''' + 'world'   // should be joined


    // Not Violations
    def g = 'Hello' +           // OK because of line break
                'World'
    def h = 'Hello' + null      // OK because not a string
    def i = 'Hello' + method()  // OK because not a string
    def j = 'Hello' - "$World"  // OK because not +

ConstantIfExpression Rule

Checks for if statements with a constant value for the if boolean expression, such as true, false, null, or a literal constant value. These if statements can be simplified or avoided altogether. Examples of violations include:

    if (true) { .. }
    if (false) { .. }
    if (Boolean.TRUE) { .. }
    if (Boolean.FALSE) { .. }
    if (null) { .. }
    if (0) { .. }
    if (99.7) { .. }
    if ("") { .. }
    if ("abc") { .. }
    if ([:]) { .. }
    if ([a:123, b:456]) { .. }
    if ([a, b, c]) { .. }

ConstantTernaryExpression Rule

Checks for ternary expressions with a constant value for the boolean expression, such as true, false, null, or a literal constant value. Examples of violations include:

    true ? x : y
    false ? x : y
    Boolean.TRUE ? x : y
    Boolean.FALSE ? x : y
    null ? x : y
    0 ? x : y
    99.7 ? x : y
    "" ? x : y
    "abc" ? x : y
    [:] ? x : y
    [a:123, b:456] ? x : y
    [a, b, c] ? x : y

The rule also checks for the same types of constant values for the boolean expressions within the "short" ternary expressions, also known as the "Elvis" operator, e.g.:

    true ?: y
    null ?: y
    99.7 ?: y
    "abc" ?: y
    [:] ?: y
    [a, b, c] ?: y

DeadCode Rule

Since CodeNarc 0.11

Dead code appears after a return statement or an exception is thrown. If code appears after one of these statements then it will never be executed and can be safely deleted.

DoubleNegative Rule

Since CodeNarc 0.11

There is no point in using a double negative, it is always positive. For instance !!x can always be simplified to x. And !(!x) can as well.

DuplicateCaseStatement Rule

Since CodeNarc 0.11

Check for duplicate case statements in a switch block, such as two equal integers or strings. Here are some examples of code that produces violations:

            switch( 0 ) {
                case 1: break;
                case 2: break;
                case 2: break;          // violation
            }

            switch( "test" ) {
                case "$a": break;
                case "$a": break;       // ok; only flags constant values (not GStrings)
                case "ab": break;
                case "ab": break;       // violation
                case "abc": break;
            }

EmptyCatchBlock Rule

Checks for empty catch blocks. In most cases, exceptions should not be caught and ignored (swallowed).

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            doSomething
        } catch(MyException e) {
            // should do something here
        }
    }

EmptyElseBlock Rule

Checks for empty else blocks. Empty else blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        if (x==23) {
            println 'ok'
        } else {
            // empty
        }
    }

EmptyFinallyBlock Rule

Checks for empty finally blocks. Empty finally blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            doSomething()
        } finally {
            // empty
        }
    }

EmptyForStatement Rule

Checks for empty for blocks. Empty for statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        for (int i=0; i < 23; i++) {
            // empty
        }
    }

EmptyIfStatement Rule

Checks for empty if statements. Empty if statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        if (x==23) {
            // empty
        }
    }

EmptyInstanceInitializer Rule

New in CodeNarc 0.13

An empty class instance initializer was found. It is safe to remove it. Example:

    class MyClass {
        { }     // empty instance initializer, not a closure
    }

EmptyMethod Rule

New in CodeNarc 0.13

A method was found without an implementation. If the method is overriding or implementing a parent method, then mark it with the @Override annotation. This rule should not be used with Java 5 code because you cannot put @Override on a method implementing an interface. Use with Java 6 and higher.

Example of violations:

    class MyClass {

        // violation, empty method
        public void method1() {}

        // violation, empty method
        def method2() {}

        // OK because of @Override
        @Override
        public void method3() {}
    }

    abstract class MyBaseClass {
        // OK, handled by EmptyMethodInAbstractClass Rule
        public void method() {}
    }

EmptyStaticInitializer Rule

New in CodeNarc 0.13

An empty static initializer was found. It is safe to remove it. Example:

    class MyClass {
        static { }
    }

EmptySwitchStatement Rule

Checks for empty switch statements. Empty switch statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        switch(myVariable) {
            // empty
        }
    }

EmptySynchronizedStatement Rule

Checks for empty synchronized statements. Empty synchronized statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    class MyClass {
        def myMethod() {
            synchronized(lock) {
            }
        }
    }

EmptyTryBlock Rule

Checks for empty try blocks. Empty try blocks are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        try {
            // empty
        } catch(MyException e) {
            e.printStackTrace()
        }
    }

EmptyWhileStatement Rule

Checks for empty while statements. Empty while statements are confusing and serve no purpose.

Here is an example of code that produces a violation:

    def myMethod() {
        while (!stopped) {
            // empty
        }
    }

EqualsAndHashCode Rule

Checks that if either the boolean equals(Object) or the int hashCode() methods are overridden within a class, then both must be overridden.

Here is an example of code that produces a violation:

    class MyClass {
        boolean equals(Object object) {
            // do something
        }
    }

And so does this:

    class MyClass {
        int hashCode() {
            return 0
        }
    }

ExplicitArrayListInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of ArrayList. In Groovy, it is best to write new ArrayList() as [], which creates the same object.

ExplicitCallToAndMethod Rule

Since CodeNarc 0.11

This rule detects when the and(Object) method is called directly in code instead of using the & operator. A groovier way to express this: a.and(b) is this: a & b. This rule can be configured to ignore this.and(Object) using the ignoreThisReference property. It defaults to true, so even and(x) will not trigger a violation. The default is true because and appears commonly in Grails criteria.

ExplicitCallToCompareToMethod Rule

Since CodeNarc 0.11

This rule detects when the compareTo(Object) method is called directly in code instead of using the <=>, >, >=, <, and <= operators. A groovier way to express this: a.compareTo(b) is this: a <=> b, or using the other operators. Here are some other ways to write groovier code:

    a.compareTo(b) == 0               // can be replaced by: a == b
    a.compareTo(b)                    // can be replaced by: a <=> b
    a.compareTo(b) > 0                // can be replaced by: a > b
    a.compareTo(b) >= 0               // can be replaced by: a >= b
    a.compareTo(b) < 0                // can be replaced by: a < b
    a.compareTo(b) <= 0               // can be replaced by: a <= b

This rule can be configured to ignore this.compareTo(Object) using the ignoreThisReference property. It defaults to false, so even compareTo(x) will trigger a violation.

ExplicitCallToDivMethod Rule

Since CodeNarc 0.11

This rule detects when the div(Object) method is called directly in code instead of using the / operator. A groovier way to express this: a.div(b) is this: a / b. This rule can be configured to ignore div.xor(Object) using the ignoreThisReference property. It defaults to false, so even div(x) will trigger a violation.

ExplicitCallToEqualsMethod Rule

Since CodeNarc 0.11

This rule detects when the equals(Object) method is called directly in code instead of using the == or != operator. A groovier way to express this: a.equals(b) is this: a == b and a groovier way to express : !a.equals(b) is: a != b. This rule can be configured to ignore this.equals(Object) using the ignoreThisReference property. It defaults to false, so even equals(x) will trigger a violation.

ExplicitCallToGetAtMethod Rule

Since CodeNarc 0.11

This rule detects when the getAt(Object) method is called directly in code instead of using the [] index operator. A groovier way to express this: a.getAt(b) is this: a[b]. This rule can be configured to ignore this.getAt(Object) using the ignoreThisReference property. It defaults to false, so even getAt(x) will trigger a violation.

ExplicitCallToLeftShiftMethod Rule

Since CodeNarc 0.11

This rule detects when the leftShift(Object) method is called directly in code instead of using the << operator. A groovier way to express this: a.leftShift(b) is this: a << b. This rule can be configured to ignore this.leftShift(Object) using the ignoreThisReference property. It defaults to false, so even leftShift(x) will trigger a violation.

ExplicitCallToMinusMethod Rule

Since CodeNarc 0.11

This rule detects when the minus(Object) method is called directly in code instead of using the - operator. A groovier way to express this: a.minus(b) is this: a - b. This rule can be configured to ignore minus.xor(Object) using the ignoreThisReference property. It defaults to false, so even minus(x) will trigger a violation.

ExplicitCallToMultiplyMethod Rule

Since CodeNarc 0.11

This rule detects when the multiply(Object) method is called directly in code instead of using the * operator. A groovier way to express this: a.multiply(b) is this: a * b. This rule can be configured to ignore this.multiply(Object) using the ignoreThisReference property. It defaults to false, so even multiply(x) will trigger a violation.

ExplicitCallToModMethod Rule

Since CodeNarc 0.11

This rule detects when the mod(Object) method is called directly in code instead of using the % operator. A groovier way to express this: a.mod(b) is this: a % b. This rule can be configured to ignore this.mod(Object) using the ignoreThisReference property. It defaults to false, so even mod(x) will trigger a violation.

ExplicitCallToOrMethod Rule

Since CodeNarc 0.11

This rule detects when the or(Object) method is called directly in code instead of using the | operator. A groovier way to express this: a.or(b) is this: a | b. This rule can be configured to ignore this.or(Object) using the ignoreThisReference property. It defaults to true, so even or(x) will not trigger a violation. This is the default because it is commonly used in Grails criteria.

ExplicitCallToPlusMethod Rule

Since CodeNarc 0.11

This rule detects when the plus(Object) method is called directly in code instead of using the + operator. A groovier way to express this: a.plus(b) is this: a + b. This rule can be configured to ignore this.plus(Object) using the ignoreThisReference property. It defaults to false, so even plus(x) will trigger a violation.

ExplicitCallToPowerMethod Rule

Since CodeNarc 0.11

This rule detects when the power(Object) method is called directly in code instead of using the ** operator. A groovier way to express this: a.power(b) is this: a ** b. This rule can be configured to ignore this.power(Object) using the ignoreThisReference property. It defaults to false, so even power(x) will trigger a violation.

ExplicitCallToRightShiftMethod Rule

Since CodeNarc 0.11

This rule detects when the rightShift(Object) method is called directly in code instead of using the >> operator. A groovier way to express this: a.rightShift(b) is this: a >> b. This rule can be configured to ignore this.rightShift(Object) using the ignoreThisReference property. It defaults to false, so even rightShift(x) will trigger a violation.

ExplicitCallToXorMethod Rule

Since CodeNarc 0.11

This rule detects when the xor(Object) method is called directly in code instead of using the ^ operator. A groovier way to express this: a.xor(b) is this: a ^ b. This rule can be configured to ignore this.xor(Object) using the ignoreThisReference property. It defaults to false, so even xor(x) will trigger a violation.

ExplicitGarbageCollection Rule

Since CodeNarc 0.12

Calls to System.gc(), Runtime.getRuntime().gc(), and System.runFinalization() are not advised. Code should have the same behavior whether the garbage collection is disabled using the option -Xdisableexplicitgc or not. Moreover, "modern" JVMs do a very good job handling garbage collections. If memory usage issues unrelated to memory leaks develop within an application, it should be dealt with JVM options rather than within the code itself.

ExplicitHashMapInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of HashMap. In Groovy, it is best to write new HashMap() as [:], which creates the same object.

ExplicitHashSetInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of HashSet. In Groovy, it is best to write new HashSet() as [] as Set, which creates the same object.

ExplicitLinkedListInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of LinkedList. In Groovy, it is best to write new LinkedList() as [] as Queue, which creates the same object.

ExplicitStackInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of Stack. In Groovy, it is best to write new Stack() as [] as Stack, which creates the same object.

ExplicitTreeSetInstantiation Rule

Since CodeNarc 0.11

This rule checks for explicit calls to the no-argument constructor of TreeSet. In Groovy, it is best to write new TreeSet() as [] as SortedSet, which creates the same object.

GroovyLangImmutable Rule

New in CodeNarc 0.13

The groovy.lang.Immutable annotation has been deprecated and replaced by groovy.transform.Immutable. Do not use the Immutable in groovy.lang.

Example of violations:

  @Immutable
  class Person { }

  @groovy.lang.Immutable
  class Person { }

  import groovy.lang.Immutable as Imtl
  @Imtl
  class Person { }

  // the following code is OK
  @groovy.transform.Immutable
  class Person { }

  import groovy.transform.Immutable
  @Immutable
  class Person { }

  import groovy.transform.*
  @Immutable
  class Person { }

  import groovy.transform.Immutable as Imtl
  @Imtl
  class Person { }

GStringAsMapKey Rule

Since CodeNarc 0.11

A GString should not be used as a map key since its hashcode is not guaranteed to be stable. Consider calling key.toString().

Here is an example of code that produces a violation:

    Map map = ["${someRef}" : 'invalid' ]       // violation

IntegerGetInteger Rule

New in CodeNarc 0.13

This rule catches usages of java.lang.Integer.getInteger(String, ...) which reads an Integer from the System properties. It is often mistakenly used to attempt to read user input or parse a String into an Integer. It is a poor piece of API to use; replace it with System.properties['prop'].

Example of violations:

    // violations
    Integer.getInteger(value)
    Integer.getInteger(value, radix)

    // zero or more than 2 parameters is OK, must be different method
    Integer.getInteger()
    Integer.getInteger(value, radix, locale)

InvertedIfElse Rule

Since CodeNarc 0.11

An inverted if-else statement is one in which there is a single if statement with a single else branch and the boolean test of the if is negated. For instance if (!x) false else true. It is usually clearer to write this as if (x) true else false.

RemoveAllOnSelf Rule

Since CodeNarc 0.11

Don't use removeAll to clear a collection. If you want to remove all elements from a collection c, use c.clear, not c.removeAll(c). Calling c.removeAll(c) to clear a collection is less clear, susceptible to errors from typos, less efficient and for some collections, might throw a ConcurrentModificationException.

ReturnFromFinallyBlock Rule

Checks for a return from within a finally block. Returning from a finally block is confusing and can hide the original exception.

Here is an example of code that produces a violation:

    int myMethod() {
        try {
            doSomething()
            return 0
        } catch(Exception e) {
            return -1
        } finally {
            return 99               // violation
        }
    }

ReturnsNullInsteadOfEmptyArray Rule

Since CodeNarc 0.11

If you have a method or closure that returns an array, then when there are no results return a zero-length (empty) array rather than null. It is often a better design to return a zero-length array rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method.

ReturnsNullInsteadOfEmptyCollection Rule

Since CodeNarc 0.11

If you have a method or closure that returns a collection, then when there are no results return a zero-length (empty) collection rather than null. It is often a better design to return a zero-length collection rather than a null reference to indicate that there are no results (i.e., an empty list of results). This way, no explicit check for null is needed by clients of the method.

SerialVersionUID Rule

Since CodeNarc 0.11

A serialVersionUID is normally intended to be used with Serialization. It needs to be of type long, static, and final. Also, it should have a visibility modifier such as public or private. Providing no modifier creates a Property and Groovy generates a getter, which is probably not intended.

SerializableClassMustDefineSerialVersionUID Rule

New in CodeNarc 0.13

Classes that implement Serializable should define a serialVersionUID. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If you don't define serialVersionUID, the system will make one by hashing most of your class's features. Then if you change anything, the UID will change and Java won't let you reload old data.

An example of a missing serialVersionUID:

    class MyClass imlements Serializable {
        // missing serialVersionUID
    }

SimpleDateFormatMissingLocale Rule

Since CodeNarc 0.12

Be sure to specify a Locale when creating a new instance of SimpleDateFormat; the class is locale-sensitive. If you instantiate SimpleDateFormat without a Locale parameter, it will format the date and time according to the default Locale. Both the pattern and the Locale determine the format. For the same pattern, SimpleDateFormat may format a date and time differently if the Locale varies.

    // violation, missing locale
    new SimpleDateFormat('pattern')

    // OK, includes locale
    new SimpleDateFormat('pattern', Locale.US)

    // OK, includes a variable that perhaps is a locale
    new SimpleDateFormat('pattern', locale)

ThrowExceptionFromFinallyBlock

Checks for throwing an exception from within a finally block. Throwing an exception from a finally block is confusing and can hide the original exception.

Here is an example of code that produces a violation:

    int myMethod() {
        try {
            doSomething()
            throw new Exception()
        } finally {
            println 'finally'
            throw new Exception()   // violation
        }
    }