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() ?: ""
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
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
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()
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.
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
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() }
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
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) { ... } }
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
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 +
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]) { .. }
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
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.
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.
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; }
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 } }
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 } }
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 } }
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 } }
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 } }
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 }
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() {} }
New in CodeNarc 0.13
An empty static initializer was found. It is safe to remove it. Example:
class MyClass { static { } }
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 } }
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) { } } }
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() } }
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 } }
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 } }
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 { }
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
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)
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.
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.
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 } }
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.
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.
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.
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 }
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)
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 } }