Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchbrunze2019-02-12 18:46:57 -0500
committerchbrunze2019-02-12 18:46:57 -0500
commiteb07bb59a0faac17f280dec09d0b2589595dafec (patch)
treed0aeab12c86f2e5d3d5dfd5a3556e2993cafedee
parentd7a4b67818bb40fae4e64aa2ce43895c03a79f76 (diff)
parent76891239d44af75885fa4d806d2ec4c347710641 (diff)
downloadorg.eclipse.openk.build.codeconventions-eb07bb59a0faac17f280dec09d0b2589595dafec.tar.gz
org.eclipse.openk.build.codeconventions-eb07bb59a0faac17f280dec09d0b2589595dafec.tar.xz
org.eclipse.openk.build.codeconventions-eb07bb59a0faac17f280dec09d0b2589595dafec.zip
Task references: CICA-394
Reason: CIM Cache v2.20.0 - MS 5 - documentation, release and fixes Rationale: none Side effects: none # Conflicts: # .gitignore
-rw-r--r--.gitignore32
-rw-r--r--Jenkinsfile50
-rw-r--r--dev/pom.xml32
-rw-r--r--dev/src/main/java/.gitignore0
-rw-r--r--dev/src/main/resources/checkstyle/checkstyle-main.xml442
-rw-r--r--dev/src/main/resources/checkstyle/checkstyle-test.xml442
-rw-r--r--dev/src/main/resources/findbugs/findbugs-exclude.xml40
-rw-r--r--dev/src/main/resources/findbugs/findbugs-include.xml55
-rw-r--r--dev/src/main/resources/pmd/category/java/bestpractices.xml1508
-rw-r--r--dev/src/main/resources/pmd/category/java/categories.properties9
-rw-r--r--dev/src/main/resources/pmd/category/java/codestyle.xml2062
-rw-r--r--dev/src/main/resources/pmd/category/java/design.xml1652
-rw-r--r--dev/src/main/resources/pmd/category/java/documentation.xml154
-rw-r--r--dev/src/main/resources/pmd/category/java/errorprone.xml3392
-rw-r--r--dev/src/main/resources/pmd/category/java/multithreading.xml373
-rw-r--r--dev/src/main/resources/pmd/category/java/performance.xml1008
-rw-r--r--dev/src/main/resources/pmd/category/java/security.xml75
-rw-r--r--dev/src/main/resources/pmd/ruleset_java.xml111
-rw-r--r--dev/src/test/java/.gitignore0
-rw-r--r--dev/src/test/resources/.gitignore0
20 files changed, 11424 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index 9ce8af0..11c7b3a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,19 @@
-*target/
-*.checkstyle
-*.classpath
-*.eclipse-pmd
-*.idea
-*.iml
-*.project
-*.settings/
-*.springBeans
-*.log
-*.versionsBackup
-*.fbExcludeFilterFile
-*.fbIncludeFilterFile \ No newline at end of file
+**/*target/
+**/*.checkstyle
+**/*.classpath
+**/*.fbExcludeFilterFile
+**/*.fbIncludeFilterFile
+**/*.idea
+**/*.iml
+**/*.jdbc
+**/*.log
+**/*.project
+**/*.settings/
+**/*.springBeans
+**/*.versionsBackup
+**/launch.json
+**/node_modules/**
+**/package-lock.json
+bin/
+obj/
+.vs/ \ No newline at end of file
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..d8b02af
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,50 @@
+pipeline {
+ agent any
+ tools {
+ maven 'apache-maven-latest'
+ jdk 'jdk1.8.0-latest'
+ }
+
+ stages {
+ stage ('prepare') {
+ steps {
+ cleanWs()
+ checkout scm
+ }
+ }
+ stage ('build') {
+ steps {
+ sh 'mvn -version'
+ sh 'java -version'
+ sh 'mvn -f dev/pom.xml -B clean install -DskipTests'
+ }
+ }
+
+ stage ('test') {
+ steps {
+ sh 'mvn -version'
+ sh 'java -version'
+ sh 'mvn -f dev/pom.xml -B test'
+ }
+ }
+
+ stage ('deploy snapshot') {
+ when {
+ branch 'develop'
+ }
+ steps {
+ sh 'mvn -f dev/pom.xml -B deploy -DskipTests -DaltDeploymentRepository=repo.eclipse.org::default::https://repo.eclipse.org/content/repositories/openk-platform-snapshots/'
+ }
+ }
+
+ stage ('deploy release') {
+ when {
+ branch 'master'
+ }
+ steps {
+ sh 'mvn -f dev/pom.xml -B deploy -DskipTests -DaltDeploymentRepository=repo.eclipse.org::default::https://repo.eclipse.org/content/repositories/openk-platform-release/'
+ }
+ }
+ }
+}
+
diff --git a/dev/pom.xml b/dev/pom.xml
new file mode 100644
index 0000000..c84fe18
--- /dev/null
+++ b/dev/pom.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.eclipse.openk.build</groupId>
+ <artifactId>build-codeconventions</artifactId>
+ <name>${project.groupId}.${project.artifactId}</name>
+ <version>2.21.0-SNAPSHOT</version>
+
+ <packaging>jar</packaging>
+
+ <reporting>
+ <plugins>
+
+ <!-- no maven-project-info -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.9</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report></report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ </plugin>
+
+ </plugins>
+ </reporting>
+
+</project>
diff --git a/dev/src/main/java/.gitignore b/dev/src/main/java/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dev/src/main/java/.gitignore
diff --git a/dev/src/main/resources/checkstyle/checkstyle-main.xml b/dev/src/main/resources/checkstyle/checkstyle-main.xml
new file mode 100644
index 0000000..f26d73d
--- /dev/null
+++ b/dev/src/main/resources/checkstyle/checkstyle-main.xml
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+ This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+ Checkstyle-Configuration: Checkstyle
+ Description: none
+-->
+<module name="Checker">
+ <property name="severity" value="warning"/>
+ <module name="TreeWalker">
+ <module name="SuppressWarningsHolder"/>
+ <module name="MissingOverride">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Verifies that the java.lang.Override annotation is present when the {@inheritDoc} javadoc tag is present."/>
+ <property name="id" value="missingoverride"/>
+ </module>
+ <module name="ConstantName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that constants (static final fields) variables follow naming convention"/>
+ <property name="id" value="nameconstant"/>
+ </module>
+ <module name="LocalFinalVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that local final variables follow naming convention"/>
+ <property name="id" value="namelocalfinalvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="LocalVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that local variables follow naming convention"/>
+ <property name="id" value="namelocalvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="MemberName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that member variables (non-static fields) follow naming convention"/>
+ <property name="id" value="namemember"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="MethodName">
+ <property name="id" value="namemethod"/>
+ <property name="format" value="^([a-z][a-zA-Z0-9])+([_a-zA-Z0-9])*$"/>
+ </module>
+ <module name="PackageName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that package names follow naming convention"/>
+ <property name="id" value="namepackage"/>
+ <property name="format" value="^[a-z]+(\.[a-z_][a-z0-9_]*)*$"/>
+ </module>
+ <module name="ParameterName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that parameter names follow naming convention"/>
+ <property name="id" value="nameparam"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ <property name="accessModifiers" value="public"/>
+ </module>
+ <module name="StaticVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that static variables (static, non-final fields) follow naming convention"/>
+ <property name="id" value="namestaticvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that interface names follow naming convention"/>
+ <property name="id" value="nameinterface"/>
+ <property name="format" value="^I(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="INTERFACE_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that class names follow naming convention"/>
+ <property name="id" value="nameclass"/>
+ <property name="format" value="(^(([A-Z][a-z0-9]+)+[A-Z]?)$)|(^(([A-Z][a-z0-9]*)+([_][A-Z0-9][A-Za-z0-9]*)*)(?=(_Deserializer|_EndPoint|_Exporter|_Importer|_Mapper|_Modifier|_ReaderProvider|_Receiver|_Responder|_Serializer|_Task|_View|_Watcher|_WriterProvider|_DeserializationParameters|_ExecutionParameters|_ExportParameters|_ImportParameters|_MapperParameters|_ModificationParameters|_QueryParameters|_ReceiveParameters|_RequestParameters|_SerializationParameters|_WatchParameters|_DeserializationConfiguration|_ExecutionConfiguration|_ExportConfiguration|_ImportConfiguration|_MapperConfiguration|_ModificationConfiguration|_QueryConfiguration|_ReceiveConfiguration|_RequestConfiguration|_SerializationConfiguration|_TaskConfiguration|_WatchConfiguration|_WriterConfiguration)(Test)?$))"/>
+ <property name="tokens" value="CLASS_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that enum names follow naming convention"/>
+ <property name="id" value="nameenum"/>
+ <property name="format" value="^(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="ENUM_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that annotation names follow naming convention"/>
+ <property name="id" value="nameannotation"/>
+ <property name="format" value="^(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="ANNOTATION_DEF"/>
+ </module>
+ <module name="AvoidStarImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no import statements that use the * notation."/>
+ <property name="id" value="starimport"/>
+ </module>
+ <module name="IllegalImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for imports from a set of illegal packages"/>
+ <property name="id" value="illegalimports"/>
+ </module>
+ <module name="CustomImportOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that the groups of import declarations appear in the order specified by the user"/>
+ <property name="id" value="importcustomorder"/>
+ <property name="customImportOrderRules" value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE"/>
+ <property name="thirdPartyPackageRegExp" value="^com\."/>
+ <property name="specialImportsRegExp" value="^org\."/>
+ <property name="sortImportsInGroupAlphabetically" value="true"/>
+ </module>
+ <module name="RedundantImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for redundant import statements"/>
+ <property name="id" value="importredundant"/>
+ </module>
+ <module name="UnusedImports">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for unused import statements. "/>
+ <property name="id" value="importunused"/>
+ </module>
+ <module name="ParameterNumber">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the number of parameters of a method or constructor (default 7)"/>
+ <property name="id" value="paramsmax"/>
+ </module>
+ <module name="EmptyForInitializerPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding of an empty for initializer"/>
+ <property name="id" value="initpad"/>
+ </module>
+ <module name="EmptyForIteratorPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding of an empty for iterator"/>
+ <property name="id" value="iterpad"/>
+ </module>
+ <module name="EmptyLineSeparator">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty line separators"/>
+ <property name="id" value="lineseparator"/>
+ <property name="tokens" value="CLASS_DEF,CTOR_DEF,ENUM_DEF,INTERFACE_DEF,METHOD_DEF,STATIC_INIT"/>
+ </module>
+ <module name="MethodParamPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding between the identifier of a method definition, constructor definition, method call, or constructor invocation"/>
+ <property name="id" value="padmethodparam"/>
+ </module>
+ <module name="NoWhitespaceAfter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="[variations] Whitespaces allowed in array-initialization. Checks that there is no whitespace after a token."/>
+ <property name="id" value="whitespaceafter"/>
+ <property name="tokens" value="INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT"/>
+ </module>
+ <module name="NoWhitespaceBefore">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there is no whitespace before a token"/>
+ <property name="id" value="whitespacebefore"/>
+ </module>
+ <module name="OperatorWrap">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on how to wrap lines on operators"/>
+ <property name="id" value="wrapoperator"/>
+ <property name="tokens" value="QUESTION,COLON,EQUAL,NOT_EQUAL,DIV,PLUS,MINUS,STAR,MOD,SR,BSR,GE,GT,SL,LE,LT,BXOR,BOR,LOR,BAND,LAND,LITERAL_INSTANCEOF,TYPE_EXTENSION_AND"/>
+ </module>
+ <module name="ParenPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on the padding of parentheses"/>
+ <property name="id" value="padparentheses"/>
+ <property name="tokens" value="QUESTION,ANNOTATION,ANNOTATION_FIELD_DEF,LITERAL_CATCH,CTOR_CALL,CTOR_DEF,LITERAL_DO,ENUM_CONSTANT_DEF,EXPR,LITERAL_FOR,LITERAL_IF,RESOURCE_SPECIFICATION,METHOD_CALL,METHOD_DEF,LITERAL_NEW,SUPER_CTOR_CALL,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE"/>
+ </module>
+ <module name="TypecastParenPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on the padding of parentheses for typecasts."/>
+ <property name="id" value="padtypecastparen"/>
+ <property name="tokens" value="RPAREN,TYPECAST"/>
+ </module>
+ <module name="WhitespaceAfter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a token is followed by whitespace."/>
+ <property name="id" value="whitespaceafter"/>
+ <property name="tokens" value="COMMA,SEMI,TYPECAST"/>
+ </module>
+ <module name="ModifierOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that the order of modifiers conforms to the suggestions in the Java Language specification"/>
+ <property name="id" value="ordermodifier"/>
+ </module>
+ <module name="RedundantModifier">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for redundant modifiers"/>
+ <property name="id" value="modiredundant"/>
+ </module>
+ <module name="EmptyBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there are no empty catch blocks."/>
+ <property name="id" value="emptycatchblocks"/>
+ <property name="option" value="text"/>
+ <property name="tokens" value="LITERAL_CATCH"/>
+ </module>
+ <module name="EmptyBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty blocks."/>
+ <property name="id" value="emptyblock"/>
+ <property name="tokens" value="LITERAL_WHILE,LITERAL_TRY,LITERAL_FINALLY,LITERAL_DO,LITERAL_IF,LITERAL_ELSE,LITERAL_FOR,INSTANCE_INIT,STATIC_INIT"/>
+ </module>
+ <module name="EmptyCatchBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty catch blocks"/>
+ <property name="id" value="emptycatch"/>
+ </module>
+ <module name="LeftCurly">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for the placement of left curly braces ('{') for code blocks."/>
+ <property name="id" value="leftcurly"/>
+ </module>
+ <module name="RightCurly">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the placement of right curly braces"/>
+ <property name="id" value="rightcurly"/>
+ <property name="option" value="alone"/>
+ </module>
+ <module name="CovariantEquals">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that classes that define a covariant equals() method also override method equals(java.lang.Object)."/>
+ <property name="id" value="covariantequals"/>
+ </module>
+ <module name="DeclarationOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether parts of a class or interface declaration appear in the right order "/>
+ <property name="id" value="orderclass"/>
+ <property name="ignoreModifiers" value="true"/>
+ </module>
+ <module name="DefaultComesLast">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that the default is after all the cases in a switch statement."/>
+ <property name="id" value="defaultlast"/>
+ </module>
+ <module name="EmptyStatement">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Detects empty statements "/>
+ <property name="id" value="emptystatement"/>
+ </module>
+ <module name="EqualsHashCode">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that classes that override equals() also override hashCode()."/>
+ <property name="id" value="equalshashcode"/>
+ </module>
+ <module name="FallThrough">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for fall through in switch statements"/>
+ <property name="id" value="switchfallthrough"/>
+ </module>
+ <module name="HiddenField">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a local variable does not shadow a field that is defined in the same class."/>
+ <property name="id" value="varhidesfield"/>
+ <property name="tokens" value="VARIABLE_DEF"/>
+ </module>
+ <module name="IllegalInstantiation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for illegal instantiations where a factory method is preferred"/>
+ <property name="id" value="illegalinstantiation"/>
+ <property name="classes" value="java.lang.Boolean, java.lang.Integer, java.lang.Long"/>
+ </module>
+ <module name="IllegalThrows">
+ <metadata name="net.sf.eclipsecs.core.comment" value="This check can be used to ensure that types are not declared to be thrown. Declaring to throw java.lang.Error or java.lang.RuntimeException is almost never acceptable."/>
+ <property name="id" value="illegalthrows"/>
+ </module>
+ <module name="InnerAssignment">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for assignments in subexpressions, such as in 'String s = Integer.toString(i = 2);'"/>
+ <property name="id" value="innerassignment"/>
+ </module>
+ <module name="MagicNumber">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no 'magic numbers'"/>
+ <property name="id" value="magicnumber"/>
+ <property name="constantWaiverParentToken" value="TYPECAST,METHOD_CALL,EXPR,ARRAY_INIT,UNARY_MINUS,UNARY_PLUS,ELIST,STAR,ASSIGN,PLUS,MINUS,DIV,LITERAL_NEW"/>
+ </module>
+ <module name="MissingSwitchDefault">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that switch statement has 'default' clause."/>
+ <property name="id" value="switchdefault"/>
+ </module>
+ <module name="MultipleStringLiterals">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for multiple occurrences of the same string literal within a single file."/>
+ <property name="id" value="multistringliterals"/>
+ <property name="ignoreStringsRegexp" value="(^&quot;&quot;$)|(^&quot;[a-zA-Z_][0-9a-zA-Z_]*&quot;$)"/>
+ </module>
+ <module name="MultipleVariableDeclarations">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that each variable declaration is in its own statement and on its own line"/>
+ <property name="id" value="multivardeclr"/>
+ </module>
+ <module name="NestedForDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested for blocks to a specified depth (default = 1)."/>
+ <property name="id" value="fordepth"/>
+ <property name="max" value="2"/>
+ </module>
+ <module name="NestedIfDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested if-else blocks to a specified depth"/>
+ <property name="max" value="3"/>
+ </module>
+ <module name="NestedTryDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested try blocks to a specified depth"/>
+ <property name="id" value="trydepth"/>
+ <property name="max" value="2"/>
+ </module>
+ <module name="SimplifyBooleanExpression">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for overly complicated boolean expressions"/>
+ <property name="id" value="boolexprsimple"/>
+ </module>
+ <module name="SimplifyBooleanReturn">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for overly complicated boolean return statements"/>
+ <property name="id" value="boolreturnsimple"/>
+ </module>
+ <module name="StringLiteralEquality">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that string literals are not used with == or != (use equals instead)"/>
+ <property name="id" value="stringliteralequals"/>
+ </module>
+ <module name="FinalClass">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a class which has only private constructors is declared as final."/>
+ <property name="id" value="finalclass"/>
+ </module>
+ <module name="InnerTypeLast">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check nested/internal types to be declared at the bottom of the class "/>
+ <property name="id" value="innertypelast"/>
+ </module>
+ <module name="HideUtilityClassConstructor">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Make sure that utility classes do not have a public constructor"/>
+ <property name="id" value="utilclassctor"/>
+ </module>
+ <module name="MutableException">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Ensures that exceptions are immutable"/>
+ <property name="id" value="exceptionimmutable"/>
+ </module>
+ <module name="OneTopLevelClass">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that each top-level class, interface or enum resides in a source file of its own"/>
+ <property name="id" value="onetoplevelclass"/>
+ </module>
+ <module name="BooleanExpressionComplexity">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restrict the number of number of &amp;&amp;, ||, &amp;, | and ^ in an expression."/>
+ <property name="id" value="booleanexprcomplexity"/>
+ </module>
+ <module name="CyclomaticComplexity">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks cyclomatic complexity against a specified limit."/>
+ <property name="id" value="cyclomatic"/>
+ </module>
+ <module name="ArrayTypeStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the style of array type definitions. 'String[] arr' instead of 'String arr[]'"/>
+ <property name="id" value="arraytypes"/>
+ </module>
+ <module name="Indentation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks correct indentation of Java Code."/>
+ <property name="id" value="indent"/>
+ <property name="basicOffset" value="2"/>
+ <property name="caseIndent" value="2"/>
+ <property name="arrayInitIndent" value="2"/>
+ </module>
+ <module name="UpperEll">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that long constants are defined with an upper ell ('123L')"/>
+ <property name="id" value="longconstant"/>
+ </module>
+ <module name="NonEmptyAtclauseDescription">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Verify that the clausedescription is not empty"/>
+ <property name="id" value="emtyclausedescription"/>
+ </module>
+ <module name="JavadocStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Classes &amp; Interfaces"/>
+ <property name="checkEmptyJavadoc" value="true"/>
+ <property name="tokens" value="INTERFACE_DEF,CLASS_DEF"/>
+ </module>
+ <module name="JavadocMethod">
+ <property name="allowedAnnotations" value="Before,BeforeClass,Override,Test"/>
+ <property name="validateThrows" value="true"/>
+ <property name="suppressLoadErrors" value="true"/>
+ </module>
+ <module name="AtclauseOrder"/>
+ <module name="AbstractClassName">
+ <property name="format" value="^Abstract(?!.*Test$)"/>
+ </module>
+ <module name="ClassTypeParameterName"/>
+ <module name="MethodTypeParameterName"/>
+ <module name="InterfaceTypeParameterName"/>
+ <module name="CommentsIndentation"/>
+ <module name="JavaNCSS"/>
+ <module name="CyclomaticComplexity"/>
+ <module name="ThrowsCount">
+ <property name="max" value="5"/>
+ <property name="ignorePrivateMethods" value="false"/>
+ </module>
+ <module name="VisibilityModifier">
+ <property name="protectedAllowed" value="true"/>
+ </module>
+ <module name="OneStatementPerLine"/>
+ <module name="SuperFinalize"/>
+ <module name="SuperClone"/>
+ <module name="ReturnCount">
+ <property name="maxForVoid" value="0"/>
+ </module>
+ <module name="ParameterAssignment"/>
+ <module name="NoClone"/>
+ <module name="IllegalType">
+ <property name="tokens" value="METHOD_DEF,PARAMETER_DEF,VARIABLE_DEF"/>
+ </module>
+ <module name="IllegalCatch"/>
+ <module name="ExplicitInitialization"/>
+ <module name="EqualsAvoidNull"/>
+ <module name="SingleSpaceSeparator"/>
+ <module name="SeparatorWrap">
+ <property name="option" value="nl"/>
+ <property name="tokens" value="DOT"/>
+ </module>
+ <module name="MethodLength"/>
+ <module name="AvoidStaticImport">
+ <property name="excludes" value="org.assertj.core.api.Assertions.*,org.junit.Assert.*,org.mockito.ArgumentMatchers.*,org.mockito.Mockito.*,org.xmlunit.matchers.CompareMatcher.*,org.xmlunit.diff.ElementSelectors.*,org.hamcrest.CoreMatchers.*"/>
+ </module>
+ <module name="CatchParameterName"/>
+ <module name="JavadocType">
+ <property name="authorFormat" value="(20[0-9][0-9]-((0[1-9])|(1[0-2]))-((0[1-9])|([1-2][0-9])|(3[0-1])) )?[a-zA-Z]+"/>
+ </module>
+ <module name="AnnotationLocation"/>
+ <module name="OuterTypeFilename"/>
+ <module name="JavadocStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Constructors, Methods &amp; Variables"/>
+ <property name="tokens" value="METHOD_DEF,CTOR_DEF,VARIABLE_DEF"/>
+ </module>
+ <module name="MutableException">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Ensures that events are immutable"/>
+ <property name="format" value="^.*Event$"/>
+ </module>
+ <module name="SeparatorWrap">
+ <property name="tokens" value="COMMA"/>
+ </module>
+ </module>
+ <module name="FileTabCharacter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no tab characters ('\t') in the source code."/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there is nothing writing to System.err"/>
+ <property name="id" value="syserr"/>
+ <property name="format" value="System\.err\."/>
+ <property name="message" value="Illegal use of System.err. - use a logger instead!"/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there is nothing writing a stacktrace to System.err"/>
+ <property name="id" value="sysstacktrace"/>
+ <property name="format" value="\.printStackTrace\(\)"/>
+ <property name="message" value="Illegal use of [exception].printStackTrace() - use a logger instead!"/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether a line has trailing spaces (exclude JavaDoc)"/>
+ <property name="id" value="trailingspaces"/>
+ <property name="format" value="(?!\*)[^$]\s+$"/>
+ <property name="message" value="Line has trailing spaces."/>
+ </module>
+ <module name="Translation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether that a set of messages files contains the same keys"/>
+ <property name="id" value="messages"/>
+ </module>
+ <module name="SeverityMatchFilter">
+ <property name="severity" value="info"/>
+ <property name="acceptOnMatch" value="false"/>
+ </module>
+ <module name="FileLength">
+ <property name="max" value="2500"/>
+ </module>
+ <module name="SuppressWarningsFilter"/>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="System.currentTimeMillis() not allowed"/>
+ <property name="format" value="System\.currentTimeMillis()"/>
+ <property name="message" value="'System.currentTimeMillis()' not allowed. Use 'IContext.getTimer().*' instead."/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="System.nanoTime() not allowed"/>
+ <property name="format" value="System\.nanoTime()"/>
+ <property name="message" value="'System.nanoTime()' not allowed. Use 'IContext.getTimer().*' instead."/>
+ </module>
+</module>
diff --git a/dev/src/main/resources/checkstyle/checkstyle-test.xml b/dev/src/main/resources/checkstyle/checkstyle-test.xml
new file mode 100644
index 0000000..f26d73d
--- /dev/null
+++ b/dev/src/main/resources/checkstyle/checkstyle-test.xml
@@ -0,0 +1,442 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
+
+<!--
+ This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+ Checkstyle-Configuration: Checkstyle
+ Description: none
+-->
+<module name="Checker">
+ <property name="severity" value="warning"/>
+ <module name="TreeWalker">
+ <module name="SuppressWarningsHolder"/>
+ <module name="MissingOverride">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Verifies that the java.lang.Override annotation is present when the {@inheritDoc} javadoc tag is present."/>
+ <property name="id" value="missingoverride"/>
+ </module>
+ <module name="ConstantName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that constants (static final fields) variables follow naming convention"/>
+ <property name="id" value="nameconstant"/>
+ </module>
+ <module name="LocalFinalVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that local final variables follow naming convention"/>
+ <property name="id" value="namelocalfinalvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="LocalVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that local variables follow naming convention"/>
+ <property name="id" value="namelocalvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="MemberName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that member variables (non-static fields) follow naming convention"/>
+ <property name="id" value="namemember"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="MethodName">
+ <property name="id" value="namemethod"/>
+ <property name="format" value="^([a-z][a-zA-Z0-9])+([_a-zA-Z0-9])*$"/>
+ </module>
+ <module name="PackageName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that package names follow naming convention"/>
+ <property name="id" value="namepackage"/>
+ <property name="format" value="^[a-z]+(\.[a-z_][a-z0-9_]*)*$"/>
+ </module>
+ <module name="ParameterName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that parameter names follow naming convention"/>
+ <property name="id" value="nameparam"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ <property name="accessModifiers" value="public"/>
+ </module>
+ <module name="StaticVariableName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that static variables (static, non-final fields) follow naming convention"/>
+ <property name="id" value="namestaticvar"/>
+ <property name="format" value="^(([a-z]+[A-Z]?[a-z]*)+[0-9]*)$"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that interface names follow naming convention"/>
+ <property name="id" value="nameinterface"/>
+ <property name="format" value="^I(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="INTERFACE_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that class names follow naming convention"/>
+ <property name="id" value="nameclass"/>
+ <property name="format" value="(^(([A-Z][a-z0-9]+)+[A-Z]?)$)|(^(([A-Z][a-z0-9]*)+([_][A-Z0-9][A-Za-z0-9]*)*)(?=(_Deserializer|_EndPoint|_Exporter|_Importer|_Mapper|_Modifier|_ReaderProvider|_Receiver|_Responder|_Serializer|_Task|_View|_Watcher|_WriterProvider|_DeserializationParameters|_ExecutionParameters|_ExportParameters|_ImportParameters|_MapperParameters|_ModificationParameters|_QueryParameters|_ReceiveParameters|_RequestParameters|_SerializationParameters|_WatchParameters|_DeserializationConfiguration|_ExecutionConfiguration|_ExportConfiguration|_ImportConfiguration|_MapperConfiguration|_ModificationConfiguration|_QueryConfiguration|_ReceiveConfiguration|_RequestConfiguration|_SerializationConfiguration|_TaskConfiguration|_WatchConfiguration|_WriterConfiguration)(Test)?$))"/>
+ <property name="tokens" value="CLASS_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that enum names follow naming convention"/>
+ <property name="id" value="nameenum"/>
+ <property name="format" value="^(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="ENUM_DEF"/>
+ </module>
+ <module name="TypeName">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that annotation names follow naming convention"/>
+ <property name="id" value="nameannotation"/>
+ <property name="format" value="^(([A-Z][a-z0-9]+)+[A-Z]?)$"/>
+ <property name="tokens" value="ANNOTATION_DEF"/>
+ </module>
+ <module name="AvoidStarImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no import statements that use the * notation."/>
+ <property name="id" value="starimport"/>
+ </module>
+ <module name="IllegalImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for imports from a set of illegal packages"/>
+ <property name="id" value="illegalimports"/>
+ </module>
+ <module name="CustomImportOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that the groups of import declarations appear in the order specified by the user"/>
+ <property name="id" value="importcustomorder"/>
+ <property name="customImportOrderRules" value="STATIC###STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS###THIRD_PARTY_PACKAGE"/>
+ <property name="thirdPartyPackageRegExp" value="^com\."/>
+ <property name="specialImportsRegExp" value="^org\."/>
+ <property name="sortImportsInGroupAlphabetically" value="true"/>
+ </module>
+ <module name="RedundantImport">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for redundant import statements"/>
+ <property name="id" value="importredundant"/>
+ </module>
+ <module name="UnusedImports">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for unused import statements. "/>
+ <property name="id" value="importunused"/>
+ </module>
+ <module name="ParameterNumber">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the number of parameters of a method or constructor (default 7)"/>
+ <property name="id" value="paramsmax"/>
+ </module>
+ <module name="EmptyForInitializerPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding of an empty for initializer"/>
+ <property name="id" value="initpad"/>
+ </module>
+ <module name="EmptyForIteratorPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding of an empty for iterator"/>
+ <property name="id" value="iterpad"/>
+ </module>
+ <module name="EmptyLineSeparator">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty line separators"/>
+ <property name="id" value="lineseparator"/>
+ <property name="tokens" value="CLASS_DEF,CTOR_DEF,ENUM_DEF,INTERFACE_DEF,METHOD_DEF,STATIC_INIT"/>
+ </module>
+ <module name="MethodParamPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the padding between the identifier of a method definition, constructor definition, method call, or constructor invocation"/>
+ <property name="id" value="padmethodparam"/>
+ </module>
+ <module name="NoWhitespaceAfter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="[variations] Whitespaces allowed in array-initialization. Checks that there is no whitespace after a token."/>
+ <property name="id" value="whitespaceafter"/>
+ <property name="tokens" value="INC,DEC,UNARY_MINUS,UNARY_PLUS,BNOT,LNOT,DOT"/>
+ </module>
+ <module name="NoWhitespaceBefore">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there is no whitespace before a token"/>
+ <property name="id" value="whitespacebefore"/>
+ </module>
+ <module name="OperatorWrap">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on how to wrap lines on operators"/>
+ <property name="id" value="wrapoperator"/>
+ <property name="tokens" value="QUESTION,COLON,EQUAL,NOT_EQUAL,DIV,PLUS,MINUS,STAR,MOD,SR,BSR,GE,GT,SL,LE,LT,BXOR,BOR,LOR,BAND,LAND,LITERAL_INSTANCEOF,TYPE_EXTENSION_AND"/>
+ </module>
+ <module name="ParenPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on the padding of parentheses"/>
+ <property name="id" value="padparentheses"/>
+ <property name="tokens" value="QUESTION,ANNOTATION,ANNOTATION_FIELD_DEF,LITERAL_CATCH,CTOR_CALL,CTOR_DEF,LITERAL_DO,ENUM_CONSTANT_DEF,EXPR,LITERAL_FOR,LITERAL_IF,RESOURCE_SPECIFICATION,METHOD_CALL,METHOD_DEF,LITERAL_NEW,SUPER_CTOR_CALL,LITERAL_SWITCH,LITERAL_SYNCHRONIZED,LITERAL_WHILE"/>
+ </module>
+ <module name="TypecastParenPad">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the policy on the padding of parentheses for typecasts."/>
+ <property name="id" value="padtypecastparen"/>
+ <property name="tokens" value="RPAREN,TYPECAST"/>
+ </module>
+ <module name="WhitespaceAfter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a token is followed by whitespace."/>
+ <property name="id" value="whitespaceafter"/>
+ <property name="tokens" value="COMMA,SEMI,TYPECAST"/>
+ </module>
+ <module name="ModifierOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that the order of modifiers conforms to the suggestions in the Java Language specification"/>
+ <property name="id" value="ordermodifier"/>
+ </module>
+ <module name="RedundantModifier">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for redundant modifiers"/>
+ <property name="id" value="modiredundant"/>
+ </module>
+ <module name="EmptyBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there are no empty catch blocks."/>
+ <property name="id" value="emptycatchblocks"/>
+ <property name="option" value="text"/>
+ <property name="tokens" value="LITERAL_CATCH"/>
+ </module>
+ <module name="EmptyBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty blocks."/>
+ <property name="id" value="emptyblock"/>
+ <property name="tokens" value="LITERAL_WHILE,LITERAL_TRY,LITERAL_FINALLY,LITERAL_DO,LITERAL_IF,LITERAL_ELSE,LITERAL_FOR,INSTANCE_INIT,STATIC_INIT"/>
+ </module>
+ <module name="EmptyCatchBlock">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for empty catch blocks"/>
+ <property name="id" value="emptycatch"/>
+ </module>
+ <module name="LeftCurly">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for the placement of left curly braces ('{') for code blocks."/>
+ <property name="id" value="leftcurly"/>
+ </module>
+ <module name="RightCurly">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the placement of right curly braces"/>
+ <property name="id" value="rightcurly"/>
+ <property name="option" value="alone"/>
+ </module>
+ <module name="CovariantEquals">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that classes that define a covariant equals() method also override method equals(java.lang.Object)."/>
+ <property name="id" value="covariantequals"/>
+ </module>
+ <module name="DeclarationOrder">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether parts of a class or interface declaration appear in the right order "/>
+ <property name="id" value="orderclass"/>
+ <property name="ignoreModifiers" value="true"/>
+ </module>
+ <module name="DefaultComesLast">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that the default is after all the cases in a switch statement."/>
+ <property name="id" value="defaultlast"/>
+ </module>
+ <module name="EmptyStatement">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Detects empty statements "/>
+ <property name="id" value="emptystatement"/>
+ </module>
+ <module name="EqualsHashCode">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that classes that override equals() also override hashCode()."/>
+ <property name="id" value="equalshashcode"/>
+ </module>
+ <module name="FallThrough">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for fall through in switch statements"/>
+ <property name="id" value="switchfallthrough"/>
+ </module>
+ <module name="HiddenField">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a local variable does not shadow a field that is defined in the same class."/>
+ <property name="id" value="varhidesfield"/>
+ <property name="tokens" value="VARIABLE_DEF"/>
+ </module>
+ <module name="IllegalInstantiation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for illegal instantiations where a factory method is preferred"/>
+ <property name="id" value="illegalinstantiation"/>
+ <property name="classes" value="java.lang.Boolean, java.lang.Integer, java.lang.Long"/>
+ </module>
+ <module name="IllegalThrows">
+ <metadata name="net.sf.eclipsecs.core.comment" value="This check can be used to ensure that types are not declared to be thrown. Declaring to throw java.lang.Error or java.lang.RuntimeException is almost never acceptable."/>
+ <property name="id" value="illegalthrows"/>
+ </module>
+ <module name="InnerAssignment">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for assignments in subexpressions, such as in 'String s = Integer.toString(i = 2);'"/>
+ <property name="id" value="innerassignment"/>
+ </module>
+ <module name="MagicNumber">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no 'magic numbers'"/>
+ <property name="id" value="magicnumber"/>
+ <property name="constantWaiverParentToken" value="TYPECAST,METHOD_CALL,EXPR,ARRAY_INIT,UNARY_MINUS,UNARY_PLUS,ELIST,STAR,ASSIGN,PLUS,MINUS,DIV,LITERAL_NEW"/>
+ </module>
+ <module name="MissingSwitchDefault">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that switch statement has 'default' clause."/>
+ <property name="id" value="switchdefault"/>
+ </module>
+ <module name="MultipleStringLiterals">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for multiple occurrences of the same string literal within a single file."/>
+ <property name="id" value="multistringliterals"/>
+ <property name="ignoreStringsRegexp" value="(^&quot;&quot;$)|(^&quot;[a-zA-Z_][0-9a-zA-Z_]*&quot;$)"/>
+ </module>
+ <module name="MultipleVariableDeclarations">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that each variable declaration is in its own statement and on its own line"/>
+ <property name="id" value="multivardeclr"/>
+ </module>
+ <module name="NestedForDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested for blocks to a specified depth (default = 1)."/>
+ <property name="id" value="fordepth"/>
+ <property name="max" value="2"/>
+ </module>
+ <module name="NestedIfDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested if-else blocks to a specified depth"/>
+ <property name="max" value="3"/>
+ </module>
+ <module name="NestedTryDepth">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restricts nested try blocks to a specified depth"/>
+ <property name="id" value="trydepth"/>
+ <property name="max" value="2"/>
+ </module>
+ <module name="SimplifyBooleanExpression">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for overly complicated boolean expressions"/>
+ <property name="id" value="boolexprsimple"/>
+ </module>
+ <module name="SimplifyBooleanReturn">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks for overly complicated boolean return statements"/>
+ <property name="id" value="boolreturnsimple"/>
+ </module>
+ <module name="StringLiteralEquality">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that string literals are not used with == or != (use equals instead)"/>
+ <property name="id" value="stringliteralequals"/>
+ </module>
+ <module name="FinalClass">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that a class which has only private constructors is declared as final."/>
+ <property name="id" value="finalclass"/>
+ </module>
+ <module name="InnerTypeLast">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check nested/internal types to be declared at the bottom of the class "/>
+ <property name="id" value="innertypelast"/>
+ </module>
+ <module name="HideUtilityClassConstructor">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Make sure that utility classes do not have a public constructor"/>
+ <property name="id" value="utilclassctor"/>
+ </module>
+ <module name="MutableException">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Ensures that exceptions are immutable"/>
+ <property name="id" value="exceptionimmutable"/>
+ </module>
+ <module name="OneTopLevelClass">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that each top-level class, interface or enum resides in a source file of its own"/>
+ <property name="id" value="onetoplevelclass"/>
+ </module>
+ <module name="BooleanExpressionComplexity">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Restrict the number of number of &amp;&amp;, ||, &amp;, | and ^ in an expression."/>
+ <property name="id" value="booleanexprcomplexity"/>
+ </module>
+ <module name="CyclomaticComplexity">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks cyclomatic complexity against a specified limit."/>
+ <property name="id" value="cyclomatic"/>
+ </module>
+ <module name="ArrayTypeStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks the style of array type definitions. 'String[] arr' instead of 'String arr[]'"/>
+ <property name="id" value="arraytypes"/>
+ </module>
+ <module name="Indentation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks correct indentation of Java Code."/>
+ <property name="id" value="indent"/>
+ <property name="basicOffset" value="2"/>
+ <property name="caseIndent" value="2"/>
+ <property name="arrayInitIndent" value="2"/>
+ </module>
+ <module name="UpperEll">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that long constants are defined with an upper ell ('123L')"/>
+ <property name="id" value="longconstant"/>
+ </module>
+ <module name="NonEmptyAtclauseDescription">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Verify that the clausedescription is not empty"/>
+ <property name="id" value="emtyclausedescription"/>
+ </module>
+ <module name="JavadocStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Classes &amp; Interfaces"/>
+ <property name="checkEmptyJavadoc" value="true"/>
+ <property name="tokens" value="INTERFACE_DEF,CLASS_DEF"/>
+ </module>
+ <module name="JavadocMethod">
+ <property name="allowedAnnotations" value="Before,BeforeClass,Override,Test"/>
+ <property name="validateThrows" value="true"/>
+ <property name="suppressLoadErrors" value="true"/>
+ </module>
+ <module name="AtclauseOrder"/>
+ <module name="AbstractClassName">
+ <property name="format" value="^Abstract(?!.*Test$)"/>
+ </module>
+ <module name="ClassTypeParameterName"/>
+ <module name="MethodTypeParameterName"/>
+ <module name="InterfaceTypeParameterName"/>
+ <module name="CommentsIndentation"/>
+ <module name="JavaNCSS"/>
+ <module name="CyclomaticComplexity"/>
+ <module name="ThrowsCount">
+ <property name="max" value="5"/>
+ <property name="ignorePrivateMethods" value="false"/>
+ </module>
+ <module name="VisibilityModifier">
+ <property name="protectedAllowed" value="true"/>
+ </module>
+ <module name="OneStatementPerLine"/>
+ <module name="SuperFinalize"/>
+ <module name="SuperClone"/>
+ <module name="ReturnCount">
+ <property name="maxForVoid" value="0"/>
+ </module>
+ <module name="ParameterAssignment"/>
+ <module name="NoClone"/>
+ <module name="IllegalType">
+ <property name="tokens" value="METHOD_DEF,PARAMETER_DEF,VARIABLE_DEF"/>
+ </module>
+ <module name="IllegalCatch"/>
+ <module name="ExplicitInitialization"/>
+ <module name="EqualsAvoidNull"/>
+ <module name="SingleSpaceSeparator"/>
+ <module name="SeparatorWrap">
+ <property name="option" value="nl"/>
+ <property name="tokens" value="DOT"/>
+ </module>
+ <module name="MethodLength"/>
+ <module name="AvoidStaticImport">
+ <property name="excludes" value="org.assertj.core.api.Assertions.*,org.junit.Assert.*,org.mockito.ArgumentMatchers.*,org.mockito.Mockito.*,org.xmlunit.matchers.CompareMatcher.*,org.xmlunit.diff.ElementSelectors.*,org.hamcrest.CoreMatchers.*"/>
+ </module>
+ <module name="CatchParameterName"/>
+ <module name="JavadocType">
+ <property name="authorFormat" value="(20[0-9][0-9]-((0[1-9])|(1[0-2]))-((0[1-9])|([1-2][0-9])|(3[0-1])) )?[a-zA-Z]+"/>
+ </module>
+ <module name="AnnotationLocation"/>
+ <module name="OuterTypeFilename"/>
+ <module name="JavadocStyle">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Constructors, Methods &amp; Variables"/>
+ <property name="tokens" value="METHOD_DEF,CTOR_DEF,VARIABLE_DEF"/>
+ </module>
+ <module name="MutableException">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Ensures that events are immutable"/>
+ <property name="format" value="^.*Event$"/>
+ </module>
+ <module name="SeparatorWrap">
+ <property name="tokens" value="COMMA"/>
+ </module>
+ </module>
+ <module name="FileTabCharacter">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Checks that there are no tab characters ('\t') in the source code."/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there is nothing writing to System.err"/>
+ <property name="id" value="syserr"/>
+ <property name="format" value="System\.err\."/>
+ <property name="message" value="Illegal use of System.err. - use a logger instead!"/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check that there is nothing writing a stacktrace to System.err"/>
+ <property name="id" value="sysstacktrace"/>
+ <property name="format" value="\.printStackTrace\(\)"/>
+ <property name="message" value="Illegal use of [exception].printStackTrace() - use a logger instead!"/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether a line has trailing spaces (exclude JavaDoc)"/>
+ <property name="id" value="trailingspaces"/>
+ <property name="format" value="(?!\*)[^$]\s+$"/>
+ <property name="message" value="Line has trailing spaces."/>
+ </module>
+ <module name="Translation">
+ <metadata name="net.sf.eclipsecs.core.comment" value="Check whether that a set of messages files contains the same keys"/>
+ <property name="id" value="messages"/>
+ </module>
+ <module name="SeverityMatchFilter">
+ <property name="severity" value="info"/>
+ <property name="acceptOnMatch" value="false"/>
+ </module>
+ <module name="FileLength">
+ <property name="max" value="2500"/>
+ </module>
+ <module name="SuppressWarningsFilter"/>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="System.currentTimeMillis() not allowed"/>
+ <property name="format" value="System\.currentTimeMillis()"/>
+ <property name="message" value="'System.currentTimeMillis()' not allowed. Use 'IContext.getTimer().*' instead."/>
+ </module>
+ <module name="RegexpSingleline">
+ <metadata name="net.sf.eclipsecs.core.comment" value="System.nanoTime() not allowed"/>
+ <property name="format" value="System\.nanoTime()"/>
+ <property name="message" value="'System.nanoTime()' not allowed. Use 'IContext.getTimer().*' instead."/>
+ </module>
+</module>
diff --git a/dev/src/main/resources/findbugs/findbugs-exclude.xml b/dev/src/main/resources/findbugs/findbugs-exclude.xml
new file mode 100644
index 0000000..185c239
--- /dev/null
+++ b/dev/src/main/resources/findbugs/findbugs-exclude.xml
@@ -0,0 +1,40 @@
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<FindBugsFilter>
+
+ <!-- See Bug Descriptions: http://findbugs.sourceforge.net/bugDescriptions.html -->
+
+ <!-- Bogus random noise: intended to be useful as a control in data mining experiments, not in finding actual bugs in software. -->
+ <Match>
+ <Bug category="NOISE" />
+ </Match>
+
+ <!-- code flaws having to do with internationalization and locale -->
+ <Match>
+ <Bug category="I18N" />
+ </Match>
+
+ <!-- Experimental and not fully vetted bug patterns -->
+ <Match>
+ <Bug category="EXPERIMENTAL" />
+ </Match>
+
+ <!-- exclude duplicate checked rules. Already checked by checkstyle -->
+ <Match>
+ <Bug pattern="CN_IMPLEMENTS_CLONE_BUT_NOT_CLONEABLE" />
+ </Match>
+
+ <Match>
+ <Class name="org.eclipse.openk.sourcesystem.mockupassetdata.logic.task.assetmasterdata.CreateEnergySource_1_Task" />
+ <Bug pattern="BC_UNCONFIRMED_CAST_OF_RETURN_VALUE" />
+ </Match>
+
+
+</FindBugsFilter> \ No newline at end of file
diff --git a/dev/src/main/resources/findbugs/findbugs-include.xml b/dev/src/main/resources/findbugs/findbugs-include.xml
new file mode 100644
index 0000000..eeeac66
--- /dev/null
+++ b/dev/src/main/resources/findbugs/findbugs-include.xml
@@ -0,0 +1,55 @@
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+<FindBugsFilter>
+ <!-- Violations of recommended and essential coding practice. Examples
+ include hash code and equals problems, cloneable idiom, dropped exceptions,
+ Serializable problems, and misuse of finalize. We strive to make this analysis
+ accurate, although some groups may not care about some of the bad practices. -->
+ <Match>
+ <Bug category="BAD_PRACTICE" />
+ </Match>
+
+ <!-- Probable bug - an apparent coding mistake resulting in code that was
+ probably not what the developer intended. We strive for a low false positive
+ rate. -->
+ <Match>
+ <Bug category="CORRECTNESS" />
+ </Match>
+
+ <!-- A use of untrusted input in a way that could create a remotely exploitable
+ security vulnerability. -->
+ <Match>
+ <Bug category="SECURITY" />
+ </Match>
+
+ <!-- code that is confusing, anomalous, or written in a way that leads
+ itself to errors. Examples include dead local stores, switch fall through,
+ unconfirmed casts, and redundant null check of value known to be null. More
+ false positives accepted. In previous versions of FindBugs, this category
+ was known as Style. -->
+ <Match>
+ <Bug category="STYLE" />
+ </Match>
+
+ <!-- code that is not necessarily incorrect but may be inefficient -->
+ <Match>
+ <Bug category="PERFORMANCE" />
+ </Match>
+
+ <!-- code that is vulnerable to attacks from untrusted code -->
+ <Match>
+ <Bug category="MALICIOUS_CODE" />
+ </Match>
+
+ <!-- code flaws having to do with threads, locks, and volatiles -->
+ <Match>
+ <Bug category="MT_CORRECTNESS" />
+ </Match>
+</FindBugsFilter> \ No newline at end of file
diff --git a/dev/src/main/resources/pmd/category/java/bestpractices.xml b/dev/src/main/resources/pmd/category/java/bestpractices.xml
new file mode 100644
index 0000000..2a6bea7
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/bestpractices.xml
@@ -0,0 +1,1508 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Best Practices"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules which enforce generally accepted best practices.
+ </description>
+
+ <rule name="AbstractClassWithoutAbstractMethod"
+ language="java"
+ since="3.0"
+ message="This abstract class does not have any abstract methods"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#abstractclasswithoutabstractmethod">
+ <description>
+The abstract class does not contain any abstract methods. An abstract class suggests
+an incomplete implementation, which is to be completed by subclasses implementing the
+abstract methods. If the class is intended to be used as a base class only (not to be instantiated
+directly) a protected constructor can be provided prevent direct instantiation.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+ [@Abstract='true'
+ and count( .//MethodDeclaration[@Abstract='true'] )=0 ]
+ [count(ImplementsList)=0]
+ [count(.//ExtendsList)=0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public abstract class Foo {
+ void int method1() { ... }
+ void int method2() { ... }
+ // consider using abstract methods or removing
+ // the abstract modifier and adding protected constructors
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AccessorClassGeneration"
+ since="1.04"
+ maximumLanguageVersion="10"
+ message="Avoid instantiation through private constructors from outside of the constructor's class."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorClassGenerationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessorclassgeneration">
+ <description>
+Instantiation by way of private constructors from outside of the constructor's class often causes the
+generation of an accessor. A factory method, or non-privatization of the constructor can eliminate this
+situation. The generated class file is actually an interface. It gives the accessing class the ability
+to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter.
+This turns a private constructor effectively into one with package scope, and is challenging to discern.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Outer {
+ void method(){
+ Inner ic = new Inner();//Causes generation of accessor class
+ }
+ public class Inner {
+ private Inner(){}
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AccessorMethodGeneration"
+ language="java"
+ since="5.5.4"
+ maximumLanguageVersion="10"
+ message="Avoid autogenerated methods to access private fields and methods of inner / outer classes"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorMethodGenerationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessormethodgeneration">
+ <description>
+When accessing a private field / method from another class, the Java compiler will generate a accessor methods
+with package-private visibility. This adds overhead, and to the dex method count on Android. This situation can
+be avoided by changing the visibility of the field / method from private to package-private.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class OuterClass {
+ private int counter;
+ /* package */ int id;
+
+ public class InnerClass {
+ InnerClass() {
+ OuterClass.this.counter++; // wrong accessor method will be generated
+ }
+
+ public int getOuterClassId() {
+ return OuterClass.this.id; // id is package-private, no accessor method needed
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ArrayIsStoredDirectly"
+ since="2.2"
+ message="The user-supplied array ''{0}'' is stored directly."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.ArrayIsStoredDirectlyRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#arrayisstoreddirectly">
+ <description>
+Constructors and methods receiving arrays should clone objects and store the copy.
+This prevents future changes from the user from affecting the original array.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private String [] x;
+ public void foo (String [] param) {
+ // Don't do this, make a copy of the array at least
+ this.x=param;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidPrintStackTrace"
+ language="java"
+ since="3.2"
+ message="Avoid printStackTrace(); use a logger call instead."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidprintstacktrace">
+ <description>
+Avoid printStackTrace(); use a logger call instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+ [PrimaryPrefix/Name[contains(@Image,'printStackTrace')]]
+ [PrimarySuffix[not(boolean(Arguments/ArgumentList/Expression))]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo {
+ void bar() {
+ try {
+ // do something
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidReassigningParameters"
+ since="1.0"
+ message="Avoid reassigning parameters such as ''{0}''"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningParametersRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningparameters">
+ <description>
+Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private void foo(String bar) {
+ bar = "something else";
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidStringBufferField"
+ language="java"
+ since="4.2"
+ message="StringBuffers can grow quite a lot, and so may become a source of memory leak (if the owning class has a long life time)."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidstringbufferfield">
+ <description>
+StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks
+if held within objects with long lifetimes.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//FieldDeclaration/Type/ReferenceType/ClassOrInterfaceType[@Image = 'StringBuffer' or @Image = 'StringBuilder']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private StringBuffer buffer; // potential memory leak as an instance variable;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidUsingHardCodedIP"
+ since="4.1"
+ message="Do not hard code the IP address ${variableName}"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidUsingHardCodedIPRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidusinghardcodedip">
+ <description>
+Application with hard-coded IP addresses can become impossible to deploy in some cases.
+Externalizing IP adresses is preferable.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private String ip = "127.0.0.1"; // not recommended
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CheckResultSet"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.CheckResultSetRule"
+ message="Always check the return of one of the navigation method (next,previous,first,last) of a ResultSet."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#checkresultset">
+ <description>
+Always check the return values of navigation methods (next, previous, first, last) of a ResultSet.
+If the value return is 'false', it should be handled properly.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+Statement stat = conn.createStatement();
+ResultSet rst = stat.executeQuery("SELECT name FROM person");
+rst.next(); // what if it returns false? bad form
+String firstName = rst.getString(1);
+
+Statement stat = conn.createStatement();
+ResultSet rst = stat.executeQuery("SELECT name FROM person");
+if (rst.next()) { // result is properly examined and used
+ String firstName = rst.getString(1);
+ } else {
+ // handle missing data
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ConstantsInInterface"
+ language="java"
+ since="5.5"
+ message="Avoid constants in interfaces. Interfaces define types, constants are implementation details better placed in classes or enums. See Effective Java, item 19."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#constantsininterface">
+ <description>
+Avoid constants in interfaces. Interfaces should define types, constants are implementation details
+better placed in classes or enums. See Effective Java, item 19.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="ignoreIfHasMethods" type="Boolean" description="Whether to ignore constants in interfaces if the interface defines any methods" value="true"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Interface='true'][$ignoreIfHasMethods='false' or not(.//MethodDeclaration)]//FieldDeclaration
+ ]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public interface ConstantInterface {
+ public static final int CONST1 = 1; // violation, no fields allowed in interface!
+ static final int CONST2 = 1; // violation, no fields allowed in interface!
+ final int CONST3 = 1; // violation, no fields allowed in interface!
+ int CONST4 = 1; // violation, no fields allowed in interface!
+}
+
+// with ignoreIfHasMethods = false
+public interface AnotherConstantInterface {
+ public static final int CONST1 = 1; // violation, no fields allowed in interface!
+
+ int anyMethod();
+}
+
+// with ignoreIfHasMethods = true
+public interface YetAnotherConstantInterface {
+ public static final int CONST1 = 1; // no violation
+
+ int anyMethod();
+}
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="DefaultLabelNotLastInSwitchStmt"
+ language="java"
+ since="1.5"
+ message="The default label should be the last label in a switch statement"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#defaultlabelnotlastinswitchstmt">
+ <description>
+By convention, the default label should be the last label in a switch statement.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//SwitchStatement
+ [not(SwitchLabel[position() = last()][@Default='true'])]
+ [SwitchLabel[@Default='true']]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar(int a) {
+ switch (a) {
+ case 1: // do something
+ break;
+ default: // the default case should be last, by convention
+ break;
+ case 2:
+ break;
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ForLoopCanBeForeach"
+ language="java"
+ since="6.0.0"
+ message="This 'for' loop can be replaced by a 'foreach' loop"
+ typeResolution="true"
+ minimumLanguageVersion="1.5"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.ForLoopCanBeForeachRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#forloopcanbeforeach">
+ <description>
+Reports loops that can be safely replaced with the foreach syntax. The rule considers loops over
+lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to
+access an element of the list or array, only has one update statement, and loops through *every*
+element of the list or array left to right.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class MyClass {
+ void loop(List<String> l) {
+ for (int i = 0; i < l.size(); i++) { // pre Java 1.5
+ System.out.println(l.get(i));
+ }
+
+ for (String s : l) { // post Java 1.5
+ System.out.println(s);
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="GuardLogStatement"
+ language="java"
+ since="5.1.0"
+ message="Logger calls should be surrounded by log level guards."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.GuardLogStatementRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#guardlogstatement">
+ <description>
+Whenever using a log level, one should check if the loglevel is actually enabled, or
+otherwise skip the associate String creation and manipulation.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+ // Add this for performance
+ if (log.isDebugEnabled() { ...
+ log.debug("log something" + " and " + "concat strings");
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnit4SuitesShouldUseSuiteAnnotation"
+ language="java"
+ since="4.0"
+ message="JUnit 4 indicates test suites via annotations, not the suite method."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4suitesshouldusesuiteannotation">
+ <description>
+In JUnit 3, test suites are indicated by the suite() method. In JUnit 4, suites are indicated
+through the @RunWith(Suite.class) annotation.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceBodyDeclaration[MethodDeclaration/MethodDeclarator[@Image='suite']]
+[MethodDeclaration/ResultType/Type/ReferenceType/ClassOrInterfaceType[pmd-java:typeIs('junit.framework.Test')]]
+[not(MethodDeclaration/Block//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.JUnit4TestAdapter')])]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class BadExample extends TestCase{
+
+ public static Test suite(){
+ return new Suite();
+ }
+}
+
+@RunWith(Suite.class)
+@SuiteClasses( { TestOne.class, TestTwo.class })
+public class GoodTest {
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnit4TestShouldUseAfterAnnotation"
+ language="java"
+ since="4.0"
+ message="JUnit 4 tests that clean up tests should use the @After annotation, JUnit5 tests should use @AfterEach or @AfterAll"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshoulduseafterannotation">
+ <description>
+In JUnit 3, the tearDown method was used to clean up all data entities required in running tests.
+JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test.
+JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceBodyDeclaration
+ [MethodDeclaration/MethodDeclarator[@Image='tearDown']]
+ [count(Annotation//Name[
+ pmd-java:typeIs('org.junit.After')
+ or pmd-java:typeIs('org.junit.jupiter.api.AfterEach')
+ or pmd-java:typeIs('org.junit.jupiter.api.AfterAll')
+ or pmd-java:typeIs('org.testng.annotations.AfterMethod')])=0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyTest {
+ public void tearDown() {
+ bad();
+ }
+}
+public class MyTest2 {
+ @After public void tearDown() {
+ good();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnit4TestShouldUseBeforeAnnotation"
+ language="java"
+ since="4.0"
+ message="JUnit 4 tests that set up tests should use the @Before annotation, JUnit5 tests should use @BeforeEach or @BeforeAll"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusebeforeannotation">
+ <description>
+In JUnit 3, the setUp method was used to set up all data entities required in running tests.
+JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests.
+JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceBodyDeclaration
+ [MethodDeclaration/MethodDeclarator[@Image='setUp']]
+ [count(Annotation//Name[
+ pmd-java:typeIs('org.junit.Before')
+ or pmd-java:typeIs('org.junit.jupiter.api.BeforeEach')
+ or pmd-java:typeIs('org.junit.jupiter.api.BeforeAll')
+ or pmd-java:typeIs('org.testng.annotations.BeforeMethod')])=0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyTest {
+ public void setUp() {
+ bad();
+ }
+}
+public class MyTest2 {
+ @Before public void setUp() {
+ good();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnit4TestShouldUseTestAnnotation"
+ language="java"
+ since="4.0"
+ message="JUnit 4 tests that execute tests should use the @Test annotation, JUnit 5 tests should use @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusetestannotation">
+ <description>
+In JUnit 3, the framework executed all methods which started with the word test as a unit test.
+In JUnit 4, only methods annotated with the @Test annotation are executed.
+In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[
+ matches(@Image, $testClassPattern)
+ or ExtendsList/ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]]
+
+ /ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration[MethodDeclaration[@Public=true()]/MethodDeclarator[starts-with(@Image, 'test')]]
+ [not(Annotation//Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ])]
+]]>
+ </value>
+ </property>
+ <property name="testClassPattern" type="Regex" description="The regex pattern used to identify test classes" value="Test" />
+ <property name="version" value="2.0"/>
+ </properties>
+ <example>
+<![CDATA[
+public class MyTest {
+ public void testBad() {
+ doSomething();
+ }
+
+ @Test
+ public void testGood() {
+ doSomething();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitAssertionsShouldIncludeMessage"
+ since="1.04"
+ message="JUnit assertions should include a message"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitAssertionsShouldIncludeMessageRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junitassertionsshouldincludemessage">
+ <description>
+JUnit assertions should include an informative message - i.e., use the three-argument version of
+assertEquals(), not the two-argument version.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends TestCase {
+ public void testSomething() {
+ assertEquals("foo", "bar");
+ // Use the form:
+ // assertEquals("Foo does not equals bar", "foo", "bar");
+ // instead
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitTestContainsTooManyAsserts"
+ language="java"
+ since="5.0"
+ message="Unit tests should not contain more than ${maximumAsserts} assert(s)."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestcontainstoomanyasserts">
+ <description>
+Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which
+it is harder to verify correctness. Consider breaking the test scenario into multiple, shorter test scenarios.
+Customize the maximum number of assertions used by this Rule to suit your needs.
+
+This rule checks for JUnit4, JUnit5 and TestNG Tests, as well as methods starting with "test".
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="maximumAsserts" type="Integer" min="1" max="1000" description="Maximum number of Asserts in a test method" value="1"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclarator[@Image[fn:matches(.,'^test')] or ../../Annotation/MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ or pmd-java:typeIs('org.testng.annotations.Test')
+ ]]
+ [count(..//PrimaryPrefix/Name[@Image[fn:matches(.,'^assert')]]) > $maximumAsserts]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyTestCase extends TestCase {
+ // Ok
+ public void testMyCaseWithOneAssert() {
+ boolean myVar = false;
+ assertFalse("should be false", myVar);
+ }
+
+ // Bad, too many asserts (assuming max=1)
+ public void testMyCaseWithMoreAsserts() {
+ boolean myVar = false;
+ assertFalse("myVar should be false", myVar);
+ assertEquals("should equals false", false, myVar);
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitTestsShouldIncludeAssert"
+ since="2.0"
+ message="JUnit tests should include assert() or fail()"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitTestsShouldIncludeAssertRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert">
+ <description>
+JUnit tests should include at least one assertion. This makes the tests more robust, and using assert
+with messages provide the developer a clearer idea of what the test does.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends TestCase {
+ public void testSomething() {
+ Bar b = findBar();
+ // This is better than having a NullPointerException
+ // assertNotNull("bar not found", b);
+ b.work();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitUseExpected"
+ since="4.0"
+ message="In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitUseExpectedRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junituseexpected">
+ <description>
+In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class MyTest {
+ @Test
+ public void testBad() {
+ try {
+ doSomething();
+ fail("should have thrown an exception");
+ } catch (Exception e) {
+ }
+ }
+
+ @Test(expected=Exception.class)
+ public void testGood() {
+ doSomething();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LooseCoupling"
+ since="0.7"
+ message="Avoid using implementation types like ''{0}''; use the interface instead"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.LooseCouplingRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#loosecoupling">
+ <description>
+The use of implementation types (i.e., HashSet) as object references limits your ability to use alternate
+implementations in the future as requirements change. Whenever available, referencing objects
+by their interface types (i.e, Set) provides much more flexibility.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class Bar {
+ // sub-optimal approach
+ private ArrayList<SomeType> list = new ArrayList<>();
+
+ public HashSet<SomeType> getFoo() {
+ return new HashSet<SomeType>();
+ }
+
+ // preferred approach
+ private List<SomeType> list = new ArrayList<>();
+
+ public Set<SomeType> getFoo() {
+ return new HashSet<SomeType>();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MethodReturnsInternalArray"
+ since="2.2"
+ message="Returning ''{0}'' may expose an internal array."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.MethodReturnsInternalArrayRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#methodreturnsinternalarray">
+ <description>
+Exposing internal arrays to the caller violates object encapsulation since elements can be
+removed or replaced outside of the object that owns it. It is safer to return a copy of the array.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class SecureSystem {
+ UserData [] ud;
+ public UserData [] getUserData() {
+ // Don't return directly the internal array, return a copy
+ return ud;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="MissingOverride"
+ since="6.2.0"
+ minimumLanguageVersion="1.5"
+ message="The method ''{0}'' is missing an @Override annotation."
+ typeResolution="true"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.MissingOverrideRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#missingoverride">
+ <description>
+ Annotating overridden methods with @Override ensures at compile time that
+ the method really overrides one, which helps refactoring and clarifies intent.
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+ public class Foo implements Runnable {
+ // This method is overridden, and should have an @Override annotation
+ public void run() {
+
+ }
+ }
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="OneDeclarationPerLine"
+ language="java"
+ since="5.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Use one line for each declaration, it enhances code readability."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#onedeclarationperline">
+ <description>
+Java allows the use of several variables declaration of the same type on one line. However, it
+can lead to quite messy code. This rule looks for several declarations on the same line.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//LocalVariableDeclaration
+ [count(VariableDeclarator) > 1]
+ [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
+|
+//FieldDeclaration
+ [count(VariableDeclarator) > 1]
+ [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
+]]>
+ </value>
+ </property>
+ <property name="version" value="2.0"/>
+ <property name="strictMode" type="Boolean" value="false"
+ description="If true, mark combined declaration even if the declarations are on separate lines."/>
+ </properties>
+ <example>
+<![CDATA[
+String name; // separate declarations
+String lastname;
+
+String name, lastname; // combined declaration, a violation
+
+String name,
+ lastname; // combined declaration on multiple lines, no violation by default.
+ // Set property strictMode to true to mark this as violation.
+]]>
+ </example>
+ </rule>
+
+ <rule name="PositionLiteralsFirstInCaseInsensitiveComparisons"
+ language="java"
+ since="5.1"
+ message="Position literals first in String comparisons for EqualsIgnoreCase"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#positionliteralsfirstincaseinsensitivecomparisons">
+ <description>
+Position literals first in comparisons, if the second argument is null then NullPointerExceptions
+can be avoided, they will just return false.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+ PrimaryPrefix[Name
+ [
+ (ends-with(@Image, '.equalsIgnoreCase'))
+ ]
+ ]
+ [
+ (../PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal)
+ and
+ ( count(../PrimarySuffix/Arguments/ArgumentList/Expression) = 1 )
+ ]
+]
+[not(ancestor::Expression/ConditionalAndExpression//EqualityExpression[@Image='!=']//NullLiteral)]
+[not(ancestor::Expression/ConditionalOrExpression//EqualityExpression[@Image='==']//NullLiteral)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo {
+ boolean bar(String x) {
+ return x.equalsIgnoreCase("2"); // should be "2".equalsIgnoreCase(x)
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="PositionLiteralsFirstInComparisons"
+ language="java"
+ since="3.3"
+ message="Position literals first in String comparisons"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#positionliteralsfirstincomparisons">
+ <description>
+Position literals first in comparisons, if the second argument is null then NullPointerExceptions
+can be avoided, they will just return false.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+ PrimaryPrefix[Name[(ends-with(@Image, '.equals'))]]
+ [
+ (../PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral='true'])
+ and
+ ( count(../PrimarySuffix/Arguments/ArgumentList/Expression) = 1 )
+ ]
+]
+[not(ancestor::Expression/ConditionalAndExpression//EqualityExpression[@Image='!=']//NullLiteral)]
+[not(ancestor::Expression/ConditionalOrExpression//EqualityExpression[@Image='==']//NullLiteral)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo {
+ boolean bar(String x) {
+ return x.equals("2"); // should be "2".equals(x)
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="PreserveStackTrace"
+ since="3.7"
+ message="New exception is thrown in catch block, original stack trace may be lost"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.PreserveStackTraceRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#preservestacktrace">
+ <description>
+Throwing a new exception from a catch block without passing the original exception into the
+new exception will cause the original stack trace to be lost making it difficult to debug
+effectively.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ void good() {
+ try{
+ Integer.parseInt("a");
+ } catch (Exception e) {
+ throw new Exception(e); // first possibility to create exception chain
+ }
+ try {
+ Integer.parseInt("a");
+ } catch (Exception e) {
+ throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
+ }
+ }
+ void bad() {
+ try{
+ Integer.parseInt("a");
+ } catch (Exception e) {
+ throw new Exception(e.getMessage());
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ReplaceEnumerationWithIterator"
+ language="java"
+ since="3.4"
+ message="Consider replacing this Enumeration with the newer java.util.Iterator"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replaceenumerationwithiterator">
+ <description>
+Consider replacing Enumeration usages with the newer java.util.Iterator
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ImplementsList/ClassOrInterfaceType[@Image='Enumeration']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo implements Enumeration {
+ private int x = 42;
+ public boolean hasMoreElements() {
+ return true;
+ }
+ public Object nextElement() {
+ return String.valueOf(i++);
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ReplaceHashtableWithMap"
+ language="java"
+ since="3.4"
+ message="Consider replacing this Hashtable with the newer java.util.Map"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacehashtablewithmap">
+ <description>
+Consider replacing Hashtable usage with the newer java.util.Map if thread safety is not required.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ Hashtable h = new Hashtable();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ReplaceVectorWithList"
+ language="java"
+ since="3.4"
+ message="Consider replacing this Vector with the newer java.util.List"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacevectorwithlist">
+ <description>
+Consider replacing Vector usages with the newer java.util.ArrayList if expensive thread-safe operations are not required.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//Type/ReferenceType/ClassOrInterfaceType[@Image='Vector']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ Vector v = new Vector();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SwitchStmtsShouldHaveDefault"
+ language="java"
+ since="1.0"
+ message="Switch statements should have a default label"
+ typeResolution="true"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#switchstmtsshouldhavedefault">
+ <description>
+All switch statements should include a default option to catch any unspecified values.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="version" value="2.0"/>
+ <property name="xpath">
+ <value><![CDATA[
+ //SwitchStatement[@DefaultCase = false() and @ExhaustiveEnumSwitch = false()]
+ ]]></value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ int x = 2;
+ switch (x) {
+ case 1: int j = 6;
+ case 2: int j = 8;
+ // missing default: here
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SystemPrintln"
+ language="java"
+ since="2.1"
+ message="{0} is used"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#systemprintln">
+ <description>
+References to System.(out|err).print are usually intended for debugging purposes and can remain in
+the codebase even in production code. By using a logger one can enable/disable this behaviour at
+will (and by priority) and avoid clogging the Standard out log.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Name[
+ starts-with(@Image, 'System.out.print')
+ or
+ starts-with(@Image, 'System.err.print')
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+ <![CDATA[
+class Foo{
+ Logger log = Logger.getLogger(Foo.class.getName());
+ public void testA () {
+ System.out.println("Entering test");
+ // Better use this
+ log.fine("Entering test");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedFormalParameter"
+ language="java"
+ since="0.8"
+ message="Avoid unused {0} parameters such as ''{1}''."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedFormalParameterRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedformalparameter">
+ <description>
+Avoid passing parameters to methods or constructors without actually referencing them in the method body.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private void bar(String howdy) {
+ // howdy is not used
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedImports"
+ since="1.0"
+ message="Avoid unused imports such as ''{0}''"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedImportsRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedimports">
+ <description>
+Avoid unused import statements to prevent unwanted dependencies.
+This rule will also find unused on demand imports, i.e. import com.foo.*.
+ </description>
+ <priority>4</priority>
+ <example>
+<![CDATA[
+import java.io.File; // not referenced or required
+import java.util.*; // not referenced or required
+
+public class Foo {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedLocalVariable"
+ language="java"
+ since="0.1"
+ message="Avoid unused local variables such as ''{0}''."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedLocalVariableRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedlocalvariable">
+ <description>
+Detects when a local variable is declared and/or assigned, but not used.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void doSomething() {
+ int i = 5; // Unused
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedPrivateField"
+ since="0.1"
+ language="java"
+ message="Avoid unused private fields such as ''{0}''."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateFieldRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatefield">
+ <description>
+Detects when a private field is declared and/or assigned a value, but not used.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Something {
+ private static int FOO = 2; // Unused
+ private int i = 5; // Unused
+ private int j = 6;
+ public int addOne() {
+ return j++;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedPrivateMethod"
+ language="java"
+ since="0.7"
+ message="Avoid unused private methods such as ''{0}''."
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateMethodRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatemethod">
+ <description>
+Unused Private Method detects when a private method is declared but is unused.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Something {
+ private void foo() {} // unused
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseAssertEqualsInsteadOfAssertTrue"
+ language="java"
+ since="3.1"
+ message="Use assertEquals(x, y) instead of assertTrue(x.equals(y))"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertequalsinsteadofasserttrue">
+ <description>
+This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+ PrimaryPrefix/Name[@Image = 'assertTrue']
+][
+ PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
+ [ends-with(@Image, '.equals')]
+]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a, b;
+ assertTrue(a.equals(b)); // bad usage
+ assertEquals(?a should equals b?, a, b); // good usage
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseAssertNullInsteadOfAssertTrue"
+ language="java"
+ since="3.5"
+ message="Use assertNull(x) instead of assertTrue(x==null), or assertNotNull(x) vs assertFalse(x==null)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertnullinsteadofasserttrue">
+ <description>
+This rule detects JUnit assertions in object references equality. These assertions should be made by
+more specific methods, like assertNull, assertNotNull.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+ PrimaryPrefix/Name[@Image = 'assertTrue' or @Image = 'assertFalse']
+][
+ PrimarySuffix/Arguments/ArgumentList[
+ Expression/EqualityExpression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral
+ ]
+]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a = doSomething();
+ assertTrue(a==null); // bad usage
+ assertNull(a); // good usage
+ assertTrue(a != null); // bad usage
+ assertNotNull(a); // good usage
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseAssertSameInsteadOfAssertTrue"
+ language="java"
+ since="3.1"
+ message="Use assertSame(x, y) instead of assertTrue(x==y), or assertNotSame(x,y) vs assertFalse(x==y)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertsameinsteadofasserttrue">
+ <description>
+This rule detects JUnit assertions in object references equality. These assertions should be made
+by more specific methods, like assertSame, assertNotSame.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+ PrimaryPrefix/Name
+ [@Image = 'assertTrue' or @Image = 'assertFalse']
+]
+[PrimarySuffix/Arguments
+ /ArgumentList/Expression
+ /EqualityExpression[count(.//NullLiteral) = 0]]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class FooTest extends TestCase {
+ void testCode() {
+ Object a, b;
+ assertTrue(a == b); // bad usage
+ assertSame(a, b); // good usage
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseAssertTrueInsteadOfAssertEquals"
+ language="java"
+ since="5.0"
+ message="Use assertTrue(x)/assertFalse(x) instead of assertEquals(true, x)/assertEquals(false, x) or assertEquals(Boolean.TRUE, x)/assertEquals(Boolean.FALSE, x)."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useasserttrueinsteadofassertequals">
+ <description>
+When asserting a value is the same as a literal or Boxed boolean, use assertTrue/assertFalse, instead of assertEquals.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[PrimaryPrefix/Name[@Image = 'assertEquals']]
+[
+ PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral
+ or
+ PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix
+ /Name[(@Image = 'Boolean.TRUE' or @Image = 'Boolean.FALSE')]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyTestCase extends TestCase {
+ public void testMyCase() {
+ boolean myVar = true;
+ // Ok
+ assertTrue("myVar is true", myVar);
+ // Bad
+ assertEquals("myVar is true", true, myVar);
+ // Bad
+ assertEquals("myVar is false", false, myVar);
+ // Bad
+ assertEquals("myVar is true", Boolean.TRUE, myVar);
+ // Bad
+ assertEquals("myVar is false", Boolean.FALSE, myVar);
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseCollectionIsEmpty"
+ since="3.9"
+ message="Substitute calls to size() == 0 (or size() != 0, size() &gt; 0, size() &lt; 1) with calls to isEmpty()"
+ class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseCollectionIsEmptyRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usecollectionisempty">
+ <description>
+The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements.
+Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ void good() {
+ List foo = getList();
+ if (foo.isEmpty()) {
+ // blah
+ }
+ }
+
+ void bad() {
+ List foo = getList();
+ if (foo.size() == 0) {
+ // blah
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseVarargs"
+ language="java"
+ minimumLanguageVersion="1.5"
+ since="5.0"
+ message="Consider using varargs for methods or constructors which take an array the last parameter."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usevarargs">
+ <description>
+Java 5 introduced the varargs parameter declaration for methods and constructors. This syntactic
+sugar provides flexibility for users of these methods and constructors, allowing them to avoid
+having to deal with the creation of an array.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//FormalParameters/FormalParameter
+ [position()=last()]
+ [@Array='true']
+ [@Varargs='false']
+ [not (./Type/ReferenceType[@Array='true'][PrimitiveType[@Image='byte']])]
+ [not (./Type/ReferenceType[ClassOrInterfaceType[@Image='Byte']])]
+ [not (./Type/PrimitiveType[@Image='byte'])]
+ [not (ancestor::MethodDeclaration/preceding-sibling::Annotation/*/Name[@Image='Override'])]
+ [not(
+ ancestor::MethodDeclaration
+ [@Public='true' and @Static='true']
+ [child::ResultType[@Void='true']] and
+ ancestor::MethodDeclarator[@Image='main'] and
+ ..[@ParameterCount='1'] and
+ ./Type/ReferenceType[ClassOrInterfaceType[@Image='String']]
+ )]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void foo(String s, Object[] args) {
+ // Do something here...
+ }
+
+ public void bar(String s, Object... args) {
+ // Ahh, varargs tastes much better...
+ }
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/category/java/categories.properties b/dev/src/main/resources/pmd/category/java/categories.properties
new file mode 100644
index 0000000..d932ccf
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/categories.properties
@@ -0,0 +1,9 @@
+rulesets.filenames=\
+ category/java/bestpractices.xml,\
+ category/java/codestyle.xml,\
+ category/java/design.xml,\
+ category/java/documentation.xml,\
+ category/java/errorprone.xml,\
+ category/java/multithreading.xml,\
+ category/java/performance.xml,\
+ category/java/security.xml
diff --git a/dev/src/main/resources/pmd/category/java/codestyle.xml b/dev/src/main/resources/pmd/category/java/codestyle.xml
new file mode 100644
index 0000000..a0d481f
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/codestyle.xml
@@ -0,0 +1,2062 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Code Style"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+ Rules which enforce a specific coding style.
+ </description>
+
+ <rule name="AbstractNaming"
+ language="java"
+ since="1.4"
+ deprecated="true"
+ message="Abstract classes should be named 'AbstractXXX'"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#abstractnaming">
+ <description>
+ Abstract classes should be named 'AbstractXXX'.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+ [@Abstract='true' and @Interface='false']
+ [not (starts-with(@Image,'Abstract'))]
+|
+//ClassOrInterfaceDeclaration
+ [@Abstract='false']
+ [$strict='true']
+ [starts-with(@Image, 'Abstract')]
+]]>
+ </value>
+ </property>
+ <property name="strict" type="Boolean" value="true" description="Also flag classes, that are named Abstract, but are not abstract."/>
+ </properties>
+ <example>
+<![CDATA[
+public abstract class Foo { // should be AbstractFoo
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AtLeastOneConstructor"
+ language="java"
+ since="1.04"
+ message="Each class should declare at least one constructor"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.AtLeastOneConstructorRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#atleastoneconstructor">
+ <description>
+<![CDATA[
+Each non-static class should declare at least one constructor.
+Classes with solely static members are ignored, refer to [UseUtilityClassRule](pmd_rules_java_design.html#useutilityclass) to detect those.
+]]>
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ // missing constructor
+ public void doSomething() { ... }
+ public void doOtherThing { ... }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidDollarSigns"
+ since="1.5"
+ message="Avoid using dollar signs in variable/method/class/interface names"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.AvoidDollarSignsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoiddollarsigns">
+ <description>
+Avoid using dollar signs in variable/method/class/interface names.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Fo$o { // not a recommended name
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidFinalLocalVariable"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Avoid using final local variables, turn them into fields"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidfinallocalvariable">
+ <description>Avoid using final local variables, turn them into fields.</description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//LocalVariableDeclaration[
+ @Final = 'true'
+ and not(../../ForStatement)
+ and
+ (
+ (count(VariableDeclarator/VariableInitializer) = 0)
+ or
+ (VariableDeclarator/VariableInitializer/Expression/PrimaryExpression/PrimaryPrefix/Literal)
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyClass {
+ public void foo() {
+ final String finalLocalVariable;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidPrefixingMethodParameters"
+ language="java"
+ since="5.0"
+ deprecated="true"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Avoid prefixing parameters by in, out or inOut. Uses Javadoc to document this behavior."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidprefixingmethodparameters">
+ <description>
+Prefixing parameters by 'in' or 'out' pollutes the name of the parameters and reduces code readability.
+To indicate whether or not a parameter will be modify in a method, its better to document method
+behavior with Javadoc.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration/MethodDeclarator/FormalParameters/FormalParameter/VariableDeclaratorId[
+ pmd:matches(@Image,'^in[A-Z].*','^out[A-Z].*','^in$','^out$')
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// Not really clear
+public class Foo {
+ public void bar(
+ int inLeftOperand,
+ Result outRightOperand) {
+ outRightOperand.setValue(inLeftOperand * outRightOperand.getValue());
+ }
+}
+]]>
+ </example>
+ <example>
+<![CDATA[
+// Far more useful
+public class Foo {
+ /**
+ *
+ * @param leftOperand, (purpose), not modified by method.
+ * @param rightOperand (purpose), will be modified by the method: contains the result.
+ */
+ public void bar(
+ int leftOperand,
+ Result rightOperand) {
+ rightOperand.setValue(leftOperand * rightOperand.getValue());
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidProtectedFieldInFinalClass"
+ language="java"
+ since="2.1"
+ message="Avoid protected fields in a final class. Change to private or package access."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidprotectedfieldinfinalclass">
+ <description>
+Do not use protected fields in final classes since they cannot be subclassed.
+Clarify your intent by using private or package access modifiers instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Final='true']
+/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration
+/FieldDeclaration[@Protected='true']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public final class Bar {
+ private int x;
+ protected int y; // bar cannot be subclassed, so is y really private or package visible?
+ Bar() {}
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidProtectedMethodInFinalClassNotExtending"
+ language="java"
+ since="5.1"
+ message="Avoid protected methods in a final class that doesn't extend anything other than Object. Change to private or package access."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidprotectedmethodinfinalclassnotextending">
+ <description>
+Do not use protected methods in most final classes since they cannot be subclassed. This should
+only be allowed in final classes that extend other classes with protected methods (whose
+visibility cannot be reduced). Clarify your intent by using private or package access modifiers instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Final='true' and not(ExtendsList)]
+/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration
+/MethodDeclaration[@Protected='true'][MethodDeclarator/@Image != 'finalize']
+ ]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public final class Foo {
+ private int bar() {}
+ protected int baz() {} // Foo cannot be subclassed, and doesn't extend anything, so is baz() really private or package visible?
+}
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidUsingNativeCode"
+ language="java"
+ since="4.1"
+ message="The use of native code is not recommended."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidusingnativecode">
+ <description>
+Unnecessary reliance on Java Native Interface (JNI) calls directly reduces application portability
+and increases the maintenance burden.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>//Name[starts-with(@Image,'System.loadLibrary')]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SomeJNIClass {
+
+ public SomeJNIClass() {
+ System.loadLibrary("nativelib");
+ }
+
+ static {
+ System.loadLibrary("nativelib");
+ }
+
+ public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException {
+ System.loadLibrary("nativelib");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="BooleanGetMethodName"
+ language="java"
+ since="4.0"
+ message="A 'getX()' method which returns a boolean should be named 'isX()'"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#booleangetmethodname">
+ <description>
+Methods that return boolean results should be named as predicate statements to denote this.
+I.e, 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get'
+prefix for these methods.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[
+MethodDeclarator[count(FormalParameters/FormalParameter) = 0 or $checkParameterizedMethods = 'true']
+ [starts-with(@Image, 'get')]
+and
+ResultType/Type/PrimitiveType[@Image = 'boolean']
+and not(../Annotation//Name[@Image = 'Override'])
+]
+]]>
+ </value>
+ </property>
+ <property name="checkParameterizedMethods" type="Boolean" description="Check parameterized methods" value="false"/>
+ </properties>
+ <example>
+<![CDATA[
+public boolean getFoo(); // bad
+public boolean isFoo(); // ok
+public boolean getFoo(boolean bar); // ok, unless checkParameterizedMethods=true
+]]>
+ </example>
+ </rule>
+
+ <rule name="CallSuperInConstructor"
+ language="java"
+ since="3.0"
+ message="It is a good practice to call super() in a constructor"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#callsuperinconstructor">
+ <description>
+It is a good practice to call super() in a constructor. If super() is not called but
+another constructor (such as an overloaded constructor) is called, this rule will not report it.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[ count (ExtendsList/*) > 0 ]
+/ClassOrInterfaceBody
+ /ClassOrInterfaceBodyDeclaration
+ /ConstructorDeclaration[ count (.//ExplicitConstructorInvocation)=0 ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo extends Bar{
+ public Foo() {
+ // call the constructor of Bar
+ super();
+ }
+ public Foo(int code) {
+ // do something with code
+ this();
+ // no problem with this
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ClassNamingConventions"
+ since="1.2"
+ message="The {0} name ''{1}'' doesn''t match ''{2}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.ClassNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#classnamingconventions">
+ <description>
+ Configurable naming conventions for type declarations. This rule reports
+ type declarations which do not match the regex that applies to their
+ specific kind (e.g. enum or interface). Each regex can be configured through
+ properties.
+
+ By default this rule uses the standard Java naming convention (Pascal case),
+ and reports utility class names not ending with 'Util'.
+ </description>
+ <priority>1</priority>
+ <example>
+<![CDATA[
+// This is Pascal case, the recommended naming convention in Java
+// Note that the default values of this rule don't allow underscores
+// or accented characters in type names
+public class FooBar {}
+
+// You may want abstract classes to be named 'AbstractXXX',
+// in which case you can customize the regex for abstract
+// classes to 'Abstract[A-Z]\w+'
+public abstract class Thing {}
+
+// This class doesn't respect the convention, and will be flagged
+public class Éléphant {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CommentDefaultAccessModifier"
+ since="5.4.0"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.CommentDefaultAccessModifierRule"
+ message="Missing commented default access modifier"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier">
+ <description>
+To avoid mistakes if we want that a Method, Constructor, Field or Nested class have a default access modifier
+we must add a comment at the beginning of it's declaration.
+By default the comment must be /* default */ or /* package */, if you want another, you have to provide a regular expression.
+This rule ignores by default all cases that have a @VisibleForTesting annotation. Use the
+property "ignoredAnnotations" to customize the recognized annotations.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ final String stringValue = "some string";
+ String getString() {
+ return stringValue;
+ }
+
+ class NestedFoo {
+ }
+}
+
+// should be
+public class Foo {
+ /* default */ final String stringValue = "some string";
+ /* default */ String getString() {
+ return stringValue;
+ }
+
+ /* default */ class NestedFoo {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ConfusingTernary"
+ since="1.9"
+ message="Avoid if (x != y) ..; else ..;"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.ConfusingTernaryRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#confusingternary">
+ <description>
+Avoid negation within an "if" expression with an "else" clause. For example, rephrase:
+`if (x != y) diff(); else same();` as: `if (x == y) same(); else diff();`.
+
+Most "if (x != y)" cases without an "else" are often return cases, so 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?".
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+boolean bar(int x, int y) {
+ return (x != y) ? diff : same;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ControlStatementBraces"
+ language="java"
+ since="6.2.0"
+ message="This statement should have braces"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#controlstatementbraces">
+ <description>
+ Enforce a policy for braces on control statements. It is recommended to use braces on 'if ... else'
+ statements and loop statements, even if they are optional. This usually makes the code clearer, and
+ helps prepare the future when you need to add another statement. That said, this rule lets you control
+ which statements are required to have braces via properties.
+
+ From 6.2.0 on, this rule supersedes WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces,
+ and IfElseStmtMustUseBraces.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="checkIfElseStmt" type="Boolean" value="true" description="Require that 'if ... else' statements use braces" />
+ <property name="checkSingleIfStmt" type="Boolean" value="true" description="Require that 'if' statements with a single branch use braces" />
+ <property name="checkWhileStmt" type="Boolean" value="true" description="Require that 'while' loops use braces" />
+ <property name="checkForStmt" type="Boolean" value="true" description="Require that 'for' loops should use braces" />
+ <property name="checkDoWhileStmt" type="Boolean" value="true" description="Require that 'do ... while' loops use braces" />
+ <property name="checkCaseStmt" type="Boolean" value="false" description="Require that cases of a switch have braces"/>
+
+ <property name="allowEmptyLoop" type="Boolean" value="false" description="Allow loops with an empty statement, e.g. 'while(true);'" />
+
+ <property name="version" value="2.0"/>
+ <property name="xpath">
+ <value><![CDATA[
+ //WhileStatement[$checkWhileStmt and not(Statement/Block) and not($allowEmptyLoop and Statement/EmptyStatement)]
+ |
+ //ForStatement[$checkForStmt and not(Statement/Block) and not($allowEmptyLoop and Statement/EmptyStatement)]
+ |
+ //DoStatement[$checkDoWhileStmt and not(Statement/Block) and not($allowEmptyLoop and Statement/EmptyStatement)]
+ |
+ (: The violation is reported on the sub statement -- not the if statement :)
+ //Statement[$checkIfElseStmt and parent::IfStatement and not(child::Block or child::IfStatement)
+ (: Whitelists single if statements :)
+ and ($checkSingleIfStmt
+ (: Inside this not(...) is the definition of a "single if statement" :)
+ or not(count(../Statement) = 1 (: No else stmt :)
+ (: Not the last branch of an 'if ... else if' chain :)
+ and not(parent::IfStatement[parent::Statement[parent::IfStatement]])))]
+ |
+ (: Reports case labels if one of their subordinate statements is not braced :)
+ //SwitchLabel[$checkCaseStmt]
+ [count(following-sibling::BlockStatement except following-sibling::SwitchLabel[1]/following-sibling::BlockStatement) > 1
+ or (some $stmt (: in only the block statements until the next label :)
+ in following-sibling::BlockStatement except following-sibling::SwitchLabel[1]/following-sibling::BlockStatement
+ satisfies not($stmt/Statement/Block))]
+ ]]></value>
+ </property>
+ </properties>
+ <example>
+ <![CDATA[
+while (true) // not recommended
+ x++;
+
+while (true) { // preferred approach
+ x++;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DefaultPackage"
+ language="java"
+ since="3.4"
+ message="Use explicit scoping instead of the default package private level"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#defaultpackage">
+ <description>
+Use explicit scoping instead of accidental usage of default package private level.
+The rule allows methods and fields annotated with Guava's @VisibleForTesting.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Interface='false']
+/ClassOrInterfaceBody
+/ClassOrInterfaceBodyDeclaration
+[not(Annotation//Name[ends-with(@Image, 'VisibleForTesting')])]
+[
+FieldDeclaration[@PackagePrivate='true']
+or MethodDeclaration[@PackagePrivate='true']
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ </rule>
+
+ <rule name="DontImportJavaLang"
+ since="0.5"
+ message="Avoid importing anything from the package 'java.lang'"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.DontImportJavaLangRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#dontimportjavalang">
+ <description>
+Avoid importing anything from the package 'java.lang'. These classes are automatically imported (JLS 7.5.3).
+ </description>
+ <priority>4</priority>
+ <example>
+<![CDATA[
+import java.lang.String; // this is unnecessary
+
+public class Foo {}
+
+// --- in another source code file...
+
+import java.lang.*; // this is bad
+
+public class Foo {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DuplicateImports"
+ since="0.5"
+ message="Avoid duplicate imports such as ''{0}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.DuplicateImportsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#duplicateimports">
+ <description>
+Duplicate or overlapping import statements should be avoided.
+ </description>
+ <priority>4</priority>
+ <example>
+<![CDATA[
+import java.lang.String;
+import java.lang.*;
+public class Foo {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyMethodInAbstractClassShouldBeAbstract"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="An empty method in an abstract class should be abstract instead"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#emptymethodinabstractclassshouldbeabstract">
+ <description>
+Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inapproprate
+usage by developers who should be implementing their own versions in the concrete subclasses.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Abstract = 'true']
+ /ClassOrInterfaceBody
+ /ClassOrInterfaceBodyDeclaration
+ /MethodDeclaration[@Abstract = 'false' and @Native = 'false']
+ [
+ ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral) = 'true' )
+ or
+ ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal[@Image = '0']) = 'true' )
+ or
+ ( boolean(./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal[string-length(@Image) = 2]) = 'true' )
+ or
+ (./Block[count(./BlockStatement) = 1]/BlockStatement/Statement/EmptyStatement)
+ or
+ ( count (./Block/*) = 0 )
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public abstract class ShouldBeAbstract {
+ public Object couldBeAbstract() {
+ // Should be abstract method ?
+ return null;
+ }
+
+ public void couldBeAbstract() {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExtendsObject"
+ language="java"
+ since="5.0"
+ message="No need to explicitly extend Object."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#extendsobject">
+ <description>No need to explicitly extend Object.</description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ExtendsList/ClassOrInterfaceType[@Image='Object' or @Image='java.lang.Object']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo extends Object { // not required
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FieldDeclarationsShouldBeAtStartOfClass"
+ language="java"
+ since="5.0"
+ message="Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes."
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.FieldDeclarationsShouldBeAtStartOfClassRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#fielddeclarationsshouldbeatstartofclass">
+ <description>
+Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class HelloWorldBean {
+
+ // Field declared before methods / inner classes - OK
+ private String _thing;
+
+ public String getMessage() {
+ return "Hello World!";
+ }
+
+ // Field declared after methods / inner classes - avoid this
+ private String _fieldInWrongLocation;
+}
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="FieldNamingConventions"
+ since="6.7.0"
+ message="The {0} name ''{1}'' doesn''t match ''{2}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.FieldNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#fieldnamingconventions">
+ <description>
+ Configurable naming conventions for field declarations. This rule reports variable declarations
+ which do not match the regex that applies to their specific kind ---e.g. constants (static final),
+ enum constant, final field. Each regex can be configured through properties.
+
+ By default this rule uses the standard Java naming convention (Camel case), and uses the ALL_UPPER
+ convention for constants and enum constants.
+ </description>
+ <priority>1</priority>
+ <example>
+ <![CDATA[
+ class Foo {
+ int myField = 1; // This is in camel case, so it's ok
+ int my_Field = 1; // This contains an underscore, it's not ok by default
+ // but you may allow it, or even require the "my_" prefix
+
+ final int FinalField = 1; // you may configure a different convention for final fields,
+ // e.g. here PascalCase: [A-Z][a-zA-Z0-9]*
+
+ interface Interface {
+ double PI = 3.14; // interface "fields" use the constantPattern property
+ }
+
+ enum AnEnum {
+ ORG, NET, COM; // These use a separate property but are set to ALL_UPPER by default
+ }
+ }
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="ForLoopShouldBeWhileLoop"
+ language="java"
+ since="1.02"
+ message="This for loop could be simplified to a while loop"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#forloopshouldbewhileloop">
+ <description>
+Some for loops can be simplified to while loops, this makes them more concise.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ForStatement
+ [not(LocalVariableDeclaration)]
+ [not(ForInit)]
+ [not(ForUpdate)]
+ [Expression]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ for (;true;) true; // No Init or Update part, may as well be: while (true)
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ForLoopsMustUseBraces"
+ language="java"
+ since="0.7"
+ deprecated="true"
+ message="Avoid using 'for' statements without curly braces"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#forloopsmustusebraces">
+ <description>
+Avoid using 'for' statements without using curly braces. If the code formatting or
+indentation is lost then it becomes difficult to separate the code being controlled
+from the rest.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//ForStatement[not(Statement/Block)]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+for (int i = 0; i < 42; i++)
+ foo();
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="FormalParameterNamingConventions"
+ since="6.6.0"
+ message="The {0} name ''{1}'' doesn''t match ''{2}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.FormalParameterNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#formalparameternamingconventions">
+ <description>
+ Configurable naming conventions for formal parameters of methods and lambdas.
+ This rule reports formal parameters which do not match the regex that applies to their
+ specific kind (e.g. lambda parameter, or final formal parameter). Each regex can be
+ configured through properties.
+
+ By default this rule uses the standard Java naming convention (Camel case).
+ </description>
+ <priority>1</priority>
+ <example>
+ <![CDATA[
+ class Foo {
+
+ abstract void bar(int myInt); // This is Camel case, so it's ok
+
+ void bar(int my_i) { // this will be reported
+
+ }
+
+ void lambdas() {
+
+ // lambdas parameters can be configured separately
+ Consumer<String> lambda1 = s_str -> { };
+
+ // lambda parameters with an explicit type can be configured separately
+ Consumer<String> lambda1 = (String str) -> { };
+
+ }
+
+ }
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="GenericsNaming"
+ language="java"
+ since="4.2.6"
+ message="Generics names should be a one letter long and upper case."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#genericsnaming">
+ <description>
+Names for references to generic values should be limited to a single uppercase letter.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//TypeDeclaration/ClassOrInterfaceDeclaration/TypeParameters/TypeParameter[
+ string-length(@Image) > 1
+ or
+ string:upper-case(@Image) != @Image
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public interface GenericDao<E extends BaseModel, K extends Serializable> extends BaseDao {
+ // This is ok...
+}
+
+public interface GenericDao<E extends BaseModel, K extends Serializable> {
+ // Also this
+}
+
+public interface GenericDao<e extends BaseModel, K extends Serializable> {
+ // 'e' should be an 'E'
+}
+
+public interface GenericDao<EF extends BaseModel, K extends Serializable> {
+ // 'EF' is not ok.
+}
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="IdenticalCatchBranches"
+ language="java"
+ since="6.4.0"
+ minimumLanguageVersion="1.7"
+ message="''catch'' branch identical to ''{0}'' branch"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.IdenticalCatchBranchesRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#identicalcatchbranches">
+ <description>
+ Identical `catch` branches use up vertical space and increase the complexity of code without
+ adding functionality. It's better style to collapse identical branches into a single multi-catch
+ branch.
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+try {
+ // do something
+} catch (IllegalArgumentException e) {
+ throw e;
+} catch (IllegalStateException e) { // Can be collapsed into the previous block
+ throw e;
+}
+
+try {
+ // do something
+} catch (IllegalArgumentException | IllegalStateException e) { // This is better
+ throw e;
+}
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="IfElseStmtsMustUseBraces"
+ language="java"
+ since="0.2"
+ deprecated="true"
+ message="Avoid using 'if...else' statements without curly braces"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#ifelsestmtsmustusebraces">
+ <description>
+Avoid using if..else statements without using surrounding braces. If the code formatting
+or indentation is lost then it becomes difficult to separate the code being controlled
+from the rest.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Statement
+ [parent::IfStatement[@Else='true']]
+ [not(child::Block)]
+ [not(child::IfStatement)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+ // this is OK
+if (foo) x++;
+
+ // but this is not
+if (foo)
+ x = x+1;
+ else
+ x = x-1;
+]]>
+ </example>
+ </rule>
+
+ <rule name="IfStmtsMustUseBraces"
+ language="java"
+ since="1.0"
+ deprecated="true"
+ message="Avoid using if statements without curly braces"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#ifstmtsmustusebraces">
+ <description>
+Avoid using if statements without using braces to surround the code block. If the code
+formatting or indentation is lost then it becomes difficult to separate the code being
+controlled from the rest.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//IfStatement[count(*) < 3][not(Statement/Block)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+ <![CDATA[
+if (foo) // not recommended
+ x++;
+
+if (foo) { // preferred approach
+ x++;
+}
+
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="LinguisticNaming"
+ language="java"
+ since="6.7.0"
+ message="Linguistics Antipattern - Method name and return type is inconsistent linguistically"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.LinguisticNamingRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming"
+ typeResolution="true">
+ <description>
+ This rule finds Linguistic Naming Antipatterns. It checks for fields, that are named, as if they should
+ be boolean but have a different type. It also checks for methods, that according to their name, should
+ return a boolean, but don't. Further, it checks, that getters return something and setters won't.
+ Finally, it checks that methods, that start with "to" - so called transform methods - actually return
+ something, since according to their name, they should convert or transform one object into another.
+ There is additionally an option, to check for methods that contain "To" in their name - which are
+ also transform methods. However, this is disabled by default, since this detection is prone to
+ false positives.
+
+ For more information, see [Linguistic Antipatterns - What They Are and How
+Developers Perceive Them](https://doi.org/10.1007/s10664-014-9350-8).
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class LinguisticNaming {
+ int isValid; // the field name indicates a boolean, but it is an int.
+ boolean isTrue; // correct type of the field
+
+ void myMethod() {
+ int hasMoneyLocal; // the local variable name indicates a boolean, but it is an int.
+ boolean hasSalaryLocal; // correct naming and type
+ }
+
+ // the name of the method indicates, it is a boolean, but the method returns an int.
+ int isValid() {
+ return 1;
+ }
+ // correct naming and return type
+ boolean isSmall() {
+ return true;
+ }
+
+ // the name indicates, this is a setter, but it returns something
+ int setName() {
+ return 1;
+ }
+
+ // the name indicates, this is a getter, but it doesn't return anything
+ void getName() {
+ // nothing to return?
+ }
+
+ // the name indicates, it transforms an object and should return the result
+ void toDataType() {
+ // nothing to return?
+ }
+ // the name indicates, it transforms an object and should return the result
+ void grapeToWine() {
+ // nothing to return?
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LocalHomeNamingConvention"
+ language="java"
+ since="4.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="The Local Home interface of a Session EJB should be suffixed by 'LocalHome'"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localhomenamingconvention">
+ <description>
+The Local Home interface of a Session EJB should be suffixed by 'LocalHome'.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+[
+ (
+ (./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalHome')])
+ )
+ and
+ not
+ (
+ ends-with(@Image,'LocalHome')
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public interface MyBeautifulLocalHome extends javax.ejb.EJBLocalHome {} // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBLocalHome {} // non-standard name
+]]>
+ </example>
+ </rule>
+
+ <rule name="LocalInterfaceSessionNamingConvention"
+ language="java"
+ since="4.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="The Local Interface of a Session EJB should be suffixed by 'Local'"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localinterfacesessionnamingconvention">
+ <description>
+The Local Interface of a Session EJB should be suffixed by 'Local'.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+[
+ (
+ (./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalObject')])
+ )
+ and
+ not
+ (
+ ends-with(@Image,'Local')
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public interface MyLocal extends javax.ejb.EJBLocalObject {} // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBLocalObject {} // non-standard name
+]]>
+ </example>
+ </rule>
+
+ <rule name="LocalVariableCouldBeFinal"
+ since="2.2"
+ message="Local variable ''{0}'' could be declared final"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableCouldBeFinalRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localvariablecouldbefinal">
+ <description>
+A local variable assigned only once can be declared final.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Bar {
+ public void foo () {
+ String txtA = "a"; // if txtA will not be assigned again it is better to do this:
+ final String txtB = "b";
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LocalVariableNamingConventions"
+ since="6.6.0"
+ message="The {0} name ''{1}'' doesn''t match ''{2}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localvariablenamingconventions">
+ <description>
+ Configurable naming conventions for local variable declarations and other locally-scoped
+ variables. This rule reports variable declarations which do not match the regex that applies to their
+ specific kind (e.g. final variable, or catch-clause parameter). Each regex can be configured through
+ properties.
+
+ By default this rule uses the standard Java naming convention (Camel case).
+ </description>
+ <priority>1</priority>
+ <example>
+ <![CDATA[
+ class Foo {
+ void bar() {
+ int localVariable = 1; // This is in camel case, so it's ok
+ int local_variable = 1; // This will be reported unless you change the regex
+
+ final int i_var = 1; // final local variables can be configured separately
+
+ try {
+ foo();
+ } catch (IllegalArgumentException e_illegal) {
+ // exception block parameters can be configured separately
+ }
+
+ }
+ }
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="LongVariable"
+ language="java"
+ since="0.3"
+ message="Avoid excessively long variable names like {0}"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#longvariable">
+ <description>
+Fields, formal arguments, or local variable names that are too long can make the code difficult to follow.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="minimum" type="Integer" description="The variable length reporting threshold" min="1" max="100" value="17"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//VariableDeclaratorId[string-length(@Image) > $minimum]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Something {
+ int reallyLongIntName = -3; // VIOLATION - Field
+ public static void main( String argumentsList[] ) { // VIOLATION - Formal
+ int otherReallyLongName = -5; // VIOLATION - Local
+ for (int interestingIntIndex = 0; // VIOLATION - For
+ interestingIntIndex < 10;
+ interestingIntIndex ++ ) {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MDBAndSessionBeanNamingConvention"
+ language="java"
+ since="4.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="SessionBean or MessageBean should be suffixed by Bean"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#mdbandsessionbeannamingconvention">
+ <description>
+The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//TypeDeclaration/ClassOrInterfaceDeclaration
+[
+ (
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'SessionBean')])
+ or
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'MessageDrivenBean')])
+ )
+ and
+ not
+ (
+ ends-with(@Image,'Bean')
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SomeBean implements SessionBean{} // proper name
+
+public class MissingTheProperSuffix implements SessionBean {} // non-standard name
+]]>
+ </example>
+ </rule>
+
+ <rule name="MethodArgumentCouldBeFinal"
+ since="2.2"
+ message="Parameter ''{0}'' is not assigned and could be declared final"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodArgumentCouldBeFinalRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#methodargumentcouldbefinal">
+ <description>
+A method argument that is never re-assigned within the method can be declared final.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void foo1 (String param) { // do stuff with param never assigning it
+
+}
+
+public void foo2 (final String param) { // better, do stuff with param never assigning it
+
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MethodNamingConventions"
+ since="1.2"
+ message="The {0} name ''{1}'' doesn''t match ''{2}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#methodnamingconventions">
+ <description>
+ Configurable naming conventions for method declarations. This rule reports
+ method declarations which do not match the regex that applies to their
+ specific kind (e.g. JUnit test or native method). Each regex can be
+ configured through properties.
+
+ By default this rule uses the standard Java naming convention (Camel case).
+ </description>
+ <priority>1</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void fooStuff() {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MIsLeadingVariableName"
+ language="java"
+ since="3.4"
+ deprecated="true"
+ message="Avoid naming non-fields with the prefix 'm_'"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#misleadingvariablename">
+ <description>
+Detects when a non-field has a name starting with 'm_'. This usually denotes a field and could be confusing.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//VariableDeclaratorId
+[starts-with(@Image, 'm_')]
+[not (../../../FieldDeclaration)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private int m_foo; // OK
+ public void bar(String m_baz) { // Bad
+ int m_boz = 42; // Bad
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NoPackage"
+ language="java"
+ since="3.3"
+ message="All classes and interfaces must belong to a named package"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#nopackage">
+ <description>
+Detects when a class or interface does not have a package definition.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//ClassOrInterfaceDeclaration[count(preceding::PackageDeclaration) = 0]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// no package declaration
+public class ClassInDefaultPackage {
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="OnlyOneReturn"
+ since="1.0"
+ message="A method should have only one exit point, and that should be the last statement in the method"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.OnlyOneReturnRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#onlyonereturn">
+ <description>
+A method should have only one exit point, and that should be the last statement in the method.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class OneReturnOnly1 {
+ public void foo(int x) {
+ if (x > 0) {
+ return "hey"; // first exit
+ }
+ return "hi"; // second exit
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="PackageCase"
+ language="java"
+ since="3.3"
+ message="Package name contains upper case characters"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#packagecase">
+ <description>
+Detects when a package definition contains uppercase characters.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//PackageDeclaration/Name[lower-case(@Image)!=@Image]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+package com.MyCompany; // should be lowercase name
+
+public class SomeClass {
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="PrematureDeclaration"
+ language="java"
+ since="5.0"
+ message="Avoid declaring a variable if it is unreferenced before a possible exit point."
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.PrematureDeclarationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#prematuredeclaration">
+ <description>
+Checks for variables that are defined before they might be used. A reference is deemed to be premature if it is created right before a block of code that doesn't use it that also has the ability to return or throw an exception.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public int getLength(String[] strings) {
+
+ int length = 0; // declared prematurely
+
+ if (strings == null || strings.length == 0) return 0;
+
+ for (String str : strings) {
+ length += str.length();
+ }
+
+ return length;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="RemoteInterfaceNamingConvention"
+ language="java"
+ since="4.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Remote Interface of a Session EJB should NOT be suffixed"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#remoteinterfacenamingconvention">
+ <description>
+Remote Interface of a Session EJB should not have a suffix.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+[
+ (
+ (./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBObject')])
+ )
+ and
+ (
+ ends-with(@Image,'Session')
+ or
+ ends-with(@Image,'EJB')
+ or
+ ends-with(@Image,'Bean')
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+/* Poor Session suffix */
+public interface BadSuffixSession extends javax.ejb.EJBObject {}
+
+/* Poor EJB suffix */
+public interface BadSuffixEJB extends javax.ejb.EJBObject {}
+
+/* Poor Bean suffix */
+public interface BadSuffixBean extends javax.ejb.EJBObject {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="RemoteSessionInterfaceNamingConvention"
+ language="java"
+ since="4.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Remote Home interface of a Session EJB should be suffixed by 'Home'"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#remotesessioninterfacenamingconvention">
+ <description>
+A Remote Home interface type of a Session EJB should be suffixed by 'Home'.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+[
+ (
+ (./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBHome')])
+ )
+ and
+ not
+ (
+ ends-with(@Image,'Home')
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public interface MyBeautifulHome extends javax.ejb.EJBHome {} // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBHome {} // non-standard name
+]]>
+ </example>
+ </rule>
+
+ <rule name="ShortClassName"
+ language="java"
+ since="5.0"
+ message="Avoid short class names like {0}"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortclassname">
+ <description>
+Short Classnames with fewer than e.g. five characters are not recommended.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="minimum" type="Integer" value="5" min="1" max="100" description="Number of characters that are required as a minimum for a class name."/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[string-length(@Image) < $minimum]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ShortMethodName"
+ language="java"
+ since="0.3"
+ message="Avoid using short method names"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortmethodname">
+ <description>
+Method names that are very short are not helpful to the reader.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="minimum" type="Integer" value="3" min="1" max="100" description="Number of characters that are required as a minimum for a method name."/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclarator[string-length(@Image) < $minimum]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class ShortMethod {
+ public void a( int i ) { // Violation
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ShortVariable"
+ language="java"
+ since="0.3"
+ message="Avoid variables with short names like {0}"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortvariable">
+ <description>
+Fields, local variables, or parameter names that are very short are not helpful to the reader.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="minimum" type="Integer" value="3" min="1" max="100" description="Number of characters that are required as a minimum for a variable name."/>
+ <property name="version" value="2.0"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//VariableDeclaratorId[string-length(@Image) < $minimum]
+ (: ForStatement :)
+ [not(../../..[self::ForInit])]
+ (: Foreach statement :)
+ [not(../../..[self::ForStatement])]
+ (: Catch statement parameter :)
+ [not(../..[self::CatchStatement])]
+ (: Lambda expression parameter :)
+ [not(parent::LambdaExpression or ../../..[self::LambdaExpression])]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Something {
+ private int q = 15; // field - too short
+ public static void main( String as[] ) { // formal arg - too short
+ int r = 20 + q; // local var - too short
+ for (int i = 0; i < 10; i++) { // not a violation (inside 'for' loop)
+ r += q;
+ }
+ for (Integer i : numbers) { // not a violation (inside 'for-each' loop)
+ r += q;
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SuspiciousConstantFieldName"
+ language="java"
+ since="2.0"
+ deprecated="true"
+ message="The field name indicates a constant but its modifiers do not"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#suspiciousconstantfieldname">
+ <description>
+Field names using all uppercase characters - Sun's Java naming conventions indicating constants - should
+be declared as final.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Interface='false']
+ /ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/FieldDeclaration
+ [@Final='false']
+ [VariableDeclarator/VariableDeclaratorId[upper-case(@Image)=@Image]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ // this is bad, since someone could accidentally
+ // do PI = 2.71828; which is actually e
+ // final double PI = 3.16; is ok
+ double PI = 3.16;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="TooManyStaticImports"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Too many static imports may lead to messy code"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#toomanystaticimports">
+ <description>
+If you overuse the static import feature, it can make your program unreadable and
+unmaintainable, polluting its namespace with all the static members you import.
+Readers of your code (including you, a few months after you wrote it) will not know
+which class a static member comes from (Sun 1.5 Language Guide).
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="maximumStaticImports" type="Integer"
+ description="All static imports can be disallowed by setting this to 0" min="0" max="100" value="4"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+.[count(ImportDeclaration[@Static = 'true']) > $maximumStaticImports]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+import static Lennon;
+import static Ringo;
+import static George;
+import static Paul;
+import static Yoko; // Too much !
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="UnnecessaryAnnotationValueElement"
+ since="6.2.0"
+ message="Avoid the use of value in annotations when it's the only element"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryAnnotationValueElementRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryannotationvalueelement">
+ <description>
+ Avoid the use of value in annotations when it's the only element.
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+@TestClassAnnotation(value = "TEST")
+public class Foo {
+
+ @TestMemberAnnotation(value = "TEST")
+ private String y;
+
+ @TestMethodAnnotation(value = "TEST")
+ public void bar() {
+ int x = 42;
+ return;
+ }
+}
+
+// should be
+
+@TestClassAnnotation("TEST")
+public class Foo {
+
+ @TestMemberAnnotation("TEST")
+ private String y;
+
+ @TestMethodAnnotation("TEST")
+ public void bar() {
+ int x = 42;
+ return;
+ }
+}
+
+]]>
+ </example>
+ </rule>
+
+
+ <rule name="UnnecessaryConstructor"
+ language="java"
+ since="1.0"
+ message="Avoid unnecessary constructors - the compiler will generate these for you"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryConstructorRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryconstructor">
+ <description>
+This rule detects when a constructor is not necessary; i.e., when there is only one constructor and the
+constructor is identical to the default constructor. The default constructor should has same access
+modifier as the declaring class. In an enum type, the default constructor is implicitly private.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public Foo() {}
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryFullyQualifiedName"
+ language="java"
+ since="5.0"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameRule"
+ message="Unnecessary use of fully qualified name ''{0}'' due to existing {2}import ''{1}''"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname">
+ <description>
+Import statements allow the use of non-fully qualified names. The use of a fully qualified name
+which is covered by an import statement is redundant. Consider using the non-fully qualified name.
+ </description>
+ <priority>4</priority>
+ <example>
+<![CDATA[
+import java.util.List;
+
+public class Foo {
+ private java.util.List list1; // Unnecessary FQN
+ private List list2; // More appropriate given import of 'java.util.List'
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryLocalBeforeReturn"
+ since="3.3"
+ message="Consider simply returning the value vs storing it in local variable ''{0}''"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryLocalBeforeReturnRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarylocalbeforereturn">
+ <description>
+Avoid the creation of unnecessary local variables
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public int foo() {
+ int x = doSomething();
+ return x; // instead, just 'return doSomething();'
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryModifier"
+ language="java"
+ since="1.02"
+ message="Unnecessary modifier{0} on {1} ''{2}''{3}"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryModifierRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarymodifier">
+ <description>
+Fields in interfaces and annotations are automatically `public static final`, and methods are `public abstract`.
+Classes, interfaces or annotations nested in an interface or annotation are automatically `public static`
+(all nested interfaces and annotations are automatically static).
+Nested enums are automatically `static`.
+For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public @interface Annotation {
+ public abstract void bar(); // both abstract and public are ignored by the compiler
+ public static final int X = 0; // public, static, and final all ignored
+ public static class Bar {} // public, static ignored
+ public static interface Baz {} // ditto
+}
+public interface Foo {
+ public abstract void bar(); // both abstract and public are ignored by the compiler
+ public static final int X = 0; // public, static, and final all ignored
+ public static class Bar {} // public, static ignored
+ public static interface Baz {} // ditto
+}
+public class Bar {
+ public static interface Baz {} // static ignored
+ public static enum FoorBar { // static ignored
+ FOO;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryReturn"
+ since="1.3"
+ message="Avoid unnecessary return statements"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryReturnRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryreturn">
+ <description>
+Avoid the use of unnecessary return statements.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ int x = 42;
+ return;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UselessParentheses"
+ language="java"
+ since="5.0"
+ message="Useless parentheses."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#uselessparentheses">
+ <description>Useless parentheses should be removed.</description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Expression[not(parent::PrimaryPrefix)]/PrimaryExpression[count(*)>1]
+ /PrimaryPrefix/Expression
+ [not(./CastExpression)]
+ [not(./ConditionalExpression)]
+ [not(./AdditiveExpression)]
+ [not(./AssignmentOperator)]
+|
+//Expression[not(parent::PrimaryPrefix)]/PrimaryExpression[count(*)=1]
+ /PrimaryPrefix/Expression
+|
+//Expression/ConditionalAndExpression/PrimaryExpression/PrimaryPrefix/Expression[
+ count(*)=1 and
+ count(./CastExpression)=0 and
+ count(./EqualityExpression/MultiplicativeExpression)=0 and
+ count(./ConditionalExpression)=0 and
+ count(./ConditionalOrExpression)=0]
+|
+//Expression/ConditionalOrExpression/PrimaryExpression/PrimaryPrefix/Expression[
+ count(*)=1 and
+ not(./CastExpression) and
+ not(./ConditionalExpression) and
+ not(./EqualityExpression/MultiplicativeExpression)]
+|
+//Expression/ConditionalExpression/PrimaryExpression/PrimaryPrefix/Expression[
+ count(*)=1 and
+ not(./CastExpression) and
+ not(./EqualityExpression)]
+|
+//Expression/AdditiveExpression[not(./PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral='true'])]
+ /PrimaryExpression[1]/PrimaryPrefix/Expression[
+ count(*)=1 and
+ not(./CastExpression) and
+ not(./AdditiveExpression[@Image = '-']) and
+ not(./ShiftExpression) and
+ not(./RelationalExpression) and
+ not(./InstanceOfExpression) and
+ not(./EqualityExpression) and
+ not(./AndExpression) and
+ not(./ExclusiveOrExpression) and
+ not(./InclusiveOrExpression) and
+ not(./ConditionalAndExpression) and
+ not(./ConditionalOrExpression) and
+ not(./ConditionalExpression)]
+|
+//Expression/EqualityExpression/PrimaryExpression/PrimaryPrefix/Expression[
+ count(*)=1 and
+ not(./CastExpression) and
+ not(./AndExpression) and
+ not(./InclusiveOrExpression) and
+ not(./ExclusiveOrExpression) and
+ not(./ConditionalExpression) and
+ not(./ConditionalAndExpression) and
+ not(./ConditionalOrExpression) and
+ not(./EqualityExpression)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+
+ private int _bar1;
+ private Integer _bar2;
+
+ public void setBar(int n) {
+ _bar1 = Integer.valueOf((n)); // here
+ _bar2 = (n); // and here
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UselessQualifiedThis"
+ language="java"
+ since="5.4.0"
+ message="Useless qualified this usage in the same class."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#uselessqualifiedthis">
+ <description>Look for qualified this usages in the same class.</description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+[PrimaryPrefix/Name[@Image]]
+[PrimarySuffix[@Arguments='false']]
+[not(PrimarySuffix/MemberSelector)]
+[ancestor::ClassOrInterfaceBodyDeclaration[1][@AnonymousInnerClass='false']]
+/PrimaryPrefix/Name[@Image = ancestor::ClassOrInterfaceDeclaration[1]/@Image]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ final Foo otherFoo = Foo.this; // use "this" directly
+
+ public void doSomething() {
+ final Foo anotherFoo = Foo.this; // use "this" directly
+ }
+
+ private ActionListener returnListener() {
+ return new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ doSomethingWithQualifiedThis(Foo.this); // This is fine
+ }
+ };
+ }
+
+ private class Foo3 {
+ final Foo myFoo = Foo.this; // This is fine
+ }
+
+ private class Foo2 {
+ final Foo2 myFoo2 = Foo2.this; // Use "this" direclty
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="VariableNamingConventions"
+ since="1.2"
+ deprecated="true"
+ message="{0} variable {1} should begin with {2}"
+ class="net.sourceforge.pmd.lang.java.rule.codestyle.VariableNamingConventionsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#variablenamingconventions">
+ <description>
+A variable naming conventions rule - customize this to your liking. Currently, it
+checks for final variables that should be fully capitalized and non-final variables
+that should not include underscores.
+ </description>
+ <priority>1</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public static final int MY_NUM = 0;
+ public String myTest = "";
+ DataModule dmTest = new DataModule();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="WhileLoopsMustUseBraces"
+ language="java"
+ since="0.7"
+ deprecated="true"
+ message="Avoid using 'while' statements without curly braces"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#whileloopsmustusebraces">
+ <description>
+Avoid using 'while' statements without using braces to surround the code block. If the code
+formatting or indentation is lost then it becomes difficult to separate the code being
+controlled from the rest.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//WhileStatement[not(Statement/Block)]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+while (true) // not recommended
+ x++;
+
+while (true) { // preferred approach
+ x++;
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/category/java/design.xml b/dev/src/main/resources/pmd/category/java/design.xml
new file mode 100644
index 0000000..bfe62f7
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/design.xml
@@ -0,0 +1,1652 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Design"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules that help you discover design issues.
+ </description>
+
+ <rule name="AbstractClassWithoutAnyMethod"
+ language="java"
+ since="4.2"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ message="No abstract method which means that the keyword is most likely used to prevent instantiation. Use a private or protected constructor instead."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#abstractclasswithoutanymethod">
+ <description>
+If an abstract class does not provides any methods, it may be acting as a simple data container
+that is not meant to be instantiated. In this case, it is probably better to use a private or
+protected constructor in order to prevent instantiation than make the class misleadingly abstract.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+ [@Abstract = 'true']
+ [count(//MethodDeclaration) + count(//ConstructorDeclaration) = 0]
+ [not(../Annotation/MarkerAnnotation/Name[pmd-java:typeIs('com.google.auto.value.AutoValue')])]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public abstract class Example {
+ String field;
+ int otherField;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidCatchingGenericException"
+ since="4.2.6"
+ language="java"
+ message="Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidcatchinggenericexception">
+ <description>
+Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement/FormalParameter/Type/ReferenceType/ClassOrInterfaceType[
+ @Image='NullPointerException' or
+ @Image='Exception' or
+ @Image='RuntimeException']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+package com.igate.primitive;
+
+public class PrimitiveType {
+
+ public void downCastPrimitiveType() {
+ try {
+ System.out.println(" i [" + i + "]");
+ } catch(Exception e) {
+ e.printStackTrace();
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ } catch(NullPointerException e) {
+ e.printStackTrace();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidDeeplyNestedIfStmts"
+ since="1.0"
+ message="Deeply nested if..then statements are hard to read"
+ class="net.sourceforge.pmd.lang.java.rule.design.AvoidDeeplyNestedIfStmtsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoiddeeplynestedifstmts">
+ <description>
+Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar(int x, int y, int z) {
+ if (x>y) {
+ if (y>z) {
+ if (z==x) {
+ // !! too deep
+ }
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidRethrowingException"
+ language="java"
+ since="3.8"
+ message="A catch statement that catches an exception only to rethrow it should be avoided."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidrethrowingexception">
+ <description>
+Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement[FormalParameter
+ /VariableDeclaratorId/@Image = Block/BlockStatement/Statement
+ /ThrowStatement/Expression/PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix/Name/@Image
+ and count(Block/BlockStatement/Statement) =1]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ try {
+ // do something
+ } catch (SomeException se) {
+ throw se;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidThrowingNewInstanceOfSameException"
+ since="4.2.5"
+ language="java"
+ message="A catch statement that catches an exception only to wrap it in a new instance of the same type of exception and throw it should be avoided"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingnewinstanceofsameexception">
+ <description>
+Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to
+code size and runtime complexity.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement[
+ count(Block/BlockStatement/Statement) = 1
+ and
+ FormalParameter/Type/ReferenceType/ClassOrInterfaceType/@Image = Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/ClassOrInterfaceType/@Image
+ and
+ count(Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/Arguments/ArgumentList/Expression) = 1
+ and
+ FormalParameter/VariableDeclaratorId = Block/BlockStatement/Statement/ThrowStatement/Expression/PrimaryExpression/PrimaryPrefix/AllocationExpression/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ try {
+ // do something
+ } catch (SomeException se) {
+ // harmless comment
+ throw new SomeException(se);
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidThrowingNullPointerException"
+ language="java"
+ since="1.8"
+ message="Avoid throwing null pointer exceptions."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingnullpointerexception">
+ <description>
+<![CDATA[
+Avoid throwing NullPointerExceptions manually. These are confusing because most people will assume that the
+virtual machine threw it. To avoid a method being called with a null parameter, you may consider
+using an IllegalArgumentException instead, making it clearly seen as a programmer-initiated exception.
+However, there are better ways to handle this:
+
+>*Effective Java, 3rd Edition, Item 72: Favor the use of standard exceptions*
+>
+>Arguably, every erroneous method invocation boils down to an illegal argument or state,
+but other exceptions are standardly used for certain kinds of illegal arguments and states.
+If a caller passes null in some parameter for which null values are prohibited, convention dictates that
+NullPointerException be thrown rather than IllegalArgumentException.
+
+To implement that, you are encouraged to use `java.util.Objects.requireNonNull()`
+(introduced in Java 1.7). This method is designed primarily for doing parameter
+validation in methods and constructors with multiple parameters.
+
+Your parameter validation could thus look like the following:
+```
+public class Foo {
+ private String exampleValue;
+
+ void setExampleValue(String exampleValue) {
+ // check, throw and assignment in a single standard call
+ this.exampleValue = Objects.requireNonNull(exampleValue, "exampleValue must not be null!");
+ }
+ }
+```
+]]>
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression/ClassOrInterfaceType[@Image='NullPointerException']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ throw new NullPointerException();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidThrowingRawExceptionTypes"
+ language="java"
+ since="1.8"
+ message="Avoid throwing raw exception types."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingrawexceptiontypes">
+ <description>
+Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,
+Exception, or Error, use a subclassed exception or error instead.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ThrowStatement//AllocationExpression
+ /ClassOrInterfaceType[
+ pmd-java:typeIsExactly('java.lang.Throwable')
+or
+ pmd-java:typeIsExactly('java.lang.Exception')
+or
+ pmd-java:typeIsExactly('java.lang.Error')
+or
+ pmd-java:typeIsExactly('java.lang.RuntimeException')
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() throws Exception {
+ throw new Exception();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ClassWithOnlyPrivateConstructorsShouldBeFinal"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="A class which only has private constructors should be final"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#classwithonlyprivateconstructorsshouldbefinal">
+ <description>
+A class with only private constructors should be final, unless the private constructor
+is invoked by a inner class.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+TypeDeclaration[count(../TypeDeclaration) = 1]/ClassOrInterfaceDeclaration
+[@Final = 'false']
+[count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private = 'true']) >= 1 ]
+[count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[(@Public = 'true') or (@Protected = 'true') or (@PackagePrivate = 'true')]) = 0 ]
+[not(.//ClassOrInterfaceDeclaration)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo { //Should be final
+ private Foo() { }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CollapsibleIfStatements"
+ language="java"
+ since="3.1"
+ message="These nested if statements could be combined"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#collapsibleifstatements">
+ <description>
+Sometimes two consecutive 'if' statements can be consolidated by separating their conditions with a boolean short-circuit operator.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//IfStatement[@Else='false']/Statement
+ /IfStatement[@Else='false']
+ |
+//IfStatement[@Else='false']/Statement
+ /Block[count(BlockStatement)=1]/BlockStatement
+ /Statement/IfStatement[@Else='false']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+void bar() {
+ if (x) { // original implementation
+ if (y) {
+ // do stuff
+ }
+ }
+}
+
+void bar() {
+ if (x && y) { // optimized implementation
+ // do stuff
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CouplingBetweenObjects"
+ since="1.04"
+ message="High amount of different objects as members denotes a high coupling"
+ class="net.sourceforge.pmd.lang.java.rule.design.CouplingBetweenObjectsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#couplingbetweenobjects">
+ <description>
+This rule counts the number of unique attributes, local variables, and return types within an object.
+A number higher than the specified threshold can indicate a high degree of coupling.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+import com.Blah;
+import org.Bar;
+import org.Bardo;
+
+public class Foo {
+ private Blah var1;
+ private Bar var2;
+
+ //followed by many imports of unique objects
+ void ObjectC doWork() {
+ Bardo var55;
+ ObjectA var44;
+ ObjectZ var93;
+ return something;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CyclomaticComplexity"
+ message="The {0} ''{1}'' has a{2} cyclomatic complexity of {3}."
+ since="1.03"
+ class="net.sourceforge.pmd.lang.java.rule.design.CyclomaticComplexityRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#cyclomaticcomplexity">
+ <description><![CDATA[
+The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic
+in a single method makes its behaviour hard to read and change.
+
+Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method,
+plus one for the method entry. Decision points are places where the control flow jumps to another place in the
+program. As such, they include all control flow statements, such as `if`, `while`, `for`, and `case`. For more
+details on the calculation, see the documentation of the [Cyclo metric](/pmd_java_metrics_index.html#cyclomatic-complexity-cyclo).
+
+Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
+high complexity, and 11+ is very high complexity. By default, this rule reports methods with a complexity >= 10.
+Additionnally, classes with many methods of moderate complexity get reported as well once the total of their
+methods' complexities reaches 80, even if none of the methods was directly reported.
+
+Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down
+into subcomponents.]]>
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+class Foo {
+ void baseCyclo() { // Cyclo = 1
+ highCyclo();
+ }
+
+ void highCyclo() { // Cyclo = 10: reported!
+ int x = 0, y = 2;
+ boolean a = false, b = true;
+
+ if (a && (y == 1 ? b : true)) { // +3
+ if (y == x) { // +1
+ while (true) { // +1
+ if (x++ < 20) { // +1
+ break; // +1
+ }
+ }
+ } else if (y == t && !d) { // +2
+ x = a ? y : x; // +1
+ } else {
+ x = 2;
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DataClass"
+ since="6.0.0"
+ message="The class ''{0}'' is suspected to be a Data Class (WOC={1}, NOPA={2}, NOAM={3}, WMC={4})"
+ class="net.sourceforge.pmd.lang.java.rule.design.DataClassRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#dataclass">
+ <description>
+Data Classes are simple data holders, which reveal most of their state, and
+without complex functionality. The lack of functionality may indicate that
+their behaviour is defined elsewhere, which is a sign of poor data-behaviour
+proximity. By directly exposing their internals, Data Classes break encapsulation,
+and therefore reduce the system's maintainability and understandability. Moreover,
+classes tend to strongly rely on their data representation, which makes for a brittle
+design.
+
+Refactoring a Data Class should focus on restoring a good data-behaviour proximity. In
+most cases, that means moving the operations defined on the data back into the class.
+In some other cases it may make sense to remove entirely the class and move the data
+into the former client classes.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class DataClass {
+
+ public int bar = 0;
+ public int na = 0;
+ private int bee = 0;
+
+ public void setBee(int n) {
+ bee = n;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotExtendJavaLangError"
+ language="java"
+ typeResolution="true"
+ since="4.0"
+ message="Exceptions should not extend java.lang.Error"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#donotextendjavalangerror">
+ <description>
+Errors are system exceptions. Do not extend them.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType
+ [pmd-java:typeIs('java.lang.Error')]
+
+
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo extends Error { }
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExceptionAsFlowControl"
+ since="1.8"
+ message="Avoid using exceptions as flow control."
+ class="net.sourceforge.pmd.lang.java.rule.design.ExceptionAsFlowControlRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#exceptionasflowcontrol">
+ <description>
+Using Exceptions as form of flow control is not recommended as they obscure true exceptions when debugging.
+Either add the necessary validation or use an alternate control structure.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void bar() {
+ try {
+ try {
+ } catch (Exception e) {
+ throw new WrapperException(e);
+ // this is essentially a GOTO to the WrapperException catch block
+ }
+ } catch (WrapperException e) {
+ // do some more stuff
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExcessiveClassLength"
+ since="0.6"
+ message="Avoid really long classes."
+ class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveClassLengthRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessiveclasslength">
+ <description>
+Excessive class file lengths are usually indications that the class may be burdened with excessive
+responsibilities that could be provided by external classes or functions. In breaking these methods
+apart the code becomes more manageable and ripe for reuse.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar1() {
+ // 1000 lines of code
+ }
+ public void bar2() {
+ // 1000 lines of code
+ }
+ public void bar3() {
+ // 1000 lines of code
+ }
+
+ public void barN() {
+ // 1000 lines of code
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExcessiveImports"
+ since="1.04"
+ message="A high number of imports can indicate a high degree of coupling within an object."
+ class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveImportsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessiveimports">
+ <description>
+A high number of imports can indicate a high degree of coupling within an object. This rule
+counts the number of unique imports and reports a violation if the count is above the
+user-specified threshold.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+import blah.blah.Baz;
+import blah.blah.Bif;
+// 18 others from the same package elided
+public class Foo {
+ public void doWork() {}
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExcessiveMethodLength"
+ since="0.6"
+ message="Avoid really long methods."
+ class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveMethodLengthRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessivemethodlength">
+ <description>
+When methods are excessively long this usually indicates that the method is doing more than its
+name/signature might suggest. They also become challenging for others to digest since excessive
+scrolling causes readers to lose focus.
+Try to reduce the method length by creating helper methods and removing any copy/pasted code.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void doSomething() {
+ System.out.println("Hello world!");
+ System.out.println("Hello world!");
+ // 98 copies omitted for brevity.
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExcessiveParameterList"
+ since="0.9"
+ message="Avoid long parameter lists."
+ class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveParameterListRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessiveparameterlist">
+ <description>
+Methods with numerous parameters are a challenge to maintain, especially if most of them share the
+same datatype. These situations usually denote the need for new objects to wrap the numerous parameters.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void addPerson( // too many arguments liable to be mixed up
+ int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {
+
+ . . . .
+}
+
+public void addPerson( // preferred approach
+ Date birthdate, BodyMeasurements measurements, int ssn) {
+
+ . . . .
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ExcessivePublicCount"
+ since="1.04"
+ message="This class has a bunch of public methods and attributes"
+ class="net.sourceforge.pmd.lang.java.rule.design.ExcessivePublicCountRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessivepubliccount">
+ <description>
+Classes with large numbers of public methods and attributes require disproportionate testing efforts
+since combinational side effects grow rapidly and increase risk. Refactoring these classes into
+smaller ones not only increases testability and reliability but also allows new variations to be
+developed easily.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public String value;
+ public Bar something;
+ public Variable var;
+ // [... more more public attributes ...]
+
+ public void doWork() {}
+ public void doMoreWork() {}
+ public void doWorkAgain() {}
+ // [... more more public methods ...]
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FinalFieldCouldBeStatic"
+ language="java"
+ since="1.1"
+ message="This final field could be made static"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#finalfieldcouldbestatic">
+ <description>
+If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead
+in each object at runtime.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//FieldDeclaration
+ [@Final='true' and @Static='false']
+ /VariableDeclarator/VariableInitializer/Expression
+ /PrimaryExpression[not(PrimarySuffix)]/PrimaryPrefix/Literal
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public final int BAR = 42; // this could be static and save some space
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="GodClass"
+ language="java"
+ since="5.0"
+ message="Possible God Class (WMC={0}, ATFD={2}, TCC={1})"
+ class="net.sourceforge.pmd.lang.java.rule.design.GodClassRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#godclass">
+ <description>
+The God Class rule detects the God Class design flaw using metrics. God classes do too many things,
+are very big and overly complex. They should be split apart to be more object-oriented.
+The rule uses the detection strategy described in "Object-Oriented Metrics in Practice".
+The violations are reported against the entire class.
+
+See also the references:
+
+Michele Lanza and Radu Marinescu. Object-Oriented Metrics in Practice:
+Using Software Metrics to Characterize, Evaluate, and Improve the Design
+of Object-Oriented Systems. Springer, Berlin, 1 edition, October 2006. Page 80.
+ </description>
+ <priority>3</priority>
+ </rule>
+
+ <rule name="ImmutableField"
+ since="2.0"
+ message="Private field ''{0}'' could be made final; it is only initialized in the declaration or constructor."
+ class="net.sourceforge.pmd.lang.java.rule.design.ImmutableFieldRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#immutablefield">
+ <description>
+Identifies private fields whose values never change once they are initialized either in the declaration
+of the field or by a constructor. This helps in converting existing classes to becoming immutable ones.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private int x; // could be final
+ public Foo() {
+ x = 7;
+ }
+ public void foo() {
+ int a = x + 2;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LawOfDemeter"
+ language="java"
+ since="5.0"
+ message="Potential violation of Law of Demeter"
+ class="net.sourceforge.pmd.lang.java.rule.design.LawOfDemeterRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#lawofdemeter">
+ <description>
+The Law of Demeter is a simple rule, that says "only talk to friends". It helps to reduce coupling between classes
+or objects.
+
+See also the references:
+
+* Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.;
+* K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.;
+* &lt;http://www.ccs.neu.edu/home/lieber/LoD.html>
+* &lt;http://en.wikipedia.org/wiki/Law_of_Demeter>
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ /**
+ * This example will result in two violations.
+ */
+ public void example(Bar b) {
+ // this method call is ok, as b is a parameter of "example"
+ C c = b.getC();
+
+ // this method call is a violation, as we are using c, which we got from B.
+ // We should ask b directly instead, e.g. "b.doItOnC();"
+ c.doIt();
+
+ // this is also a violation, just expressed differently as a method chain without temporary variables.
+ b.getC().doIt();
+
+ // a constructor call, not a method call.
+ D d = new D();
+ // this method call is ok, because we have create the new instance of D locally.
+ d.doSomethingElse();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LogicInversion"
+ language="java"
+ since="5.0"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Use opposite operator instead of the logic complement operator."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#logicinversion">
+ <description>
+Use opposite operator instead of negating the whole expression with a logic complement operator.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//UnaryExpressionNotPlusMinus[@Image='!']/PrimaryExpression/PrimaryPrefix/Expression[EqualityExpression or RelationalExpression]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public boolean bar(int a, int b) {
+
+ if (!(a == b)) { // use !=
+ return false;
+ }
+
+ if (!(a < b)) { // use >=
+ return false;
+ }
+
+ return true;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LoosePackageCoupling"
+ since="5.0"
+ message="Use of ''{0}'' outside of package hierarchy ''{1}'' is not recommended; use recommended classes instead"
+ class="net.sourceforge.pmd.lang.java.rule.design.LoosePackageCouplingRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#loosepackagecoupling">
+ <description>
+Avoid using classes from the configured package hierarchy outside of the package hierarchy,
+except when using one of the configured allowed classes.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+package some.package;
+
+import some.other.package.subpackage.subsubpackage.DontUseThisClass;
+
+public class Bar {
+ DontUseThisClass boo = new DontUseThisClass();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ModifiedCyclomaticComplexity"
+ since="5.1.2"
+ message = "The {0} ''{1}'' has a Modified Cyclomatic Complexity of {2}."
+ class="net.sourceforge.pmd.lang.java.rule.design.ModifiedCyclomaticComplexityRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#modifiedcyclomaticcomplexity"
+ deprecated="true">
+ <description>
+Complexity directly affects maintenance costs is determined by the number of decision points in a method
+plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
+Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
+high complexity, and 11+ is very high complexity. Modified complexity treats switch statements as a single
+decision point.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo { // This has a Cyclomatic Complexity = 9
+1 public void example() {
+2 if (a == b) {
+3 if (a1 == b1) {
+ fiddle();
+4 } else if a2 == b2) {
+ fiddle();
+ } else {
+ fiddle();
+ }
+5 } else if (c == d) {
+6 while (c == d) {
+ fiddle();
+ }
+7 } else if (e == f) {
+8 for (int n = 0; n < h; n++) {
+ fiddle();
+ }
+ } else{
+9 switch (z) {
+ case 1:
+ fiddle();
+ break;
+ case 2:
+ fiddle();
+ break;
+ case 3:
+ fiddle();
+ break;
+ default:
+ fiddle();
+ break;
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NcssConstructorCount"
+ message="The constructor with {0} parameters has an NCSS line count of {1}"
+ since="3.9"
+ deprecated="true"
+ class="net.sourceforge.pmd.lang.java.rule.design.NcssConstructorCountRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#ncssconstructorcount">
+ <description>
+This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
+of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm,
+lines of code that are split are counted as one.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends Bar {
+ public Foo() {
+ super();
+
+
+
+
+
+ //this constructor only has 1 NCSS lines
+ super.foo();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NcssCount"
+ message="The {0} ''{1}'' has a NCSS line count of {2}."
+ since="6.0.0"
+ class="net.sourceforge.pmd.lang.java.rule.design.NcssCountRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#ncsscount">
+ <description>
+This rule uses the NCSS (Non-Commenting Source Statements) metric to determine the number of lines
+of code in a class, method or constructor. NCSS ignores comments, blank lines, and only counts actual
+statements. For more details on the calculation, see the documentation of
+the [NCSS metric](/pmd_java_metrics_index.html#non-commenting-source-statements-ncss).
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+import java.util.Collections; // +0
+import java.io.IOException; // +0
+
+class Foo { // +1, total Ncss = 12
+
+ public void bigMethod() // +1
+ throws IOException {
+ int x = 0, y = 2; // +1
+ boolean a = false, b = true; // +1
+
+ if (a || b) { // +1
+ try { // +1
+ do { // +1
+ x += 2; // +1
+ } while (x < 12);
+
+ System.exit(0); // +1
+ } catch (IOException ioe) { // +1
+ throw new PatheticFailException(ioe); // +1
+ }
+ } else {
+ assert false; // +1
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NcssMethodCount"
+ message="The method {0}() has an NCSS line count of {1}"
+ deprecated="true"
+ since="3.9"
+ class="net.sourceforge.pmd.lang.java.rule.design.NcssMethodCountRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#ncssmethodcount">
+ <description>
+This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
+of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
+lines of code that are split are counted as one.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends Bar {
+ public int methd() {
+ super.methd();
+
+
+
+
+
+
+ //this method only has 1 NCSS lines
+ return 1;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NcssTypeCount"
+ message="The type has an NCSS line count of {0}"
+ since="3.9"
+ deprecated="true"
+ class="net.sourceforge.pmd.lang.java.rule.design.NcssTypeCountRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#ncsstypecount">
+ <description>
+This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
+of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
+lines of code that are split are counted as one.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends Bar {
+ public Foo() {
+ //this class only has 6 NCSS lines
+ super();
+
+
+
+
+
+ super.foo();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NPathComplexity"
+ since="3.9"
+ message="The {0} ''{1}'' has an NPath complexity of {2}"
+ class="net.sourceforge.pmd.lang.java.rule.design.NPathComplexityRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#npathcomplexity">
+ <description>
+The NPath complexity of a method is the number of acyclic execution paths through that method.
+While cyclomatic complexity counts the number of decision points in a method, NPath counts the number of
+full paths from the beginning to the end of the block of the method. That metric grows exponentially, as
+it multiplies the complexity of statements in the same block. For more details on the calculation, see the
+documentation of the [NPath metric](/pmd_java_metrics_index.html#npath-complexity-npath).
+
+A threshold of 200 is generally considered the point where measures should be taken to reduce
+complexity and increase readability.
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+public class Foo {
+ public static void bar() { // Ncss = 252: reported!
+ boolean a, b = true;
+ try { // 2 * 2 + 2 = 6
+ if (true) { // 2
+ List buz = new ArrayList();
+ }
+
+ for(int i = 0; i < 19; i++) { // * 2
+ List buz = new ArrayList();
+ }
+ } catch(Exception e) {
+ if (true) { // 2
+ e.printStackTrace();
+ }
+ }
+
+ while (j++ < 20) { // * 2
+ List buz = new ArrayList();
+ }
+
+ switch(j) { // * 7
+ case 1:
+ case 2: break;
+ case 3: j = 5; break;
+ case 4: if (b && a) { bar(); } break;
+ default: break;
+ }
+
+ do { // * 3
+ List buz = new ArrayList();
+ } while (a && j++ < 30);
+ }
+}
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="SignatureDeclareThrowsException"
+ since="1.2"
+ message="A method/constructor should not explicitly throw java.lang.Exception"
+ class="net.sourceforge.pmd.lang.java.rule.design.SignatureDeclareThrowsExceptionRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#signaturedeclarethrowsexception">
+ <description>
+A method/constructor shouldn't explicitly throw the generic java.lang.Exception, since it
+is unclear which exceptions that can be thrown from the methods. It might be
+difficult to document and understand such vague interfaces. Use either a class
+derived from RuntimeException or a checked exception.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void foo() throws Exception {
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifiedTernary"
+ language="java"
+ since="5.4.0"
+ message="Ternary operators that can be simplified with || or &amp;&amp;"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifiedternary">
+ <description>
+<![CDATA[
+Look for ternary operators with the form `condition ? literalBoolean : foo`
+or `condition ? foo : literalBoolean`.
+
+These expressions can be simplified respectively to
+`condition || foo` when the literalBoolean is true
+`!condition && foo` when the literalBoolean is false
+or
+`!condition || foo` when the literalBoolean is true
+`condition && foo` when the literalBoolean is false
+]]>
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ConditionalExpression[not(PrimaryExpression/*/Literal) and (Expression/PrimaryExpression/*/Literal/BooleanLiteral)]
+|
+//ConditionalExpression[not(Expression/PrimaryExpression/*/Literal) and (PrimaryExpression/*/Literal/BooleanLiteral)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public boolean test() {
+ return condition ? true : something(); // can be as simple as return condition || something();
+ }
+
+ public void test2() {
+ final boolean value = condition ? false : something(); // can be as simple as value = !condition && something();
+ }
+
+ public boolean test3() {
+ return condition ? something() : true; // can be as simple as return !condition || something();
+ }
+
+ public void test4() {
+ final boolean otherValue = condition ? something() : false; // can be as simple as condition && something();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifyBooleanAssertion"
+ language="java"
+ since="3.6"
+ message="assertTrue(!expr) can be replaced by assertFalse(expr)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanassertion">
+ <description>
+Avoid negation in an assertTrue or assertFalse test.
+
+For example, rephrase:
+
+ assertTrue(!expr);
+
+as:
+
+ assertFalse(expr);
+
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//StatementExpression
+[
+.//Name[@Image='assertTrue' or @Image='assertFalse']
+and
+PrimaryExpression/PrimarySuffix/Arguments/ArgumentList
+ /Expression/UnaryExpressionNotPlusMinus[@Image='!']
+/PrimaryExpression/PrimaryPrefix
+]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SimpleTest extends TestCase {
+ public void testX() {
+ assertTrue("not empty", !r.isEmpty()); // replace with assertFalse("not empty", r.isEmpty())
+ assertFalse(!r.isEmpty()); // replace with assertTrue(r.isEmpty())
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifyBooleanExpressions"
+ language="java"
+ since="1.05"
+ message="Avoid unnecessary comparisons in boolean expressions"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanexpressions">
+ <description>
+Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//EqualityExpression/PrimaryExpression
+ /PrimaryPrefix/Literal/BooleanLiteral
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Bar {
+ // can be simplified to
+ // bar = isFoo();
+ private boolean bar = (isFoo() == true);
+
+ public isFoo() { return false;}
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifyBooleanReturns"
+ since="0.9"
+ message="Avoid unnecessary if..then..else statements when returning booleans"
+ class="net.sourceforge.pmd.lang.java.rule.design.SimplifyBooleanReturnsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanreturns">
+ <description>
+Avoid unnecessary if-then-else statements when returning a boolean. The result of
+the conditional test can be returned instead.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public boolean isBarEqualTo(int x) {
+ if (bar == x) { // this bit of code...
+ return true;
+ } else {
+ return false;
+ }
+}
+
+public boolean isBarEqualTo(int x) {
+ return bar == x; // can be replaced with this
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifyConditional"
+ language="java"
+ since="3.1"
+ message="No need to check for null before an instanceof"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifyconditional">
+ <description>
+No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Expression
+ [ConditionalOrExpression
+ [EqualityExpression[@Image='==']
+ //NullLiteral
+ and
+ UnaryExpressionNotPlusMinus
+ [@Image='!']//InstanceOfExpression[PrimaryExpression
+ //Name/@Image = ancestor::ConditionalOrExpression/EqualityExpression
+ /PrimaryExpression/PrimaryPrefix/Name/@Image]
+ and
+ (count(UnaryExpressionNotPlusMinus) + 1 = count(*))
+ ]
+or
+ConditionalAndExpression
+ [EqualityExpression[@Image='!=']//NullLiteral
+ and
+InstanceOfExpression
+ [PrimaryExpression[count(PrimarySuffix[@ArrayDereference='true'])=0]
+ //Name[not(contains(@Image,'.'))]/@Image = ancestor::ConditionalAndExpression
+ /EqualityExpression/PrimaryExpression/PrimaryPrefix/Name/@Image]
+ and
+(count(InstanceOfExpression) + 1 = count(*))
+ ]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo {
+ void bar(Object x) {
+ if (x != null && x instanceof Bar) {
+ // just drop the "x != null" check
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SingularField"
+ since="3.1"
+ message="Perhaps ''{0}'' could be replaced by a local variable."
+ class="net.sourceforge.pmd.lang.java.rule.design.SingularFieldRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#singularfield">
+ <description>
+Fields whose scopes are limited to just single methods do not rely on the containing
+object to provide them to other methods. They may be better implemented as local variables
+within those methods.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private int x; // no reason to exist at the Foo instance level
+ public void foo(int y) {
+ x = y + 5;
+ return x;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="StdCyclomaticComplexity"
+ since="5.1.2"
+ message = "The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
+ class="net.sourceforge.pmd.lang.java.rule.design.StdCyclomaticComplexityRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#stdcyclomaticcomplexity"
+ deprecated="true">
+ <description>
+Complexity directly affects maintenance costs is determined by the number of decision points in a method
+plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
+Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
+high complexity, and 11+ is very high complexity.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo { // This has a Cyclomatic Complexity = 12
+1 public void example() {
+2 if (a == b || (c == d && e == f)) { // Only one
+3 if (a1 == b1) {
+ fiddle();
+4 } else if a2 == b2) {
+ fiddle();
+ } else {
+ fiddle();
+ }
+5 } else if (c == d) {
+6 while (c == d) {
+ fiddle();
+ }
+7 } else if (e == f) {
+8 for (int n = 0; n < h; n++) {
+ fiddle();
+ }
+ } else{
+ switch (z) {
+9 case 1:
+ fiddle();
+ break;
+10 case 2:
+ fiddle();
+ break;
+11 case 3:
+ fiddle();
+ break;
+12 default:
+ fiddle();
+ break;
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SwitchDensity"
+ since="1.02"
+ message="A high ratio of statements to labels in a switch statement. Consider refactoring."
+ class="net.sourceforge.pmd.lang.java.rule.design.SwitchDensityRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#switchdensity">
+ <description>
+A high ratio of statements to labels in a switch statement implies that the switch statement
+is overloaded. Consider moving the statements into new methods or creating subclasses based
+on the switch variable.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar(int x) {
+ switch (x) {
+ case 1: {
+ // lots of statements
+ break;
+ } case 2: {
+ // lots of statements
+ break;
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="TooManyFields"
+ since="3.0"
+ message="Too many fields"
+ class="net.sourceforge.pmd.lang.java.rule.design.TooManyFieldsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#toomanyfields">
+ <description>
+Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,
+possibly through grouping related fields in new objects. For example, a class with individual
+city/state/zip fields could park them within a single Address field.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Person { // too many separate fields
+ int birthYear;
+ int birthMonth;
+ int birthDate;
+ float height;
+ float weight;
+}
+
+public class Person { // this is more manageable
+ Date birthDate;
+ BodyMeasurements measurements;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="TooManyMethods"
+ language="java"
+ since="4.2"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="This class has too many methods, consider refactoring it."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#toomanymethods">
+ <description>
+A class with too many methods is probably a good suspect for refactoring, in order to reduce its
+complexity and find a way to have more fine grained objects.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="maxmethods" type="Integer" description="The method count reporting threshold" min="1" max="1000" value="10"/>
+ <property name="xpath">
+ <value>
+ <!-- FIXME: Refine XPath to discard 'get' and 'set' methods with Block no more than 3 lines,
+ something like this:
+ not (
+ (
+ starts-with(@Image,'get')
+ or
+ starts-with(@Image,'set')
+ or
+ starts-with(@Image,'is')
+ )
+ and (
+ (
+ (../Block/attribute::endLine)
+ -
+ (../Block/attribute::beginLine)
+ ) <= 3
+ )
+ )
+ This will avoid discarding 'real' method...
+ -->
+<![CDATA[
+ //ClassOrInterfaceDeclaration/ClassOrInterfaceBody
+ [
+ count(./ClassOrInterfaceBodyDeclaration/MethodDeclaration/MethodDeclarator[
+ not (
+ starts-with(@Image,'get')
+ or
+ starts-with(@Image,'set')
+ or
+ starts-with(@Image,'is')
+ )
+ ]) > $maxmethods
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ </rule>
+
+ <rule name="UselessOverridingMethod"
+ since="3.3"
+ message="Overriding method merely calls super"
+ class="net.sourceforge.pmd.lang.java.rule.design.UselessOverridingMethodRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#uselessoverridingmethod">
+ <description>
+The overriding method merely calls the same method defined in a superclass.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void foo(String bar) {
+ super.foo(bar); // why bother overriding?
+}
+
+public String foo() {
+ return super.foo(); // why bother overriding?
+}
+
+@Id
+public Long getId() {
+ return super.getId(); // OK if 'ignoreAnnotations' is false, which is the default behavior
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseObjectForClearerAPI"
+ language="java"
+ since="4.2.6"
+ message="Rather than using a lot of String arguments, consider using a container object for those values."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#useobjectforclearerapi">
+ <description>
+When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class
+will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information
+as a simple series of Strings, you may think of using an Object to represent all those information. You'll get a simpler
+API (such as doWork(Workload workload), rather than a tedious series of Strings) and more importantly, if you need at some
+point to pass extra data, you'll be able to do so by simply modifying or extending Workload without any modification to
+your API.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[@Public]/MethodDeclarator/FormalParameters[
+ count(FormalParameter/Type/ReferenceType/ClassOrInterfaceType[@Image = 'String']) > 3
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyClass {
+ public void connect(String username,
+ String pssd,
+ String databaseName,
+ String databaseAdress)
+ // Instead of those parameters object
+ // would ensure a cleaner API and permit
+ // to add extra data transparently (no code change):
+ // void connect(UserData data);
+ {
+
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseUtilityClass"
+ since="0.3"
+ message="All methods are static. Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning."
+ class="net.sourceforge.pmd.lang.java.rule.design.UseUtilityClassRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#useutilityclass">
+ <description>
+For classes that only have static methods, consider making them utility classes.
+Note that this doesn't apply to abstract classes, since their subclasses may
+well include non-static methods. Also, if you want this class to be a utility class,
+remember to add a private constructor to prevent instantiation.
+(Note, that this use was known before PMD 5.1.0 as UseSingleton).
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class MaybeAUtility {
+ public static void foo() {}
+ public static void bar() {}
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/category/java/documentation.xml b/dev/src/main/resources/pmd/category/java/documentation.xml
new file mode 100644
index 0000000..d662839
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/documentation.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Documentation"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules that are related to code documentation.
+ </description>
+
+ <rule name="CommentContent"
+ since="5.0"
+ message="Invalid words or phrases found"
+ class="net.sourceforge.pmd.lang.java.rule.documentation.CommentContentRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentcontent">
+ <description>
+A rule for the politically correct... we don't want to offend anyone.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+//OMG, this is horrible, Bob is an idiot !!!
+]]>
+ </example>
+ </rule>
+
+ <rule name="CommentRequired"
+ since="5.1"
+ message="Comment is required"
+ class="net.sourceforge.pmd.lang.java.rule.documentation.CommentRequiredRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentrequired">
+ <description>
+Denotes whether comments are required (or unwanted) for specific language elements.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+/**
+*
+*
+* @author Jon Doe
+*/
+]]>
+ </example>
+ </rule>
+
+ <rule name="CommentSize"
+ since="5.0"
+ message="Comment is too large"
+ class="net.sourceforge.pmd.lang.java.rule.documentation.CommentSizeRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentsize">
+ <description>
+Determines whether the dimensions of non-header comments found are within the specified limits.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+/**
+*
+* too many lines!
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*/
+]]>
+ </example>
+ </rule>
+
+ <rule name="UncommentedEmptyConstructor"
+ language="java"
+ since="3.4"
+ message="Document empty constructor"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptyconstructor">
+ <description>
+Uncommented Empty Constructor finds instances where a constructor does not
+contain statements, but there is no comment. By explicitly commenting empty
+constructors it is easier to distinguish between intentional (commented)
+and unintentional empty constructors.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ConstructorDeclaration[@Private='false']
+ [count(BlockStatement) = 0 and ($ignoreExplicitConstructorInvocation = 'true' or not(ExplicitConstructorInvocation)) and @containsComment = 'false']
+ [not(../Annotation/MarkerAnnotation/Name[pmd-java:typeIs('javax.inject.Inject')])]
+]]>
+ </value>
+ </property>
+ <property name="ignoreExplicitConstructorInvocation" type="Boolean" description="Ignore explicit constructor invocation when deciding whether constructor is empty or not" value="false"/>
+ </properties>
+ <example>
+<![CDATA[
+public Foo() {
+ // This constructor is intentionally empty. Nothing special is needed here.
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UncommentedEmptyMethodBody"
+ language="java"
+ since="3.4"
+ message="Document empty method body"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptymethodbody">
+ <description>
+Uncommented Empty Method Body finds instances where a method body does not contain
+statements, but there is no comment. By explicitly commenting empty method bodies
+it is easier to distinguish between intentional (commented) and unintentional
+empty methods.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration/Block[count(BlockStatement) = 0 and @containsComment = 'false']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void doSomething() {
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset> \ No newline at end of file
diff --git a/dev/src/main/resources/pmd/category/java/errorprone.xml b/dev/src/main/resources/pmd/category/java/errorprone.xml
new file mode 100644
index 0000000..9acaa41
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/errorprone.xml
@@ -0,0 +1,3392 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Error Prone"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
+ </description>
+
+ <rule name="AssignmentInOperand"
+ since="1.03"
+ message="Avoid assignments in operands"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentInOperandRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#assignmentinoperand">
+ <description>
+Avoid assignments in operands; this can make code more complicated and harder to read.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void bar() {
+ int x = 2;
+ if ((x = getX()) == 3) {
+ System.out.println("3!");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AssignmentToNonFinalStatic"
+ since="2.2"
+ message="Possible unsafe assignment to a non-final static field in a constructor."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentToNonFinalStaticRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#assignmenttononfinalstatic">
+ <description>
+Identifies a possible unsafe usage of a static field.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class StaticField {
+ static int x;
+ public FinalFields(int y) {
+ x = y; // unsafe
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidAccessibilityAlteration"
+ language="java"
+ since="4.1"
+ message="You should not modify visibility of class or methods using getDeclaredConstructors(), getDeclaredConstructor(Class[]), setAccessible() or PrivilegedAction."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidaccessibilityalteration">
+ <description>
+Methods such as getDeclaredConstructors(), getDeclaredConstructor(Class[]) and setAccessible(),
+as the interface PrivilegedAction, allow for the runtime alteration of variable, class, or
+method visibility, even if they are private. This violates the principle of encapsulation.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression[
+(
+(PrimarySuffix[
+ ends-with(@Image,'getDeclaredConstructors')
+ or
+ ends-with(@Image,'getDeclaredConstructor')
+ or
+ ends-with(@Image,'setAccessible')
+ ])
+or
+(PrimaryPrefix/Name[
+ ends-with(@Image,'getDeclaredConstructor')
+ or
+ ends-with(@Image,'getDeclaredConstructors')
+ or
+ starts-with(@Image,'AccessibleObject.setAccessible')
+ ])
+)
+and
+(//ImportDeclaration/Name[
+ contains(@Image,'java.security.PrivilegedAction')])
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Method;
+import java.security.PrivilegedAction;
+
+public class Violation {
+ public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException {
+ // Possible call to forbidden getDeclaredConstructors
+ Class[] arrayOfClass = new Class[1];
+ this.getClass().getDeclaredConstructors();
+ this.getClass().getDeclaredConstructor(arrayOfClass);
+ Class clazz = this.getClass();
+ clazz.getDeclaredConstructor(arrayOfClass);
+ clazz.getDeclaredConstructors();
+ // Possible call to forbidden setAccessible
+ clazz.getMethod("", arrayOfClass).setAccessible(false);
+ AccessibleObject.setAccessible(null, false);
+ Method.setAccessible(null, false);
+ Method[] methodsArray = clazz.getMethods();
+ int nbMethod;
+ for ( nbMethod = 0; nbMethod < methodsArray.length; nbMethod++ ) {
+ methodsArray[nbMethod].setAccessible(false);
+ }
+
+ // Possible call to forbidden PrivilegedAction
+ PrivilegedAction priv = (PrivilegedAction) new Object(); priv.run();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidAssertAsIdentifier"
+ language="java"
+ since="3.4"
+ message="Avoid using assert as an identifier; it became a reserved word in JDK 1.4"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidassertasidentifier">
+ <description>
+Use of the term 'assert' will conflict with newer versions of Java since it is a reserved word.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>//VariableDeclaratorId[@Image='assert']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class A {
+ public class Foo {
+ String assert = "foo";
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidBranchingStatementAsLastInLoop"
+ since="5.0"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule"
+ message="Avoid using a branching statement as the last in a loop."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidbranchingstatementaslastinloop">
+ <description>
+Using a branching statement as the last part of a loop may be a bug, and/or is confusing.
+Ensure that the usage is not a bug, or consider using another approach.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+// unusual use of branching statement in a loop
+for (int i = 0; i < 10; i++) {
+ if (i*i <= 25) {
+ continue;
+ }
+ break;
+}
+
+// this makes more sense...
+for (int i = 0; i < 10; i++) {
+ if (i*i > 25) {
+ break;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidCallingFinalize"
+ since="3.0"
+ message="Avoid calling finalize() explicitly"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidCallingFinalizeRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcallingfinalize">
+ <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>
+ <example>
+<![CDATA[
+void foo() {
+ Bar b = new Bar();
+ b.finalize();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidCatchingNPE"
+ language="java"
+ since="1.8"
+ message="Avoid catching NullPointerException; consider removing the cause of the NPE."
+ 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
+original error, causing other, more subtle problems later on.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement/FormalParameter/Type
+ /ReferenceType/ClassOrInterfaceType[@Image='NullPointerException']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ try {
+ // do something
+ } catch (NullPointerException npe) {
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidCatchingThrowable"
+ since="1.2"
+ message="A catch statement should never catch throwable since it includes errors."
+ 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
+OutOfMemoryError that should be exposed and managed separately.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void bar() {
+ try {
+ // do something
+ } catch (Throwable th) { // should not catch Throwable
+ th.printStackTrace();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidDecimalLiteralsInBigDecimalConstructor"
+ language="java"
+ since="3.4"
+ message="Avoid creating BigDecimal with a decimal (float/double) literal. Use a String literal"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoiddecimalliteralsinbigdecimalconstructor">
+ <description>
+One might assume that the result of "new BigDecimal(0.1)" is exactly equal to 0.1, but it is actually
+equal to .1000000000000000055511151231257827021181583404541015625.
+This is because 0.1 cannot be represented exactly as a double (or as a binary fraction of any finite
+length). Thus, the long value that is being passed in to the constructor is not exactly equal to 0.1,
+appearances notwithstanding.
+
+The (String) constructor, on the other hand, is perfectly predictable: 'new BigDecimal("0.1")' is
+exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the
+(String) constructor be used in preference to this one.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+[ClassOrInterfaceType[@Image="BigDecimal"]]
+[Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix
+ [
+ Literal[(not(ends-with(@Image,'"'))) and contains(@Image,".")]
+ or
+ Name[ancestor::Block/BlockStatement/LocalVariableDeclaration
+ [Type[PrimitiveType[@Image='double' or @Image='float']
+ or ReferenceType/ClassOrInterfaceType[@Image='Double' or @Image='Float']]]
+ /VariableDeclarator/VariableDeclaratorId/@Image = @Image
+ ]
+ or
+ Name[ancestor::MethodDeclaration/MethodDeclarator/FormalParameters/FormalParameter
+ [Type[PrimitiveType[@Image='double' or @Image='float']
+ or ReferenceType/ClassOrInterfaceType[@Image='Double' or @Image='Float']]]
+ /VariableDeclaratorId/@Image = @Image
+ ]
+ ]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+BigDecimal bd = new BigDecimal(1.123); // loss of precision, this would trigger the rule
+
+BigDecimal bd = new BigDecimal("1.123"); // preferred approach
+
+BigDecimal bd = new BigDecimal(12); // preferred approach, ok for integer values
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidDuplicateLiterals"
+ since="1.0"
+ message="The String literal {0} appears {1} times in this file; the first occurrence is on line {2}"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidDuplicateLiteralsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidduplicateliterals">
+ <description>
+Code containing duplicate String literals can usually be improved by declaring the String as a constant field.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+private void bar() {
+ buz("Howdy");
+ buz("Howdy");
+ buz("Howdy");
+ buz("Howdy");
+}
+private void buz(String x) {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidEnumAsIdentifier"
+ language="java"
+ since="3.4"
+ message="Avoid using enum as an identifier; it's a reserved word in JDK 1.5"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidenumasidentifier">
+ <description>
+Use of the term 'enum' will conflict with newer versions of Java since it is a reserved word.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>//VariableDeclaratorId[@Image='enum']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class A {
+ public class Foo {
+ String enum = "foo";
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidFieldNameMatchingMethodName"
+ since="3.0"
+ message="Field {0} has the same name as a method"
+ 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
+Smalltalk often prefer this approach as the methods denote accessor methods.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ Object bar;
+ // bar is data or an action or both?
+ void bar() {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidFieldNameMatchingTypeName"
+ since="3.0"
+ message="It is somewhat confusing to have a field name matching the declaring class name"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidFieldNameMatchingTypeNameRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidfieldnamematchingtypename">
+ <description>
+It is somewhat confusing to have a field name matching the declaring class name.
+This probably means that type and/or field names should be chosen more carefully.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo extends Bar {
+ int foo; // There is probably a better name that can be used
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidInstanceofChecksInCatchClause"
+ language="java"
+ since="3.0"
+ message="An instanceof check is being performed on the caught exception. Create a separate catch clause for this exception type."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidinstanceofchecksincatchclause">
+ <description>
+Each caught exception type should be handled in its own catch clause.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement/FormalParameter
+ /following-sibling::Block//InstanceOfExpression/PrimaryExpression/PrimaryPrefix
+ /Name[
+ @Image = ./ancestor::Block/preceding-sibling::FormalParameter
+ /VariableDeclaratorId/@Image
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+try { // Avoid this
+ // do something
+} catch (Exception ee) {
+ if (ee instanceof IOException) {
+ cleanup();
+ }
+}
+
+try { // Prefer this:
+ // do something
+} catch (IOException ee) {
+ cleanup();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidLiteralsInIfCondition"
+ language="java"
+ since="4.2.6"
+ message="Avoid using Literals in Conditional Statements"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidliteralsinifcondition">
+ <description>
+Avoid using hard-coded literals in conditional statements. By declaring them as static variables
+or private members with descriptive names maintainability is enhanced. By default, the literals "-1" and "0" are ignored.
+More exceptions can be defined with the property "ignoreMagicNumbers".
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="ignoreMagicNumbers"
+ description="Comma-separated list of magic numbers, that should be ignored"
+ type="String" value="-1,0"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//IfStatement/Expression/*/PrimaryExpression/PrimaryPrefix/Literal
+[not(NullLiteral)]
+[not(BooleanLiteral)]
+[empty(index-of(tokenize($ignoreMagicNumbers, '\s*,\s*'), @Image))]
+]]>
+ </value>
+ </property>
+ <property name="version" value="2.0"/>
+ </properties>
+ <example>
+<![CDATA[
+private static final int MAX_NUMBER_OF_REQUESTS = 10;
+
+public void checkRequests() {
+
+ if (i == 10) { // magic number, buried in a method
+ doSomething();
+ }
+
+ if (i == MAX_NUMBER_OF_REQUESTS) { // preferred approach
+ doSomething();
+ }
+
+ if (aString.indexOf('.') != -1) {} // magic number -1, by default ignored
+ if (aString.indexOf('.') >= 0) { } // alternative approach
+
+ if (aDouble > 0.0) {} // magic number 0.0
+ if (aDouble >= Double.MIN_VALUE) {} // preferred approach
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidLosingExceptionInformation"
+ since="4.2.6"
+ language="java"
+ message="Avoid statements in a catch block that invoke accessors on the exception without using the information"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation">
+ <description>
+Statements in a catch block that invoke accessors on the exception without using the information
+only add to code size. Either remove the invocation, or use the return result.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement/Block/BlockStatement/Statement/StatementExpression/PrimaryExpression/PrimaryPrefix/Name
+[
+ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getMessage')
+ or
+ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getLocalizedMessage')
+ or
+ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getCause')
+ or
+ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.getStackTrace')
+ or
+ @Image = concat(../../../../../../../FormalParameter/VariableDeclaratorId/@Image, '.toString')
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ try {
+ // do something
+ } catch (SomeException se) {
+ se.getMessage();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidMultipleUnaryOperators"
+ since="4.2"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidMultipleUnaryOperatorsRule"
+ message="Using multiple unary operators may be a bug, and/or is confusing."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidmultipleunaryoperators">
+ <description>
+The use of multiple unary operators may be problematic, and/or confusing.
+Ensure that the intended usage is not a bug, or consider simplifying the expression.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+// These are typo bugs, or at best needlessly complex and confusing:
+int i = - -1;
+int j = + - +1;
+int z = ~~2;
+boolean b = !!true;
+boolean c = !!!true;
+
+// These are better:
+int i = 1;
+int j = -1;
+int z = 2;
+boolean b = true;
+boolean c = false;
+
+// And these just make your brain hurt:
+int i = ~-2;
+int j = -~7;
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidUsingOctalValues"
+ since="3.9"
+ message="Do not start a literal by 0 unless it's an octal value"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidUsingOctalValuesRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidusingoctalvalues">
+ <description>
+Integer literals should not start with zero since this denotes that the rest of literal will be
+interpreted as an octal value.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+int i = 012; // set i with 10 not 12
+int j = 010; // set j with 8 not 10
+k = i * j; // set k with 80 not 120
+]]>
+ </example>
+ </rule>
+
+ <rule name="BadComparison"
+ language="java"
+ since="1.8"
+ message="Avoid equality comparisons with Double.NaN"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#badcomparison">
+ <description>
+Avoid equality comparisons with Double.NaN. Due to the implicit lack of representation
+precision when comparing floating point numbers these are likely to cause logic errors.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//EqualityExpression[@Image='==']
+ /PrimaryExpression/PrimaryPrefix
+ /Name[@Image='Double.NaN' or @Image='Float.NaN']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+boolean x = (y == Double.NaN);
+]]>
+ </example>
+ </rule>
+
+ <rule name="BeanMembersShouldSerialize"
+ since="1.1"
+ message="Found non-transient, non-static member. Please mark as transient or provide accessors."
+ 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
+naming conventions, i.e. for a variable named foo, getFoo() and setFoo() accessor methods should be provided.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+private transient int someFoo; // good, it's transient
+private static int otherFoo; // also OK
+private int moreFoo; // OK, has proper accessors, see below
+private int badFoo; // bad, should be marked transient
+
+private void setMoreFoo(int moreFoo){
+ this.moreFoo = moreFoo;
+}
+
+private int getMoreFoo(){
+ return this.moreFoo;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="BrokenNullCheck"
+ since="3.8"
+ message="Method call on object which may be null"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.BrokenNullCheckRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#brokennullcheck">
+ <description>
+The null check is broken since it will throw a NullPointerException itself.
+It is likely that you used || instead of &amp;&amp; or vice versa.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+public String bar(String string) {
+ // should be &&
+ if (string!=null || !string.equals(""))
+ return string;
+ // should be ||
+ if (string==null && string.equals(""))
+ return string;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CallSuperFirst"
+ since="4.2.5"
+ language="java"
+ message="super should be called at the start of the method"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#callsuperfirst">
+ <description>Super should be called at the start of the method</description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[MethodDeclarator[
+ @Image='onCreate' or
+ @Image='onConfigurationChanged' or
+ @Image='onPostCreate' or
+ @Image='onPostResume' or
+ @Image='onRestart' or
+ @Image='onRestoreInstanceState' or
+ @Image='onResume' or
+ @Image='onStart'
+ ]]
+ /Block[not(
+ (BlockStatement[1]/Statement/StatementExpression/PrimaryExpression[./PrimaryPrefix[@SuperModifier='true']]/PrimarySuffix[@Image= ancestor::MethodDeclaration/MethodDeclarator/@Image]))]
+[ancestor::ClassOrInterfaceDeclaration[ExtendsList/ClassOrInterfaceType[
+ pmd-java:typeIs('android.app.Activity') or
+ pmd-java:typeIs('android.app.Application') or
+ pmd-java:typeIs('android.app.Service')
+]]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class DummyActivity extends Activity {
+ public void onCreate(Bundle bundle) {
+ // missing call to super.onCreate(bundle)
+ foo();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CallSuperLast"
+ since="4.2.5"
+ language="java"
+ message="super should be called at the end of the method"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#callsuperlast">
+ <description>
+Super should be called at the end of the method
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[MethodDeclarator[
+ @Image='finish' or
+ @Image='onDestroy' or
+ @Image='onPause' or
+ @Image='onSaveInstanceState' or
+ @Image='onStop' or
+ @Image='onTerminate'
+ ]]
+ /Block/BlockStatement[last()]
+ [not(Statement/StatementExpression/PrimaryExpression[./PrimaryPrefix[@SuperModifier='true']]/PrimarySuffix[@Image= ancestor::MethodDeclaration/MethodDeclarator/@Image])]
+[ancestor::ClassOrInterfaceDeclaration[ExtendsList/ClassOrInterfaceType[
+ pmd-java:typeIs('android.app.Activity') or
+ pmd-java:typeIs('android.app.Application') or
+ pmd-java:typeIs('android.app.Service')
+]]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class DummyActivity extends Activity {
+ public void onPause() {
+ foo();
+ // missing call to super.onPause()
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CheckSkipResult"
+ language="java"
+ since="5.0"
+ message="Check the value returned by the skip() method of an InputStream to see if the requested number of bytes has been skipped."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.CheckSkipResultRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#checkskipresult">
+ <description>
+The skip() method may skip a smaller number of bytes than requested. Check the returned value to find out if it was the case or not.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+
+ private FileInputStream _s = new FileInputStream("file");
+
+ public void skip(int n) throws IOException {
+ _s.skip(n); // You are not sure that exactly n bytes are skipped
+ }
+
+ public void skipExactly(int n) throws IOException {
+ while (n != 0) {
+ long skipped = _s.skip(n);
+ if (skipped == 0)
+ throw new EOFException();
+ n -= skipped;
+ }
+ }
+]]>
+ </example>
+ </rule>
+
+ <rule name="ClassCastExceptionWithToArray"
+ language="java"
+ since="3.4"
+ message="This usage of the Collection.toArray() method will throw a ClassCastException."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#classcastexceptionwithtoarray">
+ <description>
+When deriving an array of a specific class from your Collection, one should provide an array of
+the same class as the parameter of the toArray() method. Doing otherwise you will will result
+in a ClassCastException.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CastExpression[Type/ReferenceType/ClassOrInterfaceType[@Image !=
+"Object"]]/PrimaryExpression
+[
+ PrimaryPrefix/Name[ends-with(@Image, '.toArray')]
+ and
+ PrimarySuffix/Arguments[count(*) = 0]
+and
+count(PrimarySuffix) = 1
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+Collection c = new ArrayList();
+Integer obj = new Integer(1);
+c.add(obj);
+
+ // this would trigger the rule (and throw a ClassCastException if executed)
+Integer[] a = (Integer [])c.toArray();
+
+ // this is fine and will not trigger the rule
+Integer[] b = (Integer [])c.toArray(new Integer[c.size()]);
+]]>
+ </example>
+ </rule>
+
+ <rule name="CloneMethodMustBePublic"
+ language="java"
+ since="5.4.0"
+ message="clone() method must be public if the class implements Cloneable"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodmustbepublic">
+ <description>
+The java Manual says "By convention, classes that implement this interface should override
+Object.clone (which is protected) with a public method."
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[@Public='false']
+ [MethodDeclarator/@Image = 'clone']
+ [MethodDeclarator/FormalParameters/@ParameterCount = 0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo implements Cloneable {
+ @Override
+ protected Object clone() throws CloneNotSupportedException { // Violation, must be public
+ }
+}
+
+public class Foo implements Cloneable {
+ @Override
+ protected Foo clone() { // Violation, must be public
+ }
+}
+
+public class Foo implements Cloneable {
+ @Override
+ public Object clone() // Ok
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CloneMethodMustImplementCloneable"
+ language="java"
+ since="1.9"
+ message="clone() method should be implemented only if implementing Cloneable interface"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.CloneMethodMustImplementCloneableRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodmustimplementcloneable">
+ <description>
+The method clone() should only be implemented if the class implements the Cloneable interface with the exception of
+a final method that only throws CloneNotSupportedException.
+
+The rule can also detect, if the class implements or extends a Cloneable class.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class MyClass {
+ public Object clone() throws CloneNotSupportedException {
+ return foo;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CloneMethodReturnTypeMustMatchClassName"
+ language="java"
+ minimumLanguageVersion="1.5"
+ since="5.4.0"
+ message="The return type of the clone() method must be the class name when implements Cloneable"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodreturntypemustmatchclassname">
+ <description>
+If a class implements cloneable the return type of the method clone() must be the class name. That way, the caller
+of the clone method doesn't need to cast the returned clone to the correct type.
+
+Note: This is only possible with Java 1.5 or higher.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration
+[
+MethodDeclarator/@Image = 'clone'
+and MethodDeclarator/FormalParameters/@ParameterCount = 0
+and not (ResultType//ClassOrInterfaceType/@Image = ancestor::ClassOrInterfaceDeclaration[1]/@Image)
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo implements Cloneable {
+ @Override
+ protected Object clone() { // Violation, Object must be Foo
+ }
+}
+
+public class Foo implements Cloneable {
+ @Override
+ public Foo clone() { //Ok
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CloneThrowsCloneNotSupportedException"
+ language="java"
+ since="1.9"
+ message="clone() method should throw CloneNotSupportedException"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonethrowsclonenotsupportedexception">
+ <description>
+The method clone() should throw a CloneNotSupportedException.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration
+[
+MethodDeclarator/@Image = 'clone'
+and count(MethodDeclarator/FormalParameters/*) = 0
+and count(NameList/Name[contains
+(@Image,'CloneNotSupportedException')]) = 0
+]
+[
+../../../../ClassOrInterfaceDeclaration[@Final = 'false']
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyClass implements Cloneable{
+ public Object clone() { // will cause an error
+ MyClass clone = (MyClass)super.clone();
+ return clone;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CloseResource"
+ since="1.2.2"
+ message="Ensure that resources like this {0} object are closed after use"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#closeresource">
+ <description>
+Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Bar {
+ public void foo() {
+ Connection c = pool.getConnection();
+ try {
+ // do stuff
+ } catch (SQLException ex) {
+ // handle exception
+ } finally {
+ // oops, should close the connection using 'close'!
+ // c.close();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="CompareObjectsWithEquals"
+ since="3.2"
+ message="Use equals() to compare object references."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.CompareObjectsWithEqualsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#compareobjectswithequals">
+ <description>
+Use equals() to compare object references; avoid comparing them with ==.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+class Foo {
+ boolean bar(String a, String b) {
+ return a == b;
+ }
+}
+
+]]>
+ </example>
+ </rule>
+
+ <rule name="ConstructorCallsOverridableMethod"
+ since="1.04"
+ message="Overridable {0} called during object construction"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.ConstructorCallsOverridableMethodRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#constructorcallsoverridablemethod">
+ <description>
+Calling overridable methods during construction poses a risk of invoking methods on an incompletely
+constructed object and can be difficult to debug.
+It may leave the sub-class unable to construct its superclass or forced to replicate the construction
+process completely within itself, losing the ability to call super(). If the default constructor
+contains a call to an overridable method, the subclass may be completely uninstantiable. Note that
+this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a
+private method bar() that calls a public method buz(), this denotes a problem.
+ </description>
+ <priority>1</priority>
+ <example>
+<![CDATA[
+public class SeniorClass {
+ public SeniorClass(){
+ toString(); //may throw NullPointerException if overridden
+ }
+ public String toString(){
+ return "IAmSeniorClass";
+ }
+}
+public class JuniorClass extends SeniorClass {
+ private String name;
+ public JuniorClass(){
+ super(); //Automatic call leads to NullPointerException
+ name = "JuniorClass";
+ }
+ public String toString(){
+ return name.toUpperCase();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DataflowAnomalyAnalysis"
+ since="3.9"
+ message="Found ''{0}''-anomaly for variable ''{1}'' (lines ''{2}''-''{3}'')."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.DataflowAnomalyAnalysisRule"
+ dfa="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#dataflowanomalyanalysis">
+ <description>The dataflow analysis tracks local definitions, undefinitions and references to variables on different paths on the data flow.
+From those informations there can be found various problems.
+
+1. UR - Anomaly: There is a reference to a variable that was not defined before. This is a bug and leads to an error.
+2. DU - Anomaly: A recently defined variable is undefined. These anomalies may appear in normal source text.
+3. DD - Anomaly: A recently defined variable is redefined. This is ominous but don't have to be a bug.
+ </description>
+ <priority>5</priority>
+ <example>
+<![CDATA[
+public void foo() {
+ int buz = 5;
+ buz = 6; // redefinition of buz -> dd-anomaly
+ foo(buz);
+ buz = 2;
+} // buz is undefined when leaving scope -> du-anomaly
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotCallGarbageCollectionExplicitly"
+ language="java"
+ since="4.2"
+ message="Do not explicitly trigger a garbage collection."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotcallgarbagecollectionexplicitly">
+ <description>
+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.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Name[
+(starts-with(@Image, 'System.') and
+(starts-with(@Image, 'System.gc') or
+starts-with(@Image, 'System.runFinalization'))) or
+(
+starts-with(@Image,'Runtime.getRuntime') and
+../../PrimarySuffix[ends-with(@Image,'gc')]
+)
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class GCCall {
+ public GCCall() {
+ // Explicit gc call !
+ System.gc();
+ }
+
+ public void doSomething() {
+ // Explicit gc call !
+ Runtime.getRuntime().gc();
+ }
+
+ public explicitGCcall() {
+ // Explicit gc call !
+ System.gc();
+ }
+
+ public void doSomething() {
+ // Explicit gc call !
+ Runtime.getRuntime().gc();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotCallSystemExit"
+ language="java"
+ since="4.1"
+ message="System.exit() should not be used in J2EE/JEE apps"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotcallsystemexit">
+ <description>
+Web applications should not call System.exit(), since only the web container or the
+application server should stop the JVM. This rule also checks for the equivalent call Runtime.getRuntime().exit().
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Name[
+ starts-with(@Image,'System.exit')
+ or
+ (starts-with(@Image,'Runtime.getRuntime') and ../../PrimarySuffix[ends-with(@Image,'exit')])
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ System.exit(0); // never call this when running in an application server!
+}
+public void foo() {
+ Runtime.getRuntime().exit(0); // never stop the JVM manually, the container will do this.
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotExtendJavaLangThrowable"
+ language="java"
+ since="6.0.0"
+ message="Exceptions should not extend java.lang.Throwable"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotextendjavalangthrowable">
+ <description>
+Extend Exception or RuntimeException instead of Throwable.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType
+ [@Image="Throwable" or @Image="java.lang.Throwable"]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo extends Throwable { }
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotHardCodeSDCard"
+ since="4.2.6"
+ language="java"
+ message="Do not hardcode /sdcard."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donothardcodesdcard">
+ <description>
+Use Environment.getExternalStorageDirectory() instead of "/sdcard"
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//Literal[starts-with(@Image,'"/sdcard')]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyActivity extends Activity {
+ protected void foo() {
+ String storageLocation = "/sdcard/mypackage"; // hard-coded, poor approach
+
+ storageLocation = Environment.getExternalStorageDirectory() + "/mypackage"; // preferred approach
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotThrowExceptionInFinally"
+ language="java"
+ since="4.2"
+ message="A throw statement in a finally block makes the control flow hard to understand."
+ 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
+or code defects.
+Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block"
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>//FinallyStatement[descendant::ThrowStatement]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ try {
+ // Here do some stuff
+ } catch( Exception e) {
+ // Handling the issue
+ } finally {
+ // is this really a good idea ?
+ throw new Exception();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DontImportSun"
+ since="1.5"
+ message="Avoid importing anything from the 'sun.*' packages"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.DontImportSunRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#dontimportsun">
+ <description>
+Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
+ </description>
+ <priority>4</priority>
+ <example>
+<![CDATA[
+import sun.misc.foo;
+public class Foo {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DontUseFloatTypeForLoopIndices"
+ language="java"
+ since="4.3"
+ message="Don't use floating point for loop indices. If you must use floating point, use double."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#dontusefloattypeforloopindices">
+ <description>
+Don't use floating point for loop indices. If you must use floating point, use double
+unless you're certain that float provides enough precision and you have a compelling
+performance need (space or time).
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ForStatement/ForInit/LocalVariableDeclaration
+/Type/PrimitiveType[@Image="float"]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Count {
+ public static void main(String[] args) {
+ final int START = 2000000000;
+ int count = 0;
+ for (float f = START; f < START + 50; f++)
+ count++;
+ //Prints 0 because (float) START == (float) (START + 50).
+ System.out.println(count);
+ //The termination test misbehaves due to floating point granularity.
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyCatchBlock"
+ language="java"
+ since="0.1"
+ message="Avoid empty catch blocks"
+ 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
+or reported.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement
+ [count(Block/BlockStatement) = 0 and ($allowCommentedBlocks != 'true' or Block/@containsComment = 'false')]
+ [FormalParameter/Type/ReferenceType
+ /ClassOrInterfaceType[@Image != 'InterruptedException' and @Image != 'CloneNotSupportedException']
+ ]
+ [FormalParameter/VariableDeclaratorId[not(matches(@Image, $allowExceptionNameRegex))]]
+]]>
+ </value>
+ </property>
+ <property name="allowCommentedBlocks" type="Boolean" description="Empty blocks containing comments will be skipped" value="false"/>
+ <property name="allowExceptionNameRegex" type="String" description="Empty blocks catching exceptions with names matching this regular expression will be skipped" value="^(ignored|expected)$"/>
+ </properties>
+ <example>
+<![CDATA[
+public void doSomething() {
+ try {
+ FileInputStream fis = new FileInputStream("/tmp/bugger");
+ } catch (IOException ioe) {
+ // not good
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyFinalizer"
+ language="java"
+ since="1.5"
+ message="Avoid empty finalize methods"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyfinalizer">
+ <description>
+Empty finalize methods serve no purpose and should be removed. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
+ /Block[count(*)=0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ protected void finalize() {}
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyFinallyBlock"
+ language="java"
+ since="0.4"
+ message="Avoid empty finally blocks"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyfinallyblock">
+ <description>
+Empty finally blocks serve no purpose and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//FinallyStatement[count(Block/BlockStatement) = 0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ try {
+ int x=2;
+ } finally {
+ // empty!
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyIfStmt"
+ language="java"
+ since="0.1"
+ message="Avoid empty 'if' statements"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyifstmt">
+ <description>
+Empty If Statement finds instances where a condition is checked but nothing is done about it.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//IfStatement/Statement
+ [EmptyStatement or Block[count(*) = 0]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar(int x) {
+ if (x == 0) {
+ // empty!
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyInitializer"
+ language="java"
+ since="5.0"
+ message="Empty initializer was found"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyinitializer">
+ <description>
+Empty initializers serve no purpose and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//Initializer/Block[count(*)=0]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+
+ static {} // Why ?
+
+ {} // Again, why ?
+
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyStatementBlock"
+ language="java"
+ since="5.0"
+ message="Avoid empty block statements."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptystatementblock">
+ <description>
+Empty block statements serve no purpose and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//BlockStatement/Statement/Block[count(*) = 0]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+
+ private int _bar;
+
+ public void setBar(int bar) {
+ { _bar = bar; } // Why not?
+ {} // But remove this.
+ }
+
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyStatementNotInLoop"
+ language="java"
+ since="1.5"
+ message="An empty statement (semicolon) not part of a loop"
+ 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'
+or 'while' loop is probably a bug. It could also be a double semicolon, which has no purpose
+and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//EmptyStatement
+ [not(
+ ../../../ForStatement
+ or ../../../WhileStatement
+ or ../../../BlockStatement/ClassOrInterfaceDeclaration
+ or ../../../../../../ForStatement/Statement[1]
+ /Block[1]/BlockStatement[1]/Statement/EmptyStatement
+ or ../../../../../../WhileStatement/Statement[1]
+ /Block[1]/BlockStatement[1]/Statement/EmptyStatement)
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void doit() {
+ // this is probably not what you meant to do
+ ;
+ // the extra semicolon here this is not necessary
+ System.out.println("look at the extra semicolon");;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptySwitchStatements"
+ language="java"
+ since="1.0"
+ message="Avoid empty switch statements"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyswitchstatements">
+ <description>
+Empty switch statements serve no purpose and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//SwitchStatement[count(*) = 1]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar() {
+ int x = 2;
+ switch (x) {
+ // once there was code here
+ // but it's been commented out or something
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptySynchronizedBlock"
+ language="java"
+ since="1.3"
+ message="Avoid empty synchronized blocks"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptysynchronizedblock">
+ <description>
+Empty synchronized blocks serve no purpose and should be removed.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//SynchronizedStatement/Block[1][count(*) = 0]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ synchronized (this) {
+ // empty!
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyTryBlock"
+ language="java"
+ since="0.4"
+ message="Avoid empty try blocks"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptytryblock">
+ <description>
+Avoid empty try blocks - what's the point?
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//TryStatement[not(ResourceSpecification)]/Block[1][count(*) = 0]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ try {
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="EmptyWhileStmt"
+ language="java"
+ since="0.2"
+ message="Avoid empty 'while' statements"
+ 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.
+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>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//WhileStatement/Statement[./Block[count(*) = 0] or ./EmptyStatement]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+void bar(int a, int b) {
+ while (a == b) {
+ // empty!
+ }
+}
+ ]]>
+ </example>
+ </rule>
+
+ <rule name="EqualsNull"
+ language="java"
+ since="1.9"
+ message="Avoid using equals() to compare against null"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#equalsnull">
+ <description>
+Tests for null should not use the equals() method. The '==' operator should be used instead.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+ [
+ PrimaryPrefix[Name[ends-with(@Image, 'equals')]]
+ [following-sibling::node()/Arguments/ArgumentList[count(Expression)=1]
+ /Expression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
+
+ or
+
+ PrimarySuffix[ends-with(@Image, 'equals')]
+ [following-sibling::node()/Arguments/ArgumentList[count(Expression)=1]
+ /Expression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
+
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+String x = "foo";
+
+if (x.equals(null)) { // bad form
+ doSomething();
+}
+
+if (x == null) { // preferred
+ doSomething();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FinalizeDoesNotCallSuperFinalize"
+ language="java"
+ since="1.5"
+ message="Last statement in finalize method should be a call to super.finalize()"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizedoesnotcallsuperfinalize">
+ <description>
+If the finalize() is implemented, its last action should be to call super.finalize. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<!-- in English: a method declaration of finalize(), with no arguments, containing
+a block whose last statement is NOT a call to super.finalize -->
+<![CDATA[
+//MethodDeclaration[MethodDeclarator[@Image='finalize'][not(FormalParameters/*)]]
+ /Block
+ /BlockStatement[last()]
+ [not(Statement/StatementExpression/PrimaryExpression
+ [./PrimaryPrefix[@SuperModifier='true']]
+ [./PrimarySuffix[@Image='finalize']]
+ )
+ ]
+ [not(Statement/TryStatement/FinallyStatement
+ /Block/BlockStatement/Statement/StatementExpression/PrimaryExpression
+ [./PrimaryPrefix[@SuperModifier='true']]
+ [./PrimarySuffix[@Image='finalize']]
+ )
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+protected void finalize() {
+ something();
+ // neglected to call super.finalize()
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FinalizeOnlyCallsSuperFinalize"
+ language="java"
+ since="1.5"
+ message="Finalize should do something besides just calling super.finalize()"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeonlycallssuperfinalize">
+ <description>
+If the finalize() is implemented, it should do something besides just calling super.finalize(). Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[MethodDeclarator[@Image="finalize"][not(FormalParameters/*)]]
+ /Block[count(BlockStatement)=1]
+ /BlockStatement[
+ Statement/StatementExpression/PrimaryExpression
+ [./PrimaryPrefix[@SuperModifier='true']]
+ [./PrimarySuffix[@Image='finalize']]
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+protected void finalize() {
+ super.finalize();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FinalizeOverloaded"
+ language="java"
+ since="1.5"
+ message="Finalize methods should not be overloaded"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeoverloaded">
+ <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>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration
+ /MethodDeclarator[@Image='finalize'][FormalParameters[count(*)>0]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ // this is confusing and probably a bug
+ protected void finalize(int a) {
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="FinalizeShouldBeProtected"
+ language="java"
+ since="1.1"
+ message="If you override finalize(), make it protected"
+ 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,
+other classes may invoke it at inappropriate times.
+
+Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[@Protected="false"]
+ /MethodDeclarator[@Image="finalize"]
+ [not(FormalParameters/*)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void finalize() {
+ // do something
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="IdempotentOperations"
+ since="2.0"
+ message="Avoid idempotent operations (like assigning a variable to itself)."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.IdempotentOperationsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#idempotentoperations">
+ <description>
+Avoid idempotent operations - they have no effect.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+ int x = 2;
+ x = x;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ImportFromSamePackage"
+ since="1.02"
+ message="No need to import a type that lives in the same package"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.ImportFromSamePackageRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#importfromsamepackage">
+ <description>
+There is no need to import a type that lives in the same package.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+package foo;
+
+import foo.Buz; // no need for this
+import foo.*; // or this
+
+public class Bar{}
+]]>
+ </example>
+ </rule>
+
+ <rule name="InstantiationToGetClass"
+ language="java"
+ since="2.0"
+ message="Avoid instantiating an object just to call getClass() on it; use the .class public member instead"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#instantiationtogetclass">
+ <description>
+Avoid instantiating an object just to call getClass() on it; use the .class public member instead.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimarySuffix
+ [@Image='getClass']
+ [parent::PrimaryExpression
+ [PrimaryPrefix/AllocationExpression]
+ [count(PrimarySuffix) = 2]
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// replace this
+Class c = new String().getClass();
+
+// with this:
+Class c = String.class;
+]]>
+ </example>
+ </rule>
+
+ <rule name="InvalidSlf4jMessageFormat"
+ language="java"
+ since="5.5.0"
+ message="Invalid message format"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.InvalidSlf4jMessageFormatRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#invalidslf4jmessageformat">
+ <description>
+Check for messages in slf4j loggers with non matching number of arguments and placeholders.
+ </description>
+ <priority>5</priority>
+ <example>
+<![CDATA[
+LOGGER.error("forget the arg {}");
+LOGGER.error("too many args {}", "arg1", "arg2");
+LOGGER.error("param {}", "arg1", new IllegalStateException("arg")); //The exception is shown separately, so is correct.
+]]>
+ </example>
+ </rule>
+
+ <rule name="JumbledIncrementer"
+ language="java"
+ since="1.0"
+ message="Avoid modifying an outer loop incrementer in an inner loop for update expression"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#jumbledincrementer">
+ <description>
+Avoid jumbled loop incrementers - its usually a mistake, and is confusing even if intentional.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value><![CDATA[
+//ForStatement
+ [
+ ForUpdate/StatementExpressionList/StatementExpression/PostfixExpression/PrimaryExpression/PrimaryPrefix/Name/@Image
+ =
+ ancestor::ForStatement/ForInit//VariableDeclaratorId/@Image
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+ <![CDATA[
+public class JumbledIncrementerRule1 {
+ public void foo() {
+ for (int i = 0; i < 10; i++) { // only references 'i'
+ for (int k = 0; k < 20; i++) { // references both 'i' and 'k'
+ System.out.println("Hello");
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitSpelling"
+ language="java"
+ since="1.0"
+ message="You may have misspelled a JUnit framework method (setUp or tearDown)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#junitspelling">
+ <description>
+Some JUnit framework methods are easy to misspell.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclarator[(not(@Image = 'setUp')
+ and translate(@Image, 'SETuP', 'setUp') = 'setUp')
+ or (not(@Image = 'tearDown')
+ and translate(@Image, 'TEARdOWN', 'tearDown') = 'tearDown')]
+ [FormalParameters[count(*) = 0]]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+import junit.framework.*;
+
+public class Foo extends TestCase {
+ public void setup() {} // oops, should be setUp
+ public void TearDown() {} // oops, should be tearDown
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="JUnitStaticSuite"
+ language="java"
+ since="1.0"
+ message="You have a suite() method that is not both public and static, so JUnit won't call it to get your TestSuite. Is that what you wanted to do?"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#junitstaticsuite">
+ <description>
+The suite() method in a JUnit test needs to be both public and static.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration[not(@Static='true') or not(@Public='true')]
+[MethodDeclarator/@Image='suite']
+[MethodDeclarator/FormalParameters/@ParameterCount=0]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+import junit.framework.*;
+
+public class Foo extends TestCase {
+ public void suite() {} // oops, should be static
+ private static void suite() {} // oops, should be public
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LoggerIsNotStaticFinal"
+ language="java"
+ 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">
+ <description>
+In most cases, the Logger reference can be declared as static and final.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//VariableDeclarator
+ [parent::FieldDeclaration]
+ [../Type/ReferenceType
+ /ClassOrInterfaceType[@Image='Logger']
+ and
+ (..[@Final='false'] or ..[@Static = 'false'] ) ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo{
+ Logger log = Logger.getLogger(Foo.class.getName()); // not recommended
+
+ static final Logger log = Logger.getLogger(Foo.class.getName()); // preferred approach
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MethodWithSameNameAsEnclosingClass"
+ since="1.5"
+ message="Classes should not have non-constructor methods with the same name as the class"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.MethodWithSameNameAsEnclosingClassRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#methodwithsamenameasenclosingclass">
+ <description>
+Non-constructor methods should not have the same name as the enclosing class.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class MyClass {
+
+ public MyClass() {} // this is OK because it is a constructor
+
+ public void MyClass() {} // this is bad because it is a method
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MisplacedNullCheck"
+ language="java"
+ since="3.5"
+ message="The null check here is misplaced; if the variable is null there will be a NullPointerException"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#misplacednullcheck">
+ <description>
+The null check here is misplaced. If the variable is null a NullPointerException will be thrown.
+Either the check is useless (the variable will never be "null") or it is incorrect.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Expression
+ /*[self::ConditionalOrExpression or self::ConditionalAndExpression]
+ /descendant::PrimaryExpression/PrimaryPrefix
+ /Name[starts-with(@Image,
+ concat(ancestor::PrimaryExpression/following-sibling::EqualityExpression
+ [./PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
+ /PrimaryExpression/PrimaryPrefix
+ /Name[count(../../PrimarySuffix)=0]/@Image,".")
+ )
+ ]
+ [count(ancestor::ConditionalAndExpression/EqualityExpression
+ [@Image='!=']
+ [./PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
+ [starts-with(following-sibling::*/PrimaryExpression/PrimaryPrefix/Name/@Image,
+ concat(./PrimaryExpression/PrimaryPrefix/Name/@Image, '.'))]
+ ) = 0
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ if (a.equals(baz) && a != null) {}
+ }
+}
+]]>
+ </example>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ if (a.equals(baz) || a == null) {}
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MissingBreakInSwitch"
+ language="java"
+ since="3.0"
+ message="A switch statement does not contain a break"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingbreakinswitch">
+ <description>
+Switch statements without break or return statements for each case option
+may indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//SwitchStatement
+[(count(.//BreakStatement)
+ + count(BlockStatement//Statement/ReturnStatement)
+ + count(BlockStatement//Statement/ContinueStatement)
+ + count(BlockStatement//Statement/ThrowStatement)
+ + count(BlockStatement//Statement/IfStatement[@Else='true' and Statement[2][ReturnStatement|ContinueStatement|ThrowStatement]]/Statement[1][ReturnStatement|ContinueStatement|ThrowStatement])
+ + count(SwitchLabel[name(following-sibling::node()) = 'SwitchLabel'])
+ + count(SwitchLabel[count(following-sibling::node()) = 0])
+ < count (SwitchLabel))]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public void bar(int status) {
+ switch(status) {
+ case CANCELLED:
+ doCancelled();
+ // break; hm, should this be commented out?
+ case NEW:
+ doNew();
+ // is this really a fall-through?
+ case REMOVED:
+ doRemoved();
+ // what happens if you add another case after this one?
+ case OTHER: // empty case - this is interpreted as an intentional fall-through
+ case ERROR:
+ doErrorHandling();
+ break;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MissingSerialVersionUID"
+ language="java"
+ since="3.0"
+ message="Classes implementing Serializable should set a serialVersionUID"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingserialversionuid">
+ <description>
+Serializable classes should provide a serialVersionUID field.
+The serialVersionUID field is also needed for abstract base classes. Each individual class in the inheritance
+chain needs an own serialVersionUID field. See also [Should an abstract class have a serialVersionUID](https://stackoverflow.com/questions/893259/should-an-abstract-class-have-a-serialversionuid).
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration
+ [@Interface = 'false']
+ [count(ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration
+ /FieldDeclaration/VariableDeclarator/VariableDeclaratorId[@Image='serialVersionUID']) = 0]
+ [(ImplementsList | ExtendsList)/ClassOrInterfaceType[pmd-java:typeIs('java.io.Serializable')]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo implements java.io.Serializable {
+ String name;
+ // Define serialization id to avoid serialization related bugs
+ // i.e., public static final long serialVersionUID = 4328743;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="MissingStaticMethodInNonInstantiatableClass"
+ language="java"
+ since="3.0"
+ message="Class cannot be instantiated and does not provide any static methods or fields"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingstaticmethodinnoninstantiatableclass">
+ <description>
+A class that has private constructors and does not have any static methods or fields cannot be used.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[@Nested='false']
+[
+ (
+ ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration
+ and
+ count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) = count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private='true'])
+ )
+ and
+ not(.//MethodDeclaration[@Static='true'])
+ and
+ not(.//FieldDeclaration[@Private='false'][@Static='true'])
+ and
+ not(.//ClassOrInterfaceDeclaration[@Nested='true']
+ [@Public='true']
+ [@Static='true']
+ [not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) or ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Public='true']]
+ [./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration
+ [@Public='true']
+ [./ResultType/Type/ReferenceType/ClassOrInterfaceType
+ [@Image = //ClassOrInterfaceDeclaration[@Nested='false']/@Image]
+ ]
+ ]
+ )
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// This class is unusable, since it cannot be
+// instantiated (private constructor),
+// and no static method can be called.
+
+public class Foo {
+ private Foo() {}
+ void foo() {}
+}
+
+]]>
+ </example>
+ </rule>
+
+ <rule name="MoreThanOneLogger"
+ since="2.0"
+ message="Class contains more than one logger."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.MoreThanOneLoggerRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#morethanonelogger">
+ <description>
+Normally only one logger is used in each class.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ Logger log = Logger.getLogger(Foo.class.getName());
+ // It is very rare to see two loggers on a class, normally
+ // log information is multiplexed by levels
+ Logger log2= Logger.getLogger(Foo.class.getName());
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NonCaseLabelInSwitchStatement"
+ language="java"
+ since="1.5"
+ message="A non-case label was present in a switch statement"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#noncaselabelinswitchstatement">
+ <description>
+A non-case label (e.g. a named break/continue label) was present in a switch statement.
+This legal, but confusing. It is easy to mix up the case labels and the non-case labels.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//SwitchStatement//BlockStatement/Statement/LabeledStatement</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar(int a) {
+ switch (a) {
+ case 1:
+ // do something
+ break;
+ mylabel: // this is legal, but confusing!
+ break;
+ default:
+ break;
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NonStaticInitializer"
+ language="java"
+ since="1.5"
+ message="Non-static initializers are confusing"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#nonstaticinitializer">
+ <description>
+A non-static initializer block will be called any time a constructor is invoked (just prior to
+invoking the constructor). While this is a valid language construct, it is rarely used and is
+confusing.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Initializer[@Static='false']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class MyClass {
+ // this block gets run before any call to a constructor
+ {
+ System.out.println("I am about to construct myself");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NullAssignment"
+ since="1.02"
+ message="Assigning an Object to null is a code smell. Consider refactoring."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.NullAssignmentRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#nullassignment">
+ <description>
+Assigning a "null" to a variable (outside of its declaration) is usually bad form. Sometimes, this type
+of assignment is an indication that the programmer doesn't completely understand what is going on in the code.
+
+NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection.
+ </description>
+ <priority>3</priority>
+ <example>
+ <![CDATA[
+public void bar() {
+ Object x = null; // this is OK
+ x = new Object();
+ // big, complex piece of code here
+ x = null; // this is not required
+ // big, complex piece of code here
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="OverrideBothEqualsAndHashcode"
+ language="java"
+ since="0.4"
+ message="Ensure you override both equals() and hashCode()"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.OverrideBothEqualsAndHashcodeRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#overridebothequalsandhashcode">
+ <description>
+Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Bar { // poor, missing a hashcode() method
+ public boolean equals(Object o) {
+ // do some comparison
+ }
+}
+
+public class Baz { // poor, missing an equals() method
+ public int hashCode() {
+ // return some hash value
+ }
+}
+
+public class Foo { // perfect, both methods provided
+ public boolean equals(Object other) {
+ // do some comparison
+ }
+ public int hashCode() {
+ // return some hash value
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ProperCloneImplementation"
+ language="java"
+ since="1.4"
+ message="Object clone() should be implemented with super.clone()"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#propercloneimplementation">
+ <description>
+Object clone() should be implemented with super.clone().
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclarator
+[@Image = 'clone']
+[count(FormalParameters/*) = 0]
+[count(../Block//*[
+ (self::AllocationExpression) and
+ (./ClassOrInterfaceType/@Image = ancestor::
+ClassOrInterfaceDeclaration[1]/@Image)
+ ])> 0
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo{
+ public Object clone(){
+ return new Foo(); // This is bad
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ProperLogger"
+ language="java"
+ 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">
+ <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,
+with the restriction that the logger needs to be passed into the constructor.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <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]]
+ )]
+]]>
+ </value>
+ </property>
+ <property name="staticLoggerName" type="String" description="Name of the static Logger variable" value="LOG"/>
+ </properties>
+ <example>
+ <![CDATA[
+public class Foo {
+
+ private static final Log LOG = LogFactory.getLog(Foo.class); // proper way
+
+ protected Log LOG = LogFactory.getLog(Testclass.class); // wrong approach
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ReturnEmptyArrayRatherThanNull"
+ language="java"
+ since="4.2"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Return an empty array rather than 'null'."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#returnemptyarrayratherthannull">
+ <description>
+For any method that returns an array, it is a better to return an empty array rather than a
+null reference. This removes the need for null checking all results and avoids inadvertent
+NullPointerExceptions.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclaration
+[
+(./ResultType/Type[@Array='true'])
+and
+(./Block/BlockStatement/Statement/ReturnStatement/Expression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral)
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Example {
+ // Not a good idea...
+ public int[] badBehavior() {
+ // ...
+ return null;
+ }
+
+ // Good behavior
+ public String[] bonnePratique() {
+ //...
+ return new String[0];
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ReturnFromFinallyBlock"
+ language="java"
+ since="1.05"
+ message="Avoid returning from a finally block"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#returnfromfinallyblock">
+ <description>
+Avoid returning from a finally block, this can discard exceptions.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//FinallyStatement//ReturnStatement</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Bar {
+ public String foo() {
+ try {
+ throw new Exception( "My Exception" );
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ return "A. O. K."; // return not recommended here
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimpleDateFormatNeedsLocale"
+ language="java"
+ since="2.0"
+ message="When instantiating a SimpleDateFormat object, specify a Locale"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#simpledateformatneedslocale">
+ <description>
+Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate
+formatting is used.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+ [ClassOrInterfaceType[@Image='SimpleDateFormat']]
+ [Arguments[@ArgumentCount=1]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ // Should specify Locale.US (or whatever)
+ private SimpleDateFormat sdf = new SimpleDateFormat("pattern");
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SingleMethodSingleton"
+ since="5.4"
+ message="Class contains multiple getInstance methods. Please review."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.SingleMethodSingletonRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#singlemethodsingleton">
+ <description>
+Some classes contain overloaded getInstance. The problem with overloaded getInstance methods
+is that the instance created using the overloaded method is not cached and so,
+for each call and new objects will be created for every invocation.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+public class Singleton {
+
+ private static Singleton singleton = new Singleton( );
+
+ private Singleton(){ }
+
+ public static Singleton getInstance( ) {
+ return singleton;
+ }
+
+ public static Singleton getInstance(Object obj){
+ Singleton singleton = (Singleton) obj;
+ return singleton; //violation
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SingletonClassReturningNewInstance"
+ since="5.4"
+ message="getInstance method always creates a new object and hence does not comply to Singleton Design Pattern behaviour. Please review"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.SingletonClassReturningNewInstanceRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#singletonclassreturningnewinstance">
+ <description>
+Some classes contain overloaded getInstance. The problem with overloaded getInstance methods
+is that the instance created using the overloaded method is not cached and so,
+for each call and new objects will be created for every invocation.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+class Singleton {
+ private static Singleton instance = null;
+ public static Singleton getInstance() {
+ synchronized(Singleton.class) {
+ return new Singleton();
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="StaticEJBFieldShouldBeFinal"
+ language="java"
+ since="4.1"
+ message="EJB's shouldn't have non-final static fields"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#staticejbfieldshouldbefinal">
+ <description>
+According to the J2EE specification, an EJB should not have any static fields
+with write access. However, static read-only fields are allowed. This ensures proper
+behavior especially when instances are distributed by the container on several JREs.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//ClassOrInterfaceDeclaration[
+ (
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'SessionBean')])
+ or
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBHome')])
+ or
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalObject')])
+ or
+ (./ImplementsList/ClassOrInterfaceType[ends-with(@Image,'EJBLocalHome')])
+ or
+ (./ExtendsList/ClassOrInterfaceType[ends-with(@Image,'EJBObject')])
+ )
+ and
+ (./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration[
+ (./FieldDeclaration[@Static = 'true'])
+ and
+ (./FieldDeclaration[@Final = 'false'])
+ ])
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SomeEJB extends EJBObject implements EJBLocalHome {
+
+ private static int CountA; // poor, field can be edited
+
+ private static final int CountB; // preferred, read-only access
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="StringBufferInstantiationWithChar"
+ language="java"
+ since="3.9"
+ message="Do not instantiate a StringBuffer or StringBuilder with a char"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#stringbufferinstantiationwithchar">
+ <description>
+Individual character values provided as initialization arguments will be converted into integers.
+This can lead to internal buffer sizes that are larger than expected. Some examples:
+
+```
+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 StringBuilder() // 16
+new StringBuilder(6) // 6
+new StringBuilder("hello world") // 11 + 16 = 27
+new StringBuilder('C') // chr(C) = 67
+new StringBuilder("A") // 1 + 16 = 17
+```
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression/ClassOrInterfaceType
+[@Image='StringBuffer' or @Image='StringBuilder']
+/../Arguments/ArgumentList/Expression/PrimaryExpression
+/PrimaryPrefix/
+Literal
+ [starts-with(@Image, "'")]
+ [ends-with(@Image, "'")]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// misleading instantiation, these buffers
+// are actually sized to 99 characters long
+StringBuffer sb1 = new StringBuffer('c');
+StringBuilder sb2 = new StringBuilder('c');
+
+// in these forms, just single characters are allocated
+StringBuffer sb3 = new StringBuffer("c");
+StringBuilder sb4 = new StringBuilder("c");
+]]>
+ </example>
+ </rule>
+
+ <rule name="SuspiciousEqualsMethodName"
+ language="java"
+ since="2.0"
+ message="The method name and parameter number are suspiciously close to equals(Object)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspiciousequalsmethodname">
+ <description>
+The method name and parameter number are suspiciously close to equals(Object), which can denote an
+intention to override the equals(Object) method.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//MethodDeclarator[@Image = 'equals']
+[
+ (count(FormalParameters/*) = 1
+ and not (FormalParameters/FormalParameter/Type/ReferenceType/ClassOrInterfaceType
+ [@Image = 'Object' or @Image = 'java.lang.Object'])
+ or not (../ResultType/Type/PrimitiveType[@Image = 'boolean'])
+ ) or (
+ count(FormalParameters/*) = 2
+ and ../ResultType/Type/PrimitiveType[@Image = 'boolean']
+ and FormalParameters//ClassOrInterfaceType[@Image = 'Object' or @Image = 'java.lang.Object']
+ and not(../../Annotation/MarkerAnnotation/Name[@Image='Override'])
+ )
+]
+| //MethodDeclarator[@Image = 'equal']
+[
+ count(FormalParameters/*) = 1
+ and FormalParameters/FormalParameter/Type/ReferenceType/ClassOrInterfaceType
+ [@Image = 'Object' or @Image = 'java.lang.Object']
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public int equals(Object o) {
+ // oops, this probably was supposed to be boolean equals
+ }
+ public boolean equals(String s) {
+ // oops, this probably was supposed to be equals(Object)
+ }
+ public boolean equals(Object o1, Object o2) {
+ // oops, this probably was supposed to be equals(Object)
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SuspiciousHashcodeMethodName"
+ since="1.5"
+ message="The method name and return type are suspiciously close to hashCode()"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.SuspiciousHashcodeMethodNameRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspicioushashcodemethodname">
+ <description>
+The method name and return type are suspiciously close to hashCode(), which may denote an intention
+to override the hashCode() method.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ public int hashcode() { // oops, this probably was supposed to be 'hashCode'
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SuspiciousOctalEscape"
+ since="1.5"
+ message="Suspicious decimal characters following octal escape in string literal"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.SuspiciousOctalEscapeRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspiciousoctalescape">
+ <description>
+A suspicious octal escape sequence was found inside a String literal.
+The Java language specification (section 3.10.6) says an octal
+escape sequence inside a literal String shall consist of a backslash
+followed by:
+
+ OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit
+
+Any octal escape sequence followed by non-octal digits can be confusing,
+e.g. "\038" is interpreted as the octal escape sequence "\03" followed by
+the literal character "8".
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void foo() {
+ // interpreted as octal 12, followed by character '8'
+ System.out.println("suspicious: \128");
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="TestClassWithoutTestCases"
+ since="3.0"
+ message="This class name ends with 'Test' but contains no test cases"
+ 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,
+since most people will assume it is a test case. Test classes have test methods named testXXX.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+//Consider changing the name of the class if it is not a test
+//Consider adding test methods if it is a test
+public class CarTest {
+ public static void main(String[] args) {
+ // do something
+ }
+ // code
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnconditionalIfStatement"
+ language="java"
+ since="1.5"
+ message="Do not use 'if' statements that are always true or always false"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unconditionalifstatement">
+ <description>
+Do not use "if" statements whose conditionals are always true or always false.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+ <![CDATA[
+//IfStatement/Expression
+ [count(PrimaryExpression)=1]
+ /PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ public void close() {
+ if (true) { // fixed conditional, not recommended
+ // ...
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryBooleanAssertion"
+ language="java"
+ since="3.0"
+ message="assertTrue(true) or similar statements are unnecessary"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessarybooleanassertion">
+ <description>
+A JUnit test assertion with a boolean literal is unnecessary since it always will evaluate to the same thing.
+Consider using flow control (in case of assertTrue(false) or similar) or simply removing
+statements like assertTrue(true) and assertFalse(false). If you just want a test to halt after finding
+an error, use the fail() method and provide an indication message of why it did.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//StatementExpression
+[
+PrimaryExpression/PrimaryPrefix/Name[@Image='assertTrue' or @Image='assertFalse']
+and
+PrimaryExpression/PrimarySuffix/Arguments/ArgumentList/Expression
+[PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral
+or
+UnaryExpressionNotPlusMinus[@Image='!']
+/PrimaryExpression/PrimaryPrefix[Literal/BooleanLiteral or Name[count(../../*)=1]]]
+]
+[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
+ or //MarkerAnnotation/Name[
+ pmd-java:typeIs('org.junit.Test')
+ or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+ or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+ or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+ ]
+]]]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SimpleTest extends TestCase {
+ public void testX() {
+ assertTrue(true); // serves no real purpose
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryCaseChange"
+ since="3.3"
+ message="Using equalsIgnoreCase() is cleaner than using toUpperCase/toLowerCase().equals()."
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.UnnecessaryCaseChangeRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessarycasechange">
+ <description>
+Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals()
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+boolean answer1 = buz.toUpperCase().equals("baz"); // should be buz.equalsIgnoreCase("baz")
+
+boolean answer2 = buz.toUpperCase().equalsIgnoreCase("baz"); // another unnecessary toUpperCase()
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryConversionTemporary"
+ since="0.1"
+ message="Avoid unnecessary temporaries when converting primitives to Strings"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.UnnecessaryConversionTemporaryRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessaryconversiontemporary">
+ <description>
+Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methods
+on the wrapper classes instead.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public String convert(int x) {
+ String foo = new Integer(x).toString(); // this wastes an object
+
+ return Integer.toString(x); // preferred approach
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnusedNullCheckInEquals"
+ language="java"
+ since="3.5"
+ message="Invoke equals() on the object you''ve already ensured is not null"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unusednullcheckinequals">
+ <description>
+After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+(//PrimaryPrefix[ends-with(Name/@Image, '.equals') and Name/@Image != 'Arrays.equals'] | //PrimarySuffix[@Image='equals' and not(../PrimaryPrefix/Literal)])
+ /following-sibling::PrimarySuffix/Arguments/ArgumentList/Expression
+ /PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix
+ /Name[@Image = ./../../../../../../../../../../Expression/ConditionalAndExpression
+ /EqualityExpression[@Image="!=" and count(./preceding-sibling::*)=0 and
+ ./PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
+ /PrimaryExpression/PrimaryPrefix/Name/@Image]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Test {
+
+ public String method1() { return "ok";}
+ public String method2() { return null;}
+
+ public void method(String a) {
+ String b;
+ // I don't know it method1() can be "null"
+ // but I know "a" is not null..
+ // I'd better write a.equals(method1())
+
+ if (a!=null && method1().equals(a)) { // will trigger the rule
+ //whatever
+ }
+
+ if (method1().equals(a) && a != null) { // won't trigger the rule
+ //whatever
+ }
+
+ if (a!=null && method1().equals(b)) { // won't trigger the rule
+ //whatever
+ }
+
+ if (a!=null && "LITERAL".equals(a)) { // won't trigger the rule
+ //whatever
+ }
+
+ if (a!=null && !a.equals("go")) { // won't trigger the rule
+ a=method2();
+ if (method1().equals(a)) {
+ //whatever
+ }
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseCorrectExceptionLogging"
+ language="java"
+ since="3.2"
+ message="Use the correct logging statement for logging exceptions"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#usecorrectexceptionlogging">
+ <description>
+To make sure the full stacktrace is printed out, use the logging statement with two arguments: a String and a Throwable.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CatchStatement/Block/BlockStatement/Statement/StatementExpression
+/PrimaryExpression[PrimaryPrefix/Name[starts-with(@Image,
+concat(ancestor::ClassOrInterfaceDeclaration/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/FieldDeclaration
+[Type//ClassOrInterfaceType[@Image='Log']]
+/VariableDeclarator/VariableDeclaratorId/@Image, '.'))]]
+[PrimarySuffix/Arguments[@ArgumentCount='1']]
+[PrimarySuffix/Arguments//Name/@Image = ancestor::CatchStatement/FormalParameter/VariableDeclaratorId/@Image]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Main {
+ private static final Log _LOG = LogFactory.getLog( Main.class );
+ void bar() {
+ try {
+ } catch( Exception e ) {
+ _LOG.error( e ); //Wrong!
+ } catch( OtherException oe ) {
+ _LOG.error( oe.getMessage(), oe ); //Correct
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseEqualsToCompareStrings"
+ language="java"
+ since="4.1"
+ message="Use equals() to compare strings instead of ''=='' or ''!=''"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#useequalstocomparestrings">
+ <description>
+Using '==' or '!=' to compare strings only works if intern version is used on both sides.
+Use the equals() method instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//EqualityExpression/PrimaryExpression
+[(PrimaryPrefix/Literal
+ [starts-with(@Image, '"')]
+ [ends-with(@Image, '"')]
+and count(PrimarySuffix) = 0)]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public boolean test(String s) {
+ if (s == "one") return true; // unreliable
+ if ("two".equals(s)) return true; // better
+ return false;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UselessOperationOnImmutable"
+ since="3.5"
+ message="An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself"
+ class="net.sourceforge.pmd.lang.java.rule.errorprone.UselessOperationOnImmutableRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselessoperationonimmutable">
+ <description>
+An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself
+since the result of the operation is a new object. Therefore, ignoring the operation result is an error.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+import java.math.*;
+
+class Test {
+ void method1() {
+ BigDecimal bd=new BigDecimal(10);
+ bd.add(new BigDecimal(5)); // this will trigger the rule
+ }
+ void method2() {
+ BigDecimal bd=new BigDecimal(10);
+ bd = bd.add(new BigDecimal(5)); // this won't trigger the rule
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseLocaleWithCaseConversions"
+ language="java"
+ since="2.0"
+ message="When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselocalewithcaseconversions">
+ <description>
+When doing String.toLowerCase()/toUpperCase() conversions, use Locales to avoids problems with languages that
+have unusual conventions, i.e. Turkish.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+[
+PrimaryPrefix
+[Name[ends-with(@Image, 'toLowerCase') or ends-with(@Image, 'toUpperCase')]]
+[following-sibling::PrimarySuffix[position() = 1]/Arguments[@ArgumentCount=0]]
+
+or
+
+PrimarySuffix
+[ends-with(@Image, 'toLowerCase') or ends-with(@Image, 'toUpperCase')]
+[following-sibling::PrimarySuffix[position() = 1]/Arguments[@ArgumentCount=0]]
+]
+[not(PrimaryPrefix/Name[ends-with(@Image, 'toHexString')])]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+class Foo {
+ // BAD
+ if (x.toLowerCase().equals("list")) { }
+
+ /*
+ * This will not match "LIST" when in Turkish locale
+ * The above could be
+ * if (x.toLowerCase(Locale.US).equals("list")) { }
+ * or simply
+ * if (x.equalsIgnoreCase("list")) { }
+ */
+ // GOOD
+ String z = a.toLowerCase(Locale.EN);
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseProperClassLoader"
+ language="java"
+ since="3.7"
+ message="In J2EE, getClassLoader() might not work as expected. Use Thread.currentThread().getContextClassLoader() instead."
+ 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
+Thread.currentThread().getContextClassLoader() instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//PrimarySuffix[@Image='getClassLoader']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ ClassLoader cl = Bar.class.getClassLoader();
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/category/java/multithreading.xml b/dev/src/main/resources/pmd/category/java/multithreading.xml
new file mode 100644
index 0000000..c221ceb
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/multithreading.xml
@@ -0,0 +1,373 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Multithreading"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules that flag issues when dealing with multiple threads of execution.
+ </description>
+
+ <rule name="AvoidSynchronizedAtMethodLevel"
+ language="java"
+ since="3.0"
+ message="Use block level rather than method level synchronization"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedatmethodlevel">
+ <description>
+Method-level synchronization can cause problems when new code is added to the method.
+Block-level synchronization helps to ensure that only the code that needs synchronization
+gets it.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//MethodDeclaration[@Synchronized='true']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ // Try to avoid this:
+ synchronized void foo() {
+ }
+ // Prefer this:
+ void bar() {
+ synchronized(this) {
+ }
+ }
+
+ // Try to avoid this for static methods:
+ static synchronized void fooStatic() {
+ }
+
+ // Prefer this:
+ static void barStatic() {
+ synchronized(Foo.class) {
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidThreadGroup"
+ language="java"
+ since="3.6"
+ message="Avoid using java.lang.ThreadGroup; it is not thread safe"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidthreadgroup">
+ <description>
+Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment
+it contains methods that are not thread-safe.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.ThreadGroup')]|
+//PrimarySuffix[contains(@Image, 'getThreadGroup')]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Bar {
+ void buz() {
+ ThreadGroup tg = new ThreadGroup("My threadgroup");
+ tg = new ThreadGroup(tg, "my thread group");
+ tg = Thread.currentThread().getThreadGroup();
+ tg = System.getSecurityManager().getThreadGroup();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidUsingVolatile"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="Use of modifier volatile is not recommended."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidusingvolatile">
+ <description>
+Use of the keyword 'volatile' is generally used to fine tune a Java application, and therefore, requires
+a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore,
+the volatile keyword should not be used for maintenance purpose and portability.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>//FieldDeclaration[contains(@Volatile,'true')]</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class ThrDeux {
+ private volatile String var1; // not suggested
+ private String var2; // preferred
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoNotUseThreads"
+ language="java"
+ since="4.1"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="To be compliant to J2EE, a webapp should not use any thread."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#donotusethreads">
+ <description>
+The J2EE specification explicitly forbids the use of threads.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>//ClassOrInterfaceType[@Image = 'Thread' or @Image = 'Runnable']</value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// This is not allowed
+public class UsingThread extends Thread {
+
+}
+
+// Neither this,
+public class OtherThread implements Runnable {
+ // Nor this ...
+ public void methode() {
+ Runnable thread = new Thread(); thread.run();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="DontCallThreadRun"
+ language="java"
+ since="4.3"
+ message="Don't call Thread.run() explicitly, use Thread.start()"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#dontcallthreadrun">
+ <description>
+Explicitly calling Thread.run() method will execute in the caller's thread of control. Instead, call Thread.start() for the intended behavior.
+ </description>
+ <priority>4</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//StatementExpression/PrimaryExpression
+[
+ PrimaryPrefix
+ [
+ ./Name[ends-with(@Image, '.run') or @Image = 'run']
+ and substring-before(Name/@Image, '.') =//VariableDeclarator/VariableDeclaratorId/@Image
+ [../../../Type/ReferenceType/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]]
+ or (./AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]
+ and ../PrimarySuffix[@Image = 'run'])
+ ]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+Thread t = new Thread();
+t.run(); // use t.start() instead
+new Thread().run(); // same violation
+]]>
+ </example>
+ </rule>
+
+ <rule name="DoubleCheckedLocking"
+ language="java"
+ since="1.04"
+ message="Double checked locking is not thread safe in Java."
+ class="net.sourceforge.pmd.lang.java.rule.multithreading.DoubleCheckedLockingRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#doublecheckedlocking">
+ <description>
+Partially created objects can be returned by the Double Checked Locking pattern when used in Java.
+An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the
+reference points to.
+
+Note: With Java 5, you can make Double checked locking work, if you declare the variable to be `volatile`.
+
+For more details refer to: &lt;http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html>
+or &lt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
+ </description>
+ <priority>1</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ /*volatile */ Object baz = null; // fix for Java5 and later: volatile
+ Object bar() {
+ if (baz == null) { // baz may be non-null yet not fully created
+ synchronized(this) {
+ if (baz == null) {
+ baz = new Object();
+ }
+ }
+ }
+ return baz;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="NonThreadSafeSingleton"
+ since="3.4"
+ message="Singleton is not thread safe"
+ class="net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#nonthreadsafesingleton">
+ <description>
+Non-thread safe singletons can result in bad state changes. Eliminate
+static singletons if possible by instantiating the object directly. Static
+singletons are usually not needed as only a single instance exists anyway.
+Other possible fixes are to synchronize the entire method or to use an
+[initialize-on-demand holder class](https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom).
+
+Refrain from using the double-checked locking pattern. The Java Memory Model doesn't
+guarantee it to work unless the variable is declared as `volatile`, adding an uneeded
+performance penalty. [Reference](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html)
+
+See Effective Java, item 48.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+private static Foo foo = null;
+
+//multiple simultaneous callers may see partially initialized objects
+public static Foo getFoo() {
+ if (foo==null) {
+ foo = new Foo();
+ }
+ return foo;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnsynchronizedStaticDateFormatter"
+ since="3.6"
+ message="Static DateFormatter objects should be accessed in a synchronized manner"
+ class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticDateFormatterRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticdateformatter">
+ <description>
+SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances
+for each thread. If multiple threads must access a static formatter, the formatter must be
+synchronized either on method or block level.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ private static final SimpleDateFormat sdf = new SimpleDateFormat();
+ void bar() {
+ sdf.format(); // poor, no thread-safety
+ }
+ synchronized void foo() {
+ sdf.format(); // preferred
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseConcurrentHashMap"
+ language="java"
+ minimumLanguageVersion="1.5"
+ since="4.2.6"
+ message="If you run in Java5 or newer and have concurrent access, you should use the ConcurrentHashMap implementation"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#useconcurrenthashmap">
+ <description>
+Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can
+perform efficient map reads without blocking other threads.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Type[../VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[@Image != 'ConcurrentHashMap']]
+/ReferenceType/ClassOrInterfaceType[@Image = 'Map']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class ConcurrentApp {
+ public void getMyInstance() {
+ Map map1 = new HashMap(); // fine for single-threaded access
+ Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
+
+ // the following case will be ignored by this rule
+ Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseNotifyAllInsteadOfNotify"
+ language="java"
+ since="3.0"
+ message="Call Thread.notifyAll() rather than Thread.notify()"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#usenotifyallinsteadofnotify">
+ <description>
+Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only
+one is chosen. The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//StatementExpression/PrimaryExpression
+[PrimarySuffix/Arguments[@ArgumentCount = '0']]
+[
+ PrimaryPrefix[
+ ./Name[@Image='notify' or ends-with(@Image,'.notify')]
+ or ../PrimarySuffix/@Image='notify'
+ or (./AllocationExpression and ../PrimarySuffix[@Image='notify'])
+ ]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+ void bar() {
+ x.notify();
+ // If many threads are monitoring x, only one (and you won't know which) will be notified.
+ // use instead:
+ x.notifyAll();
+ }
+]]>
+ </example>
+ </rule>
+
+</ruleset> \ No newline at end of file
diff --git a/dev/src/main/resources/pmd/category/java/performance.xml b/dev/src/main/resources/pmd/category/java/performance.xml
new file mode 100644
index 0000000..2867e62
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/performance.xml
@@ -0,0 +1,1008 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Performance"
+ xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules that flag suboptimal code.
+ </description>
+
+ <rule name="AddEmptyString"
+ language="java"
+ since="4.0"
+ message="Do not add empty strings"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#addemptystring">
+ <description>
+The conversion of literals to strings by concatenating them with empty strings is inefficient.
+It is much better to use one of the type-specific toString() methods instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AdditiveExpression/PrimaryExpression/PrimaryPrefix/Literal[@Image='""']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+String s = "" + 123; // inefficient
+String t = Integer.toString(456); // preferred approach
+]]>
+ </example>
+ </rule>
+
+ <rule name="AppendCharacterWithChar"
+ since="3.5"
+ message="Avoid appending characters as strings in StringBuffer.append."
+ class="net.sourceforge.pmd.lang.java.rule.performance.AppendCharacterWithCharRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#appendcharacterwithchar">
+ <description>
+Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+StringBuffer sb = new StringBuffer();
+sb.append("a"); // avoid this
+
+StringBuffer sb = new StringBuffer();
+sb.append('a'); // use this instead
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidArrayLoops"
+ language="java"
+ since="3.5"
+ message="System.arraycopy is more efficient"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidarrayloops">
+ <description>
+Instead of manually copying data between two arrays, use the efficient Arrays.copyOf or System.arraycopy method instead.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Statement[(ForStatement or WhileStatement) and
+count(*//AssignmentOperator[@Image = '='])=1
+and
+*/Statement
+[
+./Block/BlockStatement/Statement/StatementExpression/PrimaryExpression
+/PrimaryPrefix/Name/../../PrimarySuffix/Expression
+[(PrimaryExpression or AdditiveExpression) and count
+(.//PrimaryPrefix/Name)=1]//PrimaryPrefix/Name/@Image
+and
+./Block/BlockStatement/Statement/StatementExpression/Expression/PrimaryExpression
+/PrimaryPrefix/Name/../../PrimarySuffix[count
+(..//PrimarySuffix)=1]/Expression[(PrimaryExpression
+or AdditiveExpression) and count(.//PrimaryPrefix/Name)=1]
+//PrimaryPrefix/Name/@Image
+]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Test {
+ public void bar() {
+ int[] a = new int[10];
+ int[] b = new int[10];
+ for (int i=0;i<10;i++) {
+ b[i]=a[i];
+ }
+
+ int[] c = new int[10];
+ // this will trigger the rule
+ for (int i=0;i<10;i++) {
+ b[i]=a[c[i]];
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidFileStream"
+ since="6.0.0"
+ message="Avoid instantiating FileInputStream, FileOutputStream, FileReader, or FileWriter"
+ language="java"
+ minimumLanguageVersion="1.7"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidfilestream">
+ <description>
+The FileInputStream and FileOutputStream classes contains a finalizer method which will cause garbage collection pauses. See [JDK-8080225](https://bugs.openjdk.java.net/browse/JDK-8080225) for details.
+
+The FileReader and FileWriter constructors instantiate FileInputStream and FileOutputStream, again causing garbage collection issues while finalizer methods are called.
+
+* Use `Files.newInputStream(Paths.get(fileName))` instead of `new FileInputStream(fileName)`.
+* Use `Files.newOutputStream(Paths.get(fileName))` instead of `new FileOutputStream(fileName)`.
+* Use `Files.newBufferedReader(Paths.get(fileName))` instead of `new FileReader(fileName)`.
+* Use `Files.newBufferedWriter(Paths.get(fileName))` instead of `new FileWriter(fileName)`.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryPrefix/AllocationExpression/ClassOrInterfaceType[
+ pmd-java:typeIs('java.io.FileInputStream')
+ or pmd-java:typeIs('java.io.FileOutputStream')
+ or pmd-java:typeIs('java.io.FileReader')
+ or pmd-java:typeIs('java.io.FileWriter')
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+ // these instantiations cause garbage collection pauses, even if properly closed
+
+ FileInputStream fis = new FileInputStream(fileName);
+ FileOutputStream fos = new FileOutputStream(fileName);
+ FileReader fr = new FileReader(fileName);
+ FileWriter fw = new FileWriter(fileName);
+
+ // the following instantiations help prevent Garbage Collection pauses, no finalization
+
+ try(InputStream is = Files.newInputStream(Paths.get(fileName))) {
+ }
+ try(OutputStream os = Files.newOutputStream(Paths.get(fileName))) {
+ }
+ try(BufferedReader br = Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)) {
+ }
+ try(BufferedWriter wr = Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8)) {
+ }
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidInstantiatingObjectsInLoops"
+ since="2.2"
+ message="Avoid instantiating new objects inside loops"
+ class="net.sourceforge.pmd.lang.java.rule.performance.AvoidInstantiatingObjectsInLoopsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidinstantiatingobjectsinloops">
+ <description>
+New objects created within loops should be checked to see if they can created outside them and reused.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Something {
+ public static void main( String as[] ) {
+ for (int i = 0; i < 10; i++) {
+ Foo f = new Foo(); // Avoid this whenever you can it's really expensive
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="AvoidUsingShortType"
+ language="java"
+ since="4.1"
+ message="Do not use the short type"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidusingshorttype">
+ <description>
+Java uses the 'short' type to reduce memory usage, not to optimize calculation. In fact, the JVM does not have any
+arithmetic capabilities for the short type: the JVM must convert the short into an int, do the proper calculation
+and convert the int back to a short. Thus any storage gains found through use of the 'short' type may be offset by
+adverse impacts on performance.
+ </description>
+ <priority>1</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//FieldDeclaration/Type/PrimitiveType[@Image = 'short']
+|
+//ClassOrInterfaceBodyDeclaration[not(Annotation/MarkerAnnotation/Name[pmd-java:typeIs('java.lang.Override')])]
+ /MethodDeclaration/ResultType/Type/PrimitiveType[@Image = 'short']
+|
+//ClassOrInterfaceBodyDeclaration[not(Annotation/MarkerAnnotation/Name[pmd-java:typeIs('java.lang.Override')])]
+ /MethodDeclaration/MethodDeclarator/FormalParameters/FormalParameter/Type/PrimitiveType[@Image = 'short']
+|
+//LocalVariableDeclaration/Type/PrimitiveType[@Image = 'short']
+|
+//AnnotationMethodDeclaration/Type/PrimitiveType[@Image = 'short']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class UsingShort {
+ private short doNotUseShort = 0;
+
+ public UsingShort() {
+ short shouldNotBeUsed = 1;
+ doNotUseShort += shouldNotBeUsed;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="BigIntegerInstantiation"
+ since="3.9"
+ message="Don't create instances of already existing BigInteger and BigDecimal (ZERO, ONE, TEN)"
+ class="net.sourceforge.pmd.lang.java.rule.performance.BigIntegerInstantiationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#bigintegerinstantiation">
+ <description>
+Don't create instances of already existing BigInteger (BigInteger.ZERO, BigInteger.ONE) and
+for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN)
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+BigInteger bi = new BigInteger(1); // reference BigInteger.ONE instead
+BigInteger bi2 = new BigInteger("0"); // reference BigInteger.ZERO instead
+BigInteger bi3 = new BigInteger(0.0); // reference BigInteger.ZERO instead
+BigInteger bi4;
+bi4 = new BigInteger(0); // reference BigInteger.ZERO instead
+]]>
+ </example>
+ </rule>
+
+ <rule name="BooleanInstantiation"
+ since="1.2"
+ message="Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead."
+ class="net.sourceforge.pmd.lang.java.rule.performance.BooleanInstantiationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#booleaninstantiation">
+ <description>
+Avoid instantiating Boolean objects; you can reference Boolean.TRUE, Boolean.FALSE, or call Boolean.valueOf() instead.
+Note that new Boolean() is deprecated since JDK 9 for that reason.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+Boolean bar = new Boolean("true"); // unnecessary creation, just reference Boolean.TRUE;
+Boolean buz = Boolean.valueOf(false); // ...., just reference Boolean.FALSE;
+]]>
+ </example>
+ </rule>
+
+ <rule name="ByteInstantiation"
+ language="java"
+ since="4.0"
+ message="Avoid instantiating Byte objects. Call Byte.valueOf() instead"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#byteinstantiation">
+ <description>
+Calling new Byte() causes memory allocation that can be avoided by the static Byte.valueOf().
+It makes use of an internal cache that recycles earlier instances making it more memory efficient.
+Note that new Byte() is deprecated since JDK 9 for that reason.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+[not (ArrayDimsAndInits)
+and ClassOrInterfaceType[pmd-java:typeIs('java.lang.Byte')]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private Byte i = new Byte(0); // change to Byte i = Byte.valueOf(0);
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ConsecutiveAppendsShouldReuse"
+ language="java"
+ since="5.1"
+ message="StringBuffer (or StringBuilder).append is called consecutively without reusing the target variable."
+ class="net.sourceforge.pmd.lang.java.rule.performance.ConsecutiveAppendsShouldReuseRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#consecutiveappendsshouldreuse">
+ <description>
+Consecutive calls to StringBuffer/StringBuilder .append should be chained, reusing the target object. This can improve the performance
+by producing a smaller bytecode, reducing overhead and improving inlining. A complete analysis can be found [here](https://github.com/pmd/pmd/issues/202#issuecomment-274349067)
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+String foo = " ";
+
+StringBuffer buf = new StringBuffer();
+buf.append("Hello"); // poor
+buf.append(foo);
+buf.append("World");
+
+StringBuffer buf = new StringBuffer();
+buf.append("Hello").append(foo).append("World"); // good
+]]>
+ </example>
+ </rule>
+
+ <rule name="ConsecutiveLiteralAppends"
+ since="3.5"
+ message="StringBuffer (or StringBuilder).append is called {0} consecutive times with literals. Use a single append with a single combined String."
+ class="net.sourceforge.pmd.lang.java.rule.performance.ConsecutiveLiteralAppendsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#consecutiveliteralappends">
+ <description>
+Consecutively calling StringBuffer/StringBuilder.append(...) with literals should be avoided.
+Since the literals are constants, they can already be combined into a single String literal and this String
+can be appended in a single method call.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+StringBuilder buf = new StringBuilder();
+buf.append("Hello").append(" ").append("World"); // poor
+buf.append("Hello World"); // good
+
+buf.append('h').append('e').append('l').append('l').append('o'); // poor
+buf.append("hello"); // good
+
+buf.append(1).append('m'); // poor
+buf.append("1m"); // good
+]]>
+ </example>
+ </rule>
+
+ <rule name="InefficientEmptyStringCheck"
+ since="3.6"
+ message="String.trim().length() == 0 / String.trim().isEmpty() is an inefficient way to validate a blank String."
+ class="net.sourceforge.pmd.lang.java.rule.performance.InefficientEmptyStringCheckRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientemptystringcheck">
+ <description>
+<![CDATA[
+String.trim().length() == 0 (or String.trim().isEmpty() for the same reason) is an inefficient
+way to check if a String is really blank, as it creates a new String object just to check its size.
+Consider creating a static function that loops through a string, checking Character.isWhitespace()
+on each character and returning false if a non-whitespace character is found. A Smarter code to
+check for an empty string would be:
+
+```java
+private boolean checkTrimEmpty(String str) {
+ for(int i = 0; i < str.length(); i++) {
+ if(!Character.isWhitespace(str.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+```
+
+You can refer to Apache's StringUtils#isBlank (in commons-lang),
+Spring's StringUtils#hasText (in the Spring framework) or Google's
+CharMatcher#whitespace (in Guava) for existing implementations (some might
+include the check for != null).
+]]>
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public void bar(String string) {
+ if (string != null && string.trim().length() > 0) {
+ doSomething();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="InefficientStringBuffering"
+ since="3.4"
+ message="Avoid concatenating nonliterals in a StringBuffer/StringBuilder constructor or append()."
+ class="net.sourceforge.pmd.lang.java.rule.performance.InefficientStringBufferingRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientstringbuffering">
+ <description>
+Avoid concatenating non-literals in a StringBuffer constructor or append() since intermediate buffers will
+need to be be created and destroyed by the JVM.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+// Avoid this, two buffers are actually being created here
+StringBuffer sb = new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
+
+// do this instead
+StringBuffer sb = new StringBuffer("tmp = ");
+sb.append(System.getProperty("java.io.tmpdir"));
+]]>
+ </example>
+ </rule>
+
+ <rule name="InsufficientStringBufferDeclaration"
+ since="3.6"
+ message="StringBuffer constructor is initialized with size {0}, but has at least {1} characters appended."
+ class="net.sourceforge.pmd.lang.java.rule.performance.InsufficientStringBufferDeclarationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#insufficientstringbufferdeclaration">
+ <description>
+Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many times
+during runtime. This rule attempts to determine the total number the characters that are actually
+passed into StringBuffer.append(), but represents a best guess "worst case" scenario. An empty
+StringBuffer/StringBuilder constructor initializes the object to 16 characters. This default
+is assumed if the length of the constructor can not be determined.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+StringBuffer bad = new StringBuffer();
+bad.append("This is a long string that will exceed the default 16 characters");
+
+StringBuffer good = new StringBuffer(41);
+good.append("This is a long string, which is pre-sized");
+]]>
+ </example>
+ </rule>
+
+ <rule name="IntegerInstantiation"
+ language="java"
+ since="3.5"
+ message="Avoid instantiating Integer objects. Call Integer.valueOf() instead."
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#integerinstantiation">
+ <description>
+Calling new Integer() causes memory allocation that can be avoided by the static Integer.valueOf().
+It makes use of an internal cache that recycles earlier instances making it more memory efficient.
+Note that new Integer() is deprecated since JDK 9 for that reason.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+ [not (ArrayDimsAndInits)
+ and ClassOrInterfaceType[pmd-java:typeIs('java.lang.Integer')]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private Integer i = new Integer(0); // change to Integer i = Integer.valueOf(0);
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="LongInstantiation"
+ language="java"
+ since="4.0"
+ message="Avoid instantiating Long objects.Call Long.valueOf() instead"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#longinstantiation">
+ <description>
+Calling new Long() causes memory allocation that can be avoided by the static Long.valueOf().
+It makes use of an internal cache that recycles earlier instances making it more memory efficient.
+Note that new Long() is deprecated since JDK 9 for that reason.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+[not (ArrayDimsAndInits)
+and ClassOrInterfaceType[pmd-java:typeIs('java.lang.Long')]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private Long i = new Long(0); // change to Long i = Long.valueOf(0);
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="OptimizableToArrayCall"
+ language="java"
+ since="1.8"
+ minimumLanguageVersion="1.6"
+ message="This call to Collection.toArray() may be optimizable"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#optimizabletoarraycall">
+ <description>
+Calls to a collection's `toArray(E[])` method should specify a target array of zero size. This allows the JVM
+to optimize the memory allocation and copying as much as possible.
+
+Previous versions of this rule (pre PMD 6.0.0) suggested the opposite, but current JVM implementations
+perform always better, when they have full control over the target array. And allocation an array via
+reflection is nowadays as fast as the direct allocation.
+
+See also [Arrays of Wisdom of the Ancients](https://shipilev.net/blog/2016/arrays-wisdom-ancients/)
+
+Note: If you don't need an array of the correct type, then the simple `toArray()` method without an array
+is faster, but returns only an array of type `Object[]`.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+[PrimaryPrefix/Name[ends-with(@Image, 'toArray')]]
+[
+PrimarySuffix/Arguments/ArgumentList/Expression
+ /PrimaryExpression/PrimaryPrefix/AllocationExpression
+ /ArrayDimsAndInits/Expression/PrimaryExpression/PrimaryPrefix[not(Literal[@Image='0'])]
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+List<Foo> foos = getFoos();
+
+// much better; this one allows the jvm to allocate an array of the correct size and effectively skip
+// the zeroing, since each array element will be overridden anyways
+Foo[] fooArray = foos.toArray(new Foo[0]);
+
+// inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray method
+Foo[] fooArray = foos.toArray(new Foo[foos.size()]);
+]]>
+ </example>
+ </rule>
+
+ <rule name="RedundantFieldInitializer"
+ language="java"
+ since="5.0"
+ message="Avoid using redundant field initializer for ''${variableName}''"
+ class="net.sourceforge.pmd.lang.java.rule.performance.RedundantFieldInitializerRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#redundantfieldinitializer">
+ <description>
+Java will initialize fields with known default values so any explicit initialization of those same defaults
+is redundant and results in a larger class file (approximately three additional bytecode instructions per field).
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class C {
+ boolean b = false; // examples of redundant initializers
+ byte by = 0;
+ short s = 0;
+ char c = 0;
+ int i = 0;
+ long l = 0;
+
+ float f = .0f; // all possible float literals
+ doable d = 0d; // all possible double literals
+ Object o = null;
+
+ MyClass mca[] = null;
+ int i1 = 0, ia1[] = null;
+
+ class Nested {
+ boolean b = false;
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="SimplifyStartsWith"
+ language="java"
+ since="3.1"
+ message="This call to String.startsWith can be rewritten using String.charAt(0)"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#simplifystartswith">
+ <description>
+Since it passes in a literal of length 1, calls to (string).startsWith can be rewritten using (string).charAt(0)
+at the expense of some readability.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//PrimaryExpression
+ [PrimaryPrefix/Name
+ [ends-with(@Image, '.startsWith')] or PrimarySuffix[@Image='startsWith']]
+ [PrimarySuffix/Arguments/ArgumentList
+ /Expression/PrimaryExpression/PrimaryPrefix
+ /Literal
+ [string-length(@Image)=3]
+ [starts-with(@Image, '"')]
+ [ends-with(@Image, '"')]
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+
+ boolean checkIt(String x) {
+ return x.startsWith("a"); // suboptimal
+ }
+
+ boolean fasterCheckIt(String x) {
+ return x.charAt(0) == 'a'; // faster approach
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="ShortInstantiation"
+ language="java"
+ since="4.0"
+ message="Avoid instantiating Short objects. Call Short.valueOf() instead"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ typeResolution="true"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#shortinstantiation">
+ <description>
+Calling new Short() causes memory allocation that can be avoided by the static Short.valueOf().
+It makes use of an internal cache that recycles earlier instances making it more memory efficient.
+Note that new Short() is deprecated since JDK 9 for that reason.
+ </description>
+ <priority>2</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//AllocationExpression
+[not (ArrayDimsAndInits)
+and ClassOrInterfaceType[pmd-java:typeIs('java.lang.Short')]]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Foo {
+ private Short i = new Short(0); // change to Short i = Short.valueOf(0);
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="StringInstantiation"
+ since="1.0"
+ message="Avoid instantiating String objects; this is usually unnecessary."
+ class="net.sourceforge.pmd.lang.java.rule.performance.StringInstantiationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#stringinstantiation">
+ <description>
+Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared.
+ </description>
+ <priority>2</priority>
+ <example>
+<![CDATA[
+private String bar = new String("bar"); // just do a String bar = "bar";
+]]>
+ </example>
+ </rule>
+
+ <rule name="StringToString"
+ since="1.0"
+ message="Avoid calling toString() on String objects; this is unnecessary."
+ class="net.sourceforge.pmd.lang.java.rule.performance.StringToStringRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#stringtostring">
+ <description>
+Avoid calling toString() on objects already known to be string instances; this is unnecessary.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+private String baz() {
+ String bar = "howdy";
+ return bar.toString();
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="TooFewBranchesForASwitchStatement"
+ language="java"
+ since="4.2"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ message="A switch with less than three branches is inefficient, use a 'if statement' instead."
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#toofewbranchesforaswitchstatement">
+ <description>
+Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few
+cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use the
+if-then statement to increase code readability.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="minimumNumberCaseForASwitch" type="Integer" description="Minimum number of branches for a switch" min="1" max="100" value="3"/>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//SwitchStatement[
+ (count(.//SwitchLabel) < $minimumNumberCaseForASwitch)
+]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+// With a minimumNumberCaseForASwitch of 3
+public class Foo {
+ public void bar() {
+ switch (condition) {
+ case ONE:
+ instruction;
+ break;
+ default:
+ break; // not enough for a 'switch' stmt, a simple 'if' stmt would have been more appropriate
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UnnecessaryWrapperObjectCreation"
+ since="3.8"
+ message="Unnecessary wrapper object creation"
+ class="net.sourceforge.pmd.lang.java.rule.performance.UnnecessaryWrapperObjectCreationRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#unnecessarywrapperobjectcreation">
+ <description>
+Most wrapper classes provide static conversion methods that avoid the need to create intermediate objects
+just to create the primitive forms. Using these avoids the cost of creating objects that also need to be
+garbage-collected later.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public int convert(String s) {
+ int i, i2;
+
+ i = Integer.valueOf(s).intValue(); // this wastes an object
+ i = Integer.parseInt(s); // this is better
+
+ i2 = Integer.valueOf(i).intValue(); // this wastes an object
+ i2 = i; // this is better
+
+ String s3 = Integer.valueOf(i2).toString(); // this wastes an object
+ s3 = Integer.toString(i2); // this is better
+
+ return i2;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseArrayListInsteadOfVector"
+ language="java"
+ since="3.0"
+ message="Use ArrayList instead of Vector"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usearraylistinsteadofvector">
+ <description>
+ArrayList is a much better Collection implementation than Vector if thread-safe operation is not required.
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//CompilationUnit[count(ImportDeclaration) = 0 or count(ImportDeclaration/Name[@Image='java.util.Vector']) > 0]
+ //AllocationExpression/ClassOrInterfaceType
+ [@Image='Vector' or @Image='java.util.Vector']
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class SimpleTest extends TestCase {
+ public void testX() {
+ Collection c1 = new Vector();
+ Collection c2 = new ArrayList(); // achieves the same with much better performance
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseArraysAsList"
+ language="java"
+ since="3.5"
+ message="Use asList instead of tight loops"
+ class="net.sourceforge.pmd.lang.rule.XPathRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usearraysaslist">
+ <description>
+<![CDATA[
+The java.util.Arrays class has a "asList" method that should be used when you want to create a new List from
+an array of objects. It is faster than executing a loop to copy all the elements of the array one by one.
+
+Note that the result of Arrays.asList() is backed by the specified array,
+changes in the returned list will result in the array to be modified.
+For that reason, it is not possible to add new elements to the returned list of Arrays.asList() (UnsupportedOperationException).
+You must use new ArrayList<>(Arrays.asList(...)) if that is inconvenient for you (e.g. because of concurrent access).
+]]>
+ </description>
+ <priority>3</priority>
+ <properties>
+ <property name="xpath">
+ <value>
+<![CDATA[
+//Statement[
+ (ForStatement) and (ForStatement//VariableInitializer//Literal[@IntLiteral='true' and @Image='0']) and (count(.//IfStatement)=0)
+ ]
+ //StatementExpression[
+ PrimaryExpression/PrimaryPrefix/Name[
+ substring-before(@Image,'.add') = ancestor::MethodDeclaration//LocalVariableDeclaration[
+ ./Type//ClassOrInterfaceType[
+ @Image = 'Collection' or
+ @Image = 'List' or @Image='ArrayList'
+ ]
+ ]
+ /VariableDeclarator/VariableDeclaratorId[
+ count(..//AllocationExpression/ClassOrInterfaceType[
+ @Image="ArrayList"
+ ]
+ )=1
+ ]/@Image
+ ]
+ and
+ PrimaryExpression/PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
+ [
+ @Image = ancestor::MethodDeclaration//LocalVariableDeclaration[@Array="true"]/VariableDeclarator/VariableDeclaratorId/@Image
+ or
+ @Image = ancestor::MethodDeclaration//FormalParameter/VariableDeclaratorId/@Image
+ ]
+ /../..[count(.//PrimarySuffix)
+ =1]/PrimarySuffix/Expression/PrimaryExpression/PrimaryPrefix
+ /Name
+ ]
+]]>
+ </value>
+ </property>
+ </properties>
+ <example>
+<![CDATA[
+public class Test {
+ public void foo(Integer[] ints) {
+ // could just use Arrays.asList(ints)
+ List<Integer> l= new ArrayList<>(100);
+ for (int i=0; i< 100; i++) {
+ l.add(ints[i]);
+ }
+ for (int i=0; i< 100; i++) {
+ l.add(a[i].toString()); // won't trigger the rule
+ }
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseIndexOfChar"
+ since="3.5"
+ message="String.indexOf(char) is faster than String.indexOf(String)."
+ class="net.sourceforge.pmd.lang.java.rule.performance.UseIndexOfCharRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#useindexofchar">
+ <description>
+Use String.indexOf(char) when checking for the index of a single character; it executes faster.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+String s = "hello world";
+// avoid this
+if (s.indexOf("d") {}
+// instead do this
+if (s.indexOf('d') {}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UselessStringValueOf"
+ since="3.8"
+ message="No need to call String.valueOf to append to a string."
+ class="net.sourceforge.pmd.lang.java.rule.performance.UselessStringValueOfRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#uselessstringvalueof">
+ <description>
+No need to call String.valueOf to append to a string; just use the valueOf() argument directly.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public String convert(int i) {
+ String s;
+ s = "a" + String.valueOf(i); // not required
+ s = "a" + i; // preferred approach
+ return s;
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseStringBufferForStringAppends"
+ since="3.1"
+ message="Prefer StringBuilder (non-synchronized) or StringBuffer (synchronized) over += for concatenating strings"
+ class="net.sourceforge.pmd.lang.java.rule.performance.UseStringBufferForStringAppendsRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usestringbufferforstringappends">
+ <description>
+The use of the '+=' operator for appending strings causes the JVM to create and use an internal StringBuffer.
+If a non-trivial number of these concatenations are being used then the explicit use of a StringBuilder or
+threadsafe StringBuffer is recommended to avoid this.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ void bar() {
+ String a;
+ a = "foo";
+ a += " bar";
+ // better would be:
+ // StringBuilder a = new StringBuilder("foo");
+ // a.append(" bar");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="UseStringBufferLength"
+ since="3.4"
+ message="This is an inefficient use of StringBuffer.toString; call StringBuffer.length instead."
+ class="net.sourceforge.pmd.lang.java.rule.performance.UseStringBufferLengthRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usestringbufferlength">
+ <description>
+Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("")
+or StringBuffer.toString().length() == ...
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+StringBuffer sb = new StringBuffer();
+
+if (sb.toString().equals("")) {} // inefficient
+
+if (sb.length() == 0) {} // preferred
+]]>
+ </example>
+ </rule>
+
+
+ <!--
+ other optimization/performance should be like avoiding
+ "" + int
+ or "" + (int) i
+ and String.valueOf(int)
+
+ and using Integer.toString(int)
+
+ IntegerToStringShouldBeUsed
+ LongToStringShouldBeUsed
+ BooleanToStringShouldBeUsed
+ -->
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/category/java/security.xml b/dev/src/main/resources/pmd/category/java/security.xml
new file mode 100644
index 0000000..4a3ed95
--- /dev/null
+++ b/dev/src/main/resources/pmd/category/java/security.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+ <description>
+Rules that flag potential security flaws.
+ </description>
+
+ <rule name="HardCodedCryptoKey"
+ since="6.4.0"
+ message="Do not use hard coded encryption keys"
+ class="net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#hardcodedcryptokey">
+ <description>
+Do not use hard coded values for cryptographic operations. Please store keys outside of source code.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ void good() {
+ SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
+ }
+
+ void bad() {
+ SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
+ }
+}
+]]>
+ </example>
+ </rule>
+
+ <rule name="InsecureCryptoIv"
+ since="6.3.0"
+ message="Do not use hard coded initialization vector in crypto operations"
+ class="net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule"
+ externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#insecurecryptoiv">
+ <description>
+Do not use hard coded initialization vector in cryptographic operations. Please use a randomly generated IV.
+ </description>
+ <priority>3</priority>
+ <example>
+<![CDATA[
+public class Foo {
+ void good() {
+ SecureRandom random = new SecureRandom();
+ byte iv[] = new byte[16];
+ random.nextBytes(bytes);
+ }
+
+ void bad() {
+ byte[] iv = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, };
+ }
+
+ void alsoBad() {
+ byte[] iv = "secret iv in here".getBytes();
+ }
+}
+]]>
+ </example>
+ </rule>
+
+</ruleset>
diff --git a/dev/src/main/resources/pmd/ruleset_java.xml b/dev/src/main/resources/pmd/ruleset_java.xml
new file mode 100644
index 0000000..fc3d22e
--- /dev/null
+++ b/dev/src/main/resources/pmd/ruleset_java.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright © 2015-2019 PSI AG - http://www.psi.de
+
+ This program and the accompanying materials
+ are made available under the terms of the Eclipse Public License v1.0
+ which accompanies this distribution, and is available at
+
+ http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<ruleset name="Java Ruleset" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
+
+ <description>
+ The default ruleset used by the Maven PMD Plugin, when no other ruleset is specified.
+ It contains the rules of the old (pre PMD 6.0.0) rulesets java-basic, java-empty, java-imports,
+ java-unnecessary, java-unusedcode.
+ </description>
+
+ <!-- Standard Rulesets from java/basic, java/empty, java/imports, java/unnecessary, java/unusedcode -->
+ <rule ref="pmd/category/java/bestpractices.xml/AvoidUsingHardCodedIP" />
+ <rule ref="pmd/category/java/bestpractices.xml/CheckResultSet" />
+ <rule ref="pmd/category/java/bestpractices.xml/UnusedImports" />
+ <rule ref="pmd/category/java/bestpractices.xml/UnusedFormalParameter" />
+ <rule ref="pmd/category/java/bestpractices.xml/UnusedLocalVariable" />
+ <rule ref="pmd/category/java/bestpractices.xml/UnusedPrivateField" />
+ <rule ref="pmd/category/java/bestpractices.xml/UnusedPrivateMethod" />
+
+ <rule ref="pmd/category/java/codestyle.xml/DontImportJavaLang" />
+ <rule ref="pmd/category/java/codestyle.xml/DuplicateImports" />
+ <rule ref="pmd/category/java/codestyle.xml/ExtendsObject" />
+ <rule ref="pmd/category/java/codestyle.xml/ForLoopShouldBeWhileLoop" />
+ <rule ref="pmd/category/java/codestyle.xml/TooManyStaticImports" />
+ <rule ref="pmd/category/java/codestyle.xml/UnnecessaryFullyQualifiedName" />
+ <rule ref="pmd/category/java/codestyle.xml/UnnecessaryModifier" />
+ <rule ref="pmd/category/java/codestyle.xml/UnnecessaryReturn" />
+
+ <!-- Modification. Parentheses are used to increase the readability of expressions. Removing the parentheses makes it difficult to maintain the code in many cases. -->
+ <!-- rule ref="pmd/category/java/codestyle.xml/UselessParentheses" -->
+ <rule ref="pmd/category/java/codestyle.xml/UselessQualifiedThis" />
+
+ <rule ref="pmd/category/java/design.xml/CollapsibleIfStatements" />
+ <rule ref="pmd/category/java/design.xml/SimplifiedTernary" />
+ <rule ref="pmd/category/java/design.xml/UselessOverridingMethod" />
+
+ <rule ref="pmd/category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop" />
+ <rule ref="pmd/category/java/errorprone.xml/AvoidDecimalLiteralsInBigDecimalConstructor" />
+ <rule ref="pmd/category/java/errorprone.xml/AvoidMultipleUnaryOperators" />
+ <rule ref="pmd/category/java/errorprone.xml/AvoidUsingOctalValues" />
+ <rule ref="pmd/category/java/errorprone.xml/BrokenNullCheck" />
+ <rule ref="pmd/category/java/errorprone.xml/CheckSkipResult" />
+ <rule ref="pmd/category/java/errorprone.xml/ClassCastExceptionWithToArray" />
+ <rule ref="pmd/category/java/errorprone.xml/DontUseFloatTypeForLoopIndices" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyCatchBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyFinallyBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyIfStmt" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyInitializer" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyStatementBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyStatementNotInLoop" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptySwitchStatements" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptySynchronizedBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyTryBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/EmptyWhileStmt" />
+ <rule ref="pmd/category/java/errorprone.xml/ImportFromSamePackage" />
+ <rule ref="pmd/category/java/errorprone.xml/JumbledIncrementer" />
+ <rule ref="pmd/category/java/errorprone.xml/MisplacedNullCheck" />
+ <rule ref="pmd/category/java/errorprone.xml/OverrideBothEqualsAndHashcode" />
+ <rule ref="pmd/category/java/errorprone.xml/ReturnFromFinallyBlock" />
+ <rule ref="pmd/category/java/errorprone.xml/UnconditionalIfStatement" />
+ <rule ref="pmd/category/java/errorprone.xml/UnnecessaryConversionTemporary" />
+ <rule ref="pmd/category/java/errorprone.xml/UnusedNullCheckInEquals" />
+ <rule ref="pmd/category/java/errorprone.xml/UselessOperationOnImmutable" />
+
+ <rule ref="pmd/category/java/multithreading.xml/AvoidThreadGroup" />
+ <rule ref="pmd/category/java/multithreading.xml/DontCallThreadRun" />
+ <rule ref="pmd/category/java/multithreading.xml/DoubleCheckedLocking" />
+
+ <rule ref="pmd/category/java/performance.xml/BigIntegerInstantiation" />
+ <rule ref="pmd/category/java/performance.xml/BooleanInstantiation" />
+ <!-- End of Standard-Ruleset -->
+
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/codestyle.xml/AvoidProtectedFieldInFinalClass" />
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/codestyle.xml/AvoidProtectedMethodInFinalClassNotExtending" />
+
+ <!-- Additional rule -->
+ <!-- no brackets allowed for one-line statements by code convention -->
+ <rule ref="pmd/category/java/codestyle.xml/ControlStatementBraces">
+ <properties>
+ <property name="checkIfElseStmt">false</property>
+ <property name="checkSingleIfStmt">false</property>
+ <property name="checkWhileStmt">false</property>
+ <property name="checkForStmt">false</property>
+ <property name="checkDoWhileStmt">true</property>
+ <property name="checkCaseStmt">false</property>
+ <property name="allowEmptyLoop">false</property>
+ </properties>
+ </rule>
+
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/codestyle.xml/FieldDeclarationsShouldBeAtStartOfClass" />
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/codestyle.xml/LinguisticNaming" />
+
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/design.xml/AbstractClassWithoutAnyMethod" />
+ <!-- Additional rule -->
+ <rule ref="pmd/category/java/design.xml/AvoidRethrowingException" />
+
+</ruleset> \ No newline at end of file
diff --git a/dev/src/test/java/.gitignore b/dev/src/test/java/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dev/src/test/java/.gitignore
diff --git a/dev/src/test/resources/.gitignore b/dev/src/test/resources/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/dev/src/test/resources/.gitignore

Back to the top