ProperLogger - make class-name configurable and requirement of static-final logger (deprecate LoggerIsNotStaticFinal)
This commit is contained in:
@ -190,7 +190,7 @@ for (int i = 0; i < 10; i++) {
|
||||
<description>
|
||||
The method Object.finalize() is called by the garbage collector on an object when garbage collection determines
|
||||
that there are no more references to the object. It should not be invoked by application logic.
|
||||
|
||||
|
||||
Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -211,7 +211,7 @@ void foo() {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcatchingnpe">
|
||||
<description>
|
||||
Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the
|
||||
Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the
|
||||
original error, causing other, more subtle problems later on.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -245,7 +245,7 @@ public class Foo {
|
||||
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidCatchingThrowableRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcatchingthrowable">
|
||||
<description>
|
||||
Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as
|
||||
Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as
|
||||
OutOfMemoryError that should be exposed and managed separately.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -372,8 +372,8 @@ public class A {
|
||||
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidFieldNameMatchingMethodNameRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidfieldnamematchingmethodname">
|
||||
<description>
|
||||
It can be confusing to have a field name with the same name as a method. While this is permitted,
|
||||
having information (field) and actions (method) is not clear naming. Developers versed in
|
||||
It can be confusing to have a field name with the same name as a method. While this is permitted,
|
||||
having information (field) and actions (method) is not clear naming. Developers versed in
|
||||
Smalltalk often prefer this approach as the methods denote accessor methods.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -634,9 +634,9 @@ boolean x = (y == Double.NaN);
|
||||
class="net.sourceforge.pmd.lang.java.rule.errorprone.BeanMembersShouldSerializeRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#beanmembersshouldserialize">
|
||||
<description>
|
||||
If a class is a bean, or is referenced by a bean directly or indirectly it needs to be serializable.
|
||||
Member variables need to be marked as transient, static, or have accessor methods in the class. Marking
|
||||
variables as transient is the safest and easiest modification. Accessor methods should follow the Java
|
||||
If a class is a bean, or is referenced by a bean directly or indirectly it needs to be serializable.
|
||||
Member variables need to be marked as transient, static, or have accessor methods in the class. Marking
|
||||
variables as transient is the safest and easiest modification. Accessor methods should follow the Java
|
||||
naming conventions, i.e. for a variable named foo, getFoo() and setFoo() accessor methods should be provided.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -1324,7 +1324,7 @@ public class MyActivity extends Activity {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotthrowexceptioninfinally">
|
||||
<description>
|
||||
Throwing exceptions within a 'finally' block is confusing since they may mask other exceptions
|
||||
Throwing exceptions within a 'finally' block is confusing since they may mask other exceptions
|
||||
or code defects.
|
||||
Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block"
|
||||
</description>
|
||||
@ -1415,8 +1415,8 @@ public class Count {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptycatchblock">
|
||||
<description>
|
||||
Empty Catch Block finds instances where an exception is caught, but nothing is done.
|
||||
In most circumstances, this swallows an exception which should either be acted on
|
||||
Empty Catch Block finds instances where an exception is caught, but nothing is done.
|
||||
In most circumstances, this swallows an exception which should either be acted on
|
||||
or reported.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -1611,7 +1611,7 @@ public class Foo {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptystatementnotinloop">
|
||||
<description>
|
||||
An empty statement (or a semicolon by itself) that is not used as the sole body of a 'for'
|
||||
An empty statement (or a semicolon by itself) that is not used as the sole body of a 'for'
|
||||
or 'while' loop is probably a bug. It could also be a double semicolon, which has no purpose
|
||||
and should be removed.
|
||||
</description>
|
||||
@ -1742,7 +1742,7 @@ public class Foo {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptywhilestmt">
|
||||
<description>
|
||||
Empty While Statement finds all instances where a while statement does nothing.
|
||||
Empty While Statement finds all instances where a while statement does nothing.
|
||||
If it is a timing loop, then you should use Thread.sleep() for it; if it is
|
||||
a while loop that does a lot in the exit expression, rewrite it to make it clearer.
|
||||
</description>
|
||||
@ -1900,7 +1900,7 @@ protected void finalize() {
|
||||
<description>
|
||||
Methods named finalize() should not have parameters. It is confusing and most likely an attempt to
|
||||
overload Object.finalize(). It will not be called by the VM.
|
||||
|
||||
|
||||
Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -1932,9 +1932,9 @@ public class Foo {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeshouldbeprotected">
|
||||
<description>
|
||||
When overriding the finalize(), the new method should be set as protected. If made public,
|
||||
When overriding the finalize(), the new method should be set as protected. If made public,
|
||||
other classes may invoke it at inappropriate times.
|
||||
|
||||
|
||||
Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -2180,9 +2180,12 @@ public class Foo extends TestCase {
|
||||
since="2.0"
|
||||
message="The Logger variable declaration does not contain the static and final modifiers"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#loggerisnotstaticfinal">
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#loggerisnotstaticfinal"
|
||||
deprecated="true">
|
||||
<description>
|
||||
In most cases, the Logger reference can be declared as static and final.
|
||||
|
||||
This rule is deprecated. The rule is replaced by {% rule java/errorprone/ProperLogger %}.
|
||||
</description>
|
||||
<priority>2</priority>
|
||||
<properties>
|
||||
@ -2625,7 +2628,8 @@ class Foo{
|
||||
since="3.3"
|
||||
message="Logger should be defined private static final and have the correct class"
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#properlogger">
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#properlogger"
|
||||
typeResolution="true">
|
||||
<description>
|
||||
A logger should normally be defined private static final and be associated with the correct class.
|
||||
Private final Log log; is also allowed for rare cases where loggers need to be passed around,
|
||||
@ -2633,23 +2637,37 @@ with the restriction that the logger needs to be passed into the constructor.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<property name="version" value="2.0"/>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
//ClassOrInterfaceBodyDeclaration[FieldDeclaration//ClassOrInterfaceType[@Image='Log']
|
||||
and
|
||||
not(FieldDeclaration[@Final='true'][@Static='true'][@Private='true'][.//VariableDeclaratorId[@Image=$staticLoggerName]]
|
||||
and
|
||||
//ArgumentList//ClassOrInterfaceType[@Image = ancestor::ClassOrInterfaceDeclaration/@Image or @Image = ancestor::EnumDeclaration/@Image])
|
||||
and
|
||||
not(FieldDeclaration[@Final='true'][@Private='true'][.//VariableDeclaratorId[@Image='log']]
|
||||
[count(.//VariableInitializer)=0]
|
||||
[ancestor::ClassOrInterfaceBody//StatementExpression[.//PrimaryExpression/descendant::*[@Image='log']][count(.//AllocationExpression)=0]]
|
||||
)]
|
||||
//ClassOrInterfaceBodyDeclaration[
|
||||
FieldDeclaration//ClassOrInterfaceType[pmd-java:typeIs($loggerClass)]
|
||||
and not (
|
||||
(: check logger name :)
|
||||
(
|
||||
FieldDeclaration[$requireStaticFinalLogger][@Final=true()][@Static=true()][.//VariableDeclaratorId[@Image=$loggerName or @Image=$staticLoggerName]]
|
||||
|
|
||||
FieldDeclaration[$requireStaticFinalLogger = false()][.//VariableDeclaratorId[@Image=$loggerName or @Image=$staticLoggerName]]
|
||||
)
|
||||
and
|
||||
(: in place initialization with method argument pointing to current class (even for Enums) :)
|
||||
.//ArgumentList//ClassOrInterfaceType[@Image = ancestor::ClassOrInterfaceDeclaration/@Image or @Image = ancestor::EnumDeclaration/@Image]
|
||||
)
|
||||
and not (
|
||||
(: final logger initialized inside constructor :)
|
||||
FieldDeclaration[@Final=true()][@Private=true()][.//VariableDeclaratorId[@Image=$loggerName or @Image=$staticLoggerName]]
|
||||
[count(.//VariableInitializer)=0]
|
||||
[ancestor::ClassOrInterfaceBody//StatementExpression[.//PrimaryExpression/descendant::*[@Image=$loggerName or @Image=$staticLoggerName]][count(.//AllocationExpression)=0]]
|
||||
)
|
||||
]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
<property name="staticLoggerName" type="String" description="Name of the static Logger variable" value="LOG"/>
|
||||
<property name="staticLoggerName" type="String" description="deprecated!(Use 'loggerName' property) Name of the static Logger variable" value="LOG"/>
|
||||
<property name="loggerName" type="String" description="Name of the Logger variable" value="LOG"/>
|
||||
<property name="loggerClass" type="String" description="Class name of the logger" value="Log"/>
|
||||
<property name="requireStaticFinalLogger" type="Boolean" description="Static final logger is required" value="false"/>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
@ -2896,7 +2914,7 @@ new StringBuffer() // 16
|
||||
new StringBuffer(6) // 6
|
||||
new StringBuffer("hello world") // 11 + 16 = 27
|
||||
new StringBuffer('A') // chr(A) = 65
|
||||
new StringBuffer("A") // 1 + 16 = 17
|
||||
new StringBuffer("A") // 1 + 16 = 17
|
||||
|
||||
new StringBuilder() // 16
|
||||
new StringBuilder(6) // 6
|
||||
@ -3044,7 +3062,7 @@ public void foo() {
|
||||
class="net.sourceforge.pmd.lang.java.rule.errorprone.TestClassWithoutTestCasesRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#testclasswithouttestcases">
|
||||
<description>
|
||||
Test classes end with the suffix Test. Having a non-test class with that name is not a good practice,
|
||||
Test classes end with the suffix Test. Having a non-test class with that name is not a good practice,
|
||||
since most people will assume it is a test case. Test classes have test methods named testXXX.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
@ -3415,7 +3433,7 @@ class Foo {
|
||||
class="net.sourceforge.pmd.lang.rule.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#useproperclassloader">
|
||||
<description>
|
||||
In J2EE, the getClassLoader() method might not work as expected. Use
|
||||
In J2EE, the getClassLoader() method might not work as expected. Use
|
||||
Thread.currentThread().getContextClassLoader() instead.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
|
@ -29,6 +29,7 @@ public class Foo {
|
||||
<description><![CDATA[
|
||||
Ok, special case
|
||||
]]></description>
|
||||
<rule-property name="loggerName">log</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
@ -55,18 +56,19 @@ public enum Foo {
|
||||
<description><![CDATA[
|
||||
bug 1626232, a separate variable initialization should not confuse the rule
|
||||
]]></description>
|
||||
<rule-property name="loggerName">log</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
private String bar = "";
|
||||
private final Log log;
|
||||
Foo(Log log) {
|
||||
this.log = log;
|
||||
Foo(Log log1) {
|
||||
this.log = log1;
|
||||
}
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Enums shoud be accepted for declaration
|
||||
]]></description>
|
||||
@ -87,6 +89,99 @@ bug 1626232, extra loggers with different names are not allowed by default (use
|
||||
public class Foo {
|
||||
private static final Log LOG = LogFactory.getLog(Foo.class);
|
||||
private static final Log LOG2 = LogFactory.getLog(Foo.class + ".foo");
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Custom logger-class with invalid logger variable name
|
||||
]]></description>
|
||||
<rule-property name="loggerClass">MyLog</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
private static final MyLog INVALID_LOG_NAME = LogFactory.getLog(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Public logger
|
||||
]]></description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public static final Log LOG = LogFactory.getLog(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Public logger when static final required
|
||||
]]></description>
|
||||
<rule-property name="requireStaticFinalLogger">true</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public static final Log LOG = LogFactory.getLog(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Logger initialized as String constant from class name
|
||||
]]></description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
Log LOG = LogFactory.getLog(Foo.class.getName());
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Package-protected logger when static final is not required
|
||||
]]></description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
Log LOG = LogFactory.getLog(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Package-protected logger when static final is required
|
||||
]]></description>
|
||||
<rule-property name="requireStaticFinalLogger">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
Log LOG = LogFactory.getLog(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Check type resolution of logger
|
||||
]]></description>
|
||||
<rule-property name="loggerClass">org.slf4j.Logger</rule-property>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(Foo.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description><![CDATA[
|
||||
Check type resolution of logger with invalid logger specified
|
||||
]]></description>
|
||||
<rule-property name="loggerClass">org.slf4j.Logger</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(Bar.class);
|
||||
}
|
||||
]]> </code>
|
||||
</test-code>
|
||||
|
Reference in New Issue
Block a user