From e0bb3308441966f5d19fffec545505f731d2e8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Tue, 16 May 2023 14:03:22 +0200 Subject: [PATCH] update to Gradle 8.1.1, Java 17 --- build.gradle | 16 +- gradle.properties | 1 - gradle/compile/java.gradle | 23 +- .../{publication.gradle => maven.gradle} | 19 +- gradle/quality/checkstyle.gradle | 18 + gradle/quality/checkstyle.xml | 333 ++ gradle/quality/cyclonedx.gradle | 11 + gradle/quality/pmd.gradle | 15 + .../pmd/category/java/bestpractices.xml | 1650 ++++++++ .../pmd/category/java/categories.properties | 10 + .../quality/pmd/category/java/codestyle.xml | 2176 +++++++++++ gradle/quality/pmd/category/java/design.xml | 1657 ++++++++ .../pmd/category/java/documentation.xml | 144 + .../quality/pmd/category/java/errorprone.xml | 3383 +++++++++++++++++ .../pmd/category/java/multithreading.xml | 393 ++ .../quality/pmd/category/java/performance.xml | 1006 +++++ gradle/quality/pmd/category/java/security.xml | 65 + gradle/quality/sonarqube.gradle | 10 + gradle/quality/spotbugs.gradle | 13 + gradle/repositories/maven.gradle | 4 + gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 62076 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 25 +- gradlew.bat | 15 +- rpm-ant/build.gradle | 2 - rpm-core/build.gradle | 2 - settings.gradle | 4 +- 27 files changed, 10939 insertions(+), 59 deletions(-) rename gradle/publishing/{publication.gradle => maven.gradle} (78%) create mode 100644 gradle/quality/checkstyle.gradle create mode 100644 gradle/quality/checkstyle.xml create mode 100644 gradle/quality/cyclonedx.gradle create mode 100644 gradle/quality/pmd.gradle create mode 100644 gradle/quality/pmd/category/java/bestpractices.xml create mode 100644 gradle/quality/pmd/category/java/categories.properties create mode 100644 gradle/quality/pmd/category/java/codestyle.xml create mode 100644 gradle/quality/pmd/category/java/design.xml create mode 100644 gradle/quality/pmd/category/java/documentation.xml create mode 100644 gradle/quality/pmd/category/java/errorprone.xml create mode 100644 gradle/quality/pmd/category/java/multithreading.xml create mode 100644 gradle/quality/pmd/category/java/performance.xml create mode 100644 gradle/quality/pmd/category/java/security.xml create mode 100644 gradle/quality/sonarqube.gradle create mode 100644 gradle/quality/spotbugs.gradle create mode 100644 gradle/repositories/maven.gradle diff --git a/build.gradle b/build.gradle index ed8607f..38089d5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,16 @@ plugins { - id "de.marcphilipp.nexus-publish" version "0.4.0" - id "io.codearte.nexus-staging" version "0.21.1" + id "checkstyle" + id "pmd" + id 'maven-publish' + id 'signing' + id "io.github.gradle-nexus.publish-plugin" version "1.3.0" + id "org.cyclonedx.bom" version "1.7.2" + id "com.github.spotbugs" version "5.0.13" + id "org.xbib.gradle.plugin.asciidoctor" version "2.5.2.2" } wrapper { - gradleVersion = "${project.property('gradle.wrapper.version')}" + gradleVersion = libs.versions.gradle.get() distributionType = Wrapper.DistributionType.ALL } @@ -24,9 +30,9 @@ ext { } subprojects { - apply plugin: 'java-library' apply from: rootProject.file('gradle/ide/idea.gradle') + apply from: rootProject.file('gradle/repositories/maven.gradle') apply from: rootProject.file('gradle/compile/java.gradle') apply from: rootProject.file('gradle/test/junit5.gradle') + apply from: rootProject.file('gradle/publishing/maven.gradle') } -apply from: rootProject.file('gradle/publishing/sonatype.gradle') diff --git a/gradle.properties b/gradle.properties index 69cda89..3c53511 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,3 @@ name = rpm version = 2.2.0 org.gradle.warning.mode = ALL -gradle.wrapper.version = 7.4.2 diff --git a/gradle/compile/java.gradle b/gradle/compile/java.gradle index c9bba7f..a37f057 100644 --- a/gradle/compile/java.gradle +++ b/gradle/compile/java.gradle @@ -3,16 +3,18 @@ apply plugin: 'java-library' java { modularity.inferModulePath.set(true) + withSourcesJar() + withJavadocJar() } compileJava { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } compileTestJava { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } jar { @@ -21,19 +23,6 @@ jar { } } -task sourcesJar(type: Jar, dependsOn: classes) { - classifier 'sources' - from sourceSets.main.allSource -} - -task javadocJar(type: Jar, dependsOn: javadoc) { - classifier 'javadoc' -} - -artifacts { - archives sourcesJar, javadocJar -} - tasks.withType(JavaCompile) { options.compilerArgs << '-Xlint:all,-fallthrough' } diff --git a/gradle/publishing/publication.gradle b/gradle/publishing/maven.gradle similarity index 78% rename from gradle/publishing/publication.gradle rename to gradle/publishing/maven.gradle index c35fcb9..ce6a26f 100644 --- a/gradle/publishing/publication.gradle +++ b/gradle/publishing/maven.gradle @@ -1,13 +1,10 @@ -apply plugin: "de.marcphilipp.nexus-publish" - publishing { publications { - mavenJava(MavenPublication) { + "${project.name}"(MavenPublication) { from components.java - artifact sourcesJar - artifact javadocJar pom { + artifactId = project.name name = project.name description = rootProject.ext.description url = rootProject.ext.url @@ -49,16 +46,6 @@ publishing { if (project.hasProperty("signing.keyId")) { apply plugin: 'signing' signing { - sign publishing.publications.mavenJava - } -} - -nexusPublishing { - repositories { - sonatype { - username = project.property('ossrhUsername') - password = project.property('ossrhPassword') - packageGroup = "org.xbib" - } + sign publishing.publications."${project.name}" } } diff --git a/gradle/quality/checkstyle.gradle b/gradle/quality/checkstyle.gradle new file mode 100644 index 0000000..d737eb3 --- /dev/null +++ b/gradle/quality/checkstyle.gradle @@ -0,0 +1,18 @@ + +tasks.withType(Checkstyle) { + ignoreFailures = true + reports { + xml.getRequired().set(true) + html.getRequired().set(true) + } +} + +checkstyle { + toolVersion = '10.4' + configFile = rootProject.file('gradle/quality/checkstyle.xml') + ignoreFailures = true + showViolations = false + checkstyleMain { + source = sourceSets.main.allSource + } +} diff --git a/gradle/quality/checkstyle.xml b/gradle/quality/checkstyle.xml new file mode 100644 index 0000000..66a9aae --- /dev/null +++ b/gradle/quality/checkstyle.xml @@ -0,0 +1,333 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gradle/quality/cyclonedx.gradle b/gradle/quality/cyclonedx.gradle new file mode 100644 index 0000000..a6bf41b --- /dev/null +++ b/gradle/quality/cyclonedx.gradle @@ -0,0 +1,11 @@ +cyclonedxBom { + includeConfigs = [ 'runtimeClasspath' ] + skipConfigs = [ 'compileClasspath', 'testCompileClasspath' ] + projectType = "library" + schemaVersion = "1.4" + destination = file("build/reports") + outputName = "bom" + outputFormat = "json" + includeBomSerialNumber = true + componentVersion = "2.0.0" +} diff --git a/gradle/quality/pmd.gradle b/gradle/quality/pmd.gradle new file mode 100644 index 0000000..186080d --- /dev/null +++ b/gradle/quality/pmd.gradle @@ -0,0 +1,15 @@ + +tasks.withType(Pmd) { + ignoreFailures = true + reports { + xml.getRequired().set(true) + html.getRequired().set(true) + } +} + +pmd { + ignoreFailures = true + consoleOutput = false + toolVersion = "6.51.0" + ruleSetFiles = rootProject.files('gradle/quality/pmd/category/java/bestpractices.xml') +} diff --git a/gradle/quality/pmd/category/java/bestpractices.xml b/gradle/quality/pmd/category/java/bestpractices.xml new file mode 100644 index 0000000..6bf15a0 --- /dev/null +++ b/gradle/quality/pmd/category/java/bestpractices.xml @@ -0,0 +1,1650 @@ + + + + + + Rules which enforce generally accepted best practices. + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Constructors and methods receiving arrays should clone objects and store the copy. + This prevents future changes from the user from affecting the original array. + + 3 + + + + + + + + Avoid printStackTrace(); use a logger call instead. + + 3 + + + + + + + + + + + + + + + Reassigning loop variables can lead to hard-to-find bugs. Prevent or limit how these variables can be changed. + + In foreach-loops, configured by the `foreachReassign` property: + - `deny`: Report any reassignment of the loop variable in the loop body. _This is the default._ + - `allow`: Don't check the loop variable. + - `firstOnly`: Report any reassignments of the loop variable, except as the first statement in the loop body. + _This is useful if some kind of normalization or clean-up of the value before using is permitted, but any other change of the variable is not._ + + In for-loops, configured by the `forReassign` property: + - `deny`: Report any reassignment of the control variable in the loop body. _This is the default._ + - `allow`: Don't check the control variable. + - `skip`: Report any reassignments of the control variable, except conditional increments/decrements (`++`, `--`, `+=`, `-=`). + _This prevents accidental reassignments or unconditional increments of the control variable._ + + 3 + + + + + + + + Reassigning values to incoming parameters is not recommended. Use temporary local variables instead. + + 2 + + + + + + + + StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks + if held within objects with long lifetimes. + + 3 + + + + + + + + + + + + + + + Application with hard-coded IP addresses can become impossible to deploy in some cases. + Externalizing IP adresses is preferable. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Avoid constants in interfaces. Interfaces should define types, constants are implementation details + better placed in classes or enums. See Effective Java, item 19. + + 3 + + + + + + + + + + + + + + + + By convention, the default label should be the last label in a switch statement. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + 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); + } + } +} +]]> + + + + + + Having a lot of control variables in a 'for' loop makes it harder to see what range of values + the loop iterates over. By default this rule allows a regular 'for' loop with only one variable. + + 3 + + + + //ForInit/LocalVariableDeclaration[count(VariableDeclarator) > $maximumVariables] + + + + + + + + + + Whenever using a log level, one should check if the loglevel is actually enabled, or + otherwise skip the associate String creation and manipulation. + + 2 + + + + + + + + In JUnit 3, test suites are indicated by the suite() method. In JUnit 4, suites are indicated + through the @RunWith(Suite.class) annotation. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + + JUnit assertions should include an informative message - i.e., use the three-argument version of + assertEquals(), not the two-argument version. + + 3 + + + + + + + + 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". + + 3 + + + + + $maximumAsserts] +]]> + + + + + + + + + + + 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. + + 3 + + + + + + + + In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions. + + 3 + + + + + + + + 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. + + 3 + + list = new ArrayList<>(); + + public HashSet getFoo() { + return new HashSet(); + } + + // preferred approach + private List list = new ArrayList<>(); + + public Set getFoo() { + return new HashSet(); + } +} +]]> + + + + + + 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. + + 3 + + + + + + + + + Annotating overridden methods with @Override ensures at compile time that + the method really overrides one, which helps refactoring and clarifies intent. + + 3 + + + + + + + + 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. + + 4 + + + + 1] + [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] +| +//FieldDeclaration + [count(VariableDeclarator) > 1] + [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] +]]> + + + + + + + + + + + + + Position literals first in comparisons, if the second argument is null then NullPointerExceptions + can be avoided, they will just return false. + + 3 + + + + + + + + + + + + + + + Position literals first in comparisons, if the second argument is null then NullPointerExceptions + can be avoided, they will just return false. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + Consider replacing Enumeration usages with the newer java.util.Iterator + + 3 + + + + + + + + + + + + + + + Consider replacing Hashtable usage with the newer java.util.Map if thread safety is not required. + + 3 + + + //Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable'] + + + + + + + + + + Consider replacing Vector usages with the newer java.util.ArrayList if expensive thread-safe operations are not required. + + 3 + + + //Type/ReferenceType/ClassOrInterfaceType[@Image='Vector'] + + + + + + + + + + All switch statements should include a default option to catch any unspecified values. + + 3 + + + + + + + + + + + + + + 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. + + 2 + + + + + + + + + + + + + + + Avoid passing parameters to methods or constructors without actually referencing them in the method body. + + 3 + + + + + + + + Avoid unused import statements to prevent unwanted dependencies. + This rule will also find unused on demand imports, i.e. import com.foo.*. + + 4 + + + + + + + + Detects when a local variable is declared and/or assigned, but not used. + + 3 + + + + + + + + Detects when a private field is declared and/or assigned a value, but not used. + + 3 + + + + + + + + Unused Private Method detects when a private method is declared but is unused. + + 3 + + + + + + + + This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals. + + 3 + + + + + + + + + + + + + + + This rule detects JUnit assertions in object references equality. These assertions should be made by + more specific methods, like assertNull, assertNotNull. + + 3 + + + + + + + + + + + + + + + This rule detects JUnit assertions in object references equality. These assertions should be made + by more specific methods, like assertSame, assertNotSame. + + 3 + + + + + + + + + + + + + + + When asserting a value is the same as a literal or Boxed boolean, use assertTrue/assertFalse, instead of assertEquals. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + Java 7 introduced the try-with-resources statement. This statement ensures that each resource is closed at the end + of the statement. It avoids the need of explicitly closing the resources in a finally block. Additionally exceptions + are better handled: If an exception occurred both in the `try` block and `finally` block, then the exception from + the try block was suppressed. With the `try`-with-resources statement, the exception thrown from the try-block is + preserved. + + 3 + + + + + + + + + + + + + + + + + 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. + + 4 + + + + + + + + + + + + + + diff --git a/gradle/quality/pmd/category/java/categories.properties b/gradle/quality/pmd/category/java/categories.properties new file mode 100644 index 0000000..8ef5eac --- /dev/null +++ b/gradle/quality/pmd/category/java/categories.properties @@ -0,0 +1,10 @@ + +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/gradle/quality/pmd/category/java/codestyle.xml b/gradle/quality/pmd/category/java/codestyle.xml new file mode 100644 index 0000000..ac2f0a0 --- /dev/null +++ b/gradle/quality/pmd/category/java/codestyle.xml @@ -0,0 +1,2176 @@ + + + + + + Rules which enforce a specific coding style. + + + + + Abstract classes should be named 'AbstractXXX'. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by {% rule java/codestyle/ClassNamingConventions %}. + + 3 + + + + + + + + + + + + + + + + + + 3 + + + + + + + + Avoid using dollar signs in variable/method/class/interface names. + + 3 + + + + + + + Avoid using final local variables, turn them into fields. + 3 + + + + + + + + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the more general rule {% rule java/codestyle/FormalParameterNamingConventions %}. + + 4 + + + + + + + + + + + + + + + + + + Do not use protected fields in final classes since they cannot be subclassed. + Clarify your intent by using private or package access modifiers instead. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Unnecessary reliance on Java Native Interface (JNI) calls directly reduces application portability + and increases the maintenance burden. + + 2 + + + //Name[starts-with(@Image,'System.loadLibrary')] + + + + + + + + + + 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. + + 4 + + + + + + + + + + + + + + + + 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. + + 3 + + + + 0 ] +/ClassOrInterfaceBody + /ClassOrInterfaceBodyDeclaration + /ConstructorDeclaration[ count (.//ExplicitConstructorInvocation)=0 ] +]]> + + + + + + + + + + + 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'. + + 1 + + + + + + + + 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. + + 3 + + + + + + + + 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?". + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + 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))] + ]]> + + + + + + + + + + Use explicit scoping instead of accidental usage of default package private level. + The rule allows methods and fields annotated with Guava's @VisibleForTesting. + + 3 + + + + + + + + + + + + Avoid importing anything from the package 'java.lang'. These classes are automatically imported (JLS 7.5.3). + + 4 + + + + + + + + Duplicate or overlapping import statements should be avoided. + + 4 + + + + + + + + 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. + + 1 + + + + + + + + + + + + + + No need to explicitly extend Object. + 4 + + + + + + + + + + + + + + + Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes. + + 3 + + + + + + + + + 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. + + 1 + + + + + + + + Some for loops can be simplified to while loops, this makes them more concise. + + 3 + + + + + + + + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/codestyle/ControlStatementBraces %}. + + 3 + + + //ForStatement[not(Statement/Block)] + + + + + + + + + + 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). + + 1 + + lambda1 = s_str -> { }; + + // lambda parameters with an explicit type can be configured separately + Consumer lambda1 = (String str) -> { }; + + } + + } + ]]> + + + + + + Names for references to generic values should be limited to a single uppercase letter. + + 4 + + + + 1 + or + string:upper-case(@Image) != @Image +] +]]> + + + + + extends BaseDao { + // This is ok... +} + +public interface GenericDao { + // Also this +} + +public interface GenericDao { + // 'e' should be an 'E' +} + +public interface GenericDao { + // 'EF' is not ok. +} +]]> + + + + + + + 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. + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/codestyle/ControlStatementBraces %}. + + 3 + + + + + + + + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/codestyle/ControlStatementBraces %}. + + 3 + + + + + + + + + + + + + + + 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). + + 3 + + + + + + + + The Local Home interface of a Session EJB should be suffixed by 'LocalHome'. + + 4 + + + + + + + + + + + + + + + The Local Interface of a Session EJB should be suffixed by 'Local'. + + 4 + + + + + + + + + + + + + + + A local variable assigned only once can be declared final. + + 3 + + + + + + + + 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). + + 1 + + + + + + + + Fields, formal arguments, or local variable names that are too long can make the code difficult to follow. + + 3 + + + + + $minimum] +]]> + + + + + + + + + + + The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'. + + 4 + + + + + + + + + + + + + + + A method argument that is never re-assigned within the method can be declared final. + + 3 + + + + + + + + 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). + + 1 + + + + + + + + Detects when a non-field has a name starting with 'm_'. This usually denotes a field and could be confusing. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the more general rule + {% rule java/codestyle/LocalVariableNamingConventions %}. + + 3 + + + + + + + + + + + + + + + Detects when a class or interface does not have a package definition. + + 3 + + + //ClassOrInterfaceDeclaration[count(preceding::PackageDeclaration) = 0] + + + + + + + + + + Since Java 1.7, numeric literals can use underscores to separate digits. This rule enforces that + numeric literals above a certain length use these underscores to increase readability. + + The rule only supports decimal (base 10) literals for now. The acceptable length under which literals + are not required to have underscores is configurable via a property. Even under that length, underscores + that are misplaced (not making groups of 3 digits) are reported. + + 3 + + + + + + + + + + + + + + + + + A method should have only one exit point, and that should be the last statement in the method. + + 3 + + 0) { + return "hey"; // first exit + } + return "hi"; // second exit + } +} +]]> + + + + + + Detects when a package definition contains uppercase characters. + + 3 + + + //PackageDeclaration/Name[lower-case(@Image)!=@Image] + + + + + + + + + + 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. + + 3 + + + + + + + + Remote Interface of a Session EJB should not have a suffix. + + 4 + + + + + + + + + + + + + + + A Remote Home interface type of a Session EJB should be suffixed by 'Home'. + + 4 + + + + + + + + + + + + + + + Short Classnames with fewer than e.g. five characters are not recommended. + + 4 + + + + + + + + + + + + + + + + Method names that are very short are not helpful to the reader. + + 3 + + + + + + + + + + + + + + + + Fields, local variables, or parameter names that are very short are not helpful to the reader. + + 3 + + + + + + + + + + + + + + + + + Field names using all uppercase characters - Sun's Java naming conventions indicating constants - should + be declared as final. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the more general rule {% rule java/codestyle/FieldNamingConventions %}. + + 3 + + + + + + + + + + + + + + + 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). + + 3 + + + + + $maximumStaticImports] +]]> + + + + + + + + + + + + Avoid the use of value in annotations when it's the only element. + + 3 + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 4 + + + + + + + + Avoid the creation of unnecessary local variables + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Avoid the use of unnecessary return statements. + + 3 + + + + + + + + Use the diamond operator to let the type be inferred automatically. With the Diamond operator it is possible + to avoid duplication of the type parameters. + Instead, the compiler is now able to infer the parameter types for constructor calls, + which makes the code also more readable. + + 3 + + + + + + + + + strings = new ArrayList(); // unnecessary duplication of type parameters +List stringsWithDiamond = new ArrayList<>(); // using the diamond operator is more concise +]]> + + + + + Useless parentheses should be removed. + 4 + + + + 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)] +]]> + + + + + + + + + + + Reports qualified this usages in the same class. + + 3 + + + + + + + + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the more general rules {% rule java/codestyle/FieldNamingConventions %}, + {% rule java/codestyle/FormalParameterNamingConventions %}, and + {% rule java/codestyle/LocalVariableNamingConventions %}. + + 1 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/codestyle/ControlStatementBraces %}. + + 3 + + + //WhileStatement[not(Statement/Block)] + + + + + + + + diff --git a/gradle/quality/pmd/category/java/design.xml b/gradle/quality/pmd/category/java/design.xml new file mode 100644 index 0000000..ded3d80 --- /dev/null +++ b/gradle/quality/pmd/category/java/design.xml @@ -0,0 +1,1657 @@ + + + + + + Rules that help you discover design issues. + + + + + 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. + + 1 + + + + + + + + + + + + + + + Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block + + 3 + + + + + + + + + + + + + + + Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain. + + 3 + + y) { + if (y>z) { + if (z==x) { + // !! too deep + } + } + } + } +} +]]> + + + + + + Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + *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!"); + } + } +``` +]]> + + 1 + + + + + + + + + + + + + + + Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, + Exception, or Error, use a subclassed exception or error instead. + + 1 + + + + + + + + + + + + + + + A class with only private constructors should be final, unless the private constructor + is invoked by a inner class. + + 1 + + + + = 1 ] +[count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[(@Public = 'true') or (@Protected = 'true') or (@PackagePrivate = 'true')]) = 0 ] +[not(.//ClassOrInterfaceDeclaration)] +]]> + + + + + + + + + + + Sometimes two consecutive 'if' statements can be consolidated by separating their conditions with a boolean short-circuit operator. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + = 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.]]> + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Errors are system exceptions. Do not extend them. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead + in each object at runtime. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + Identifies private fields whose values never change once object initialization ends either in the declaration + of the field or by a constructor. This helps in converting existing classes to becoming immutable ones. + + 3 + + + + + + + + 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.; + * <http://www.ccs.neu.edu/home/lieber/LoD.html> + * <http://en.wikipedia.org/wiki/Law_of_Demeter> + + 3 + + + + + + + + Use opposite operator instead of negating the whole expression with a logic complement operator. + + 3 + + + + + + + + + = + return false; + } + + return true; +} +]]> + + + + + + Avoid using classes from the configured package hierarchy outside of the package hierarchy, + except when using one of the configured allowed classes. + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/design/CyclomaticComplexity %}. + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/design/NcssCount %}. + + 3 + + + + + + + + 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). + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/design/NcssCount %}. + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/design/NcssCount %}. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + 3 + + + + + + + + + + + + + + + Avoid negation in an assertTrue or assertFalse test. + + For example, rephrase: + + assertTrue(!expr); + + as: + + assertFalse(expr); + + + 3 + + + + + + + + + + + + + + + Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability. + + 3 + + + + + + + + + + + + + + + Avoid unnecessary if-then-else statements when returning a boolean. The result of + the conditional test can be returned instead. + + 3 + + + + + + + + No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced + by the rule {% rule java/design/CyclomaticComplexity %}. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + $maxmethods + ] +]]> + + + + + + + + The overriding method merely calls the same method defined in a superclass. + + 3 + + + + + + + + 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. + + 3 + + + + 3 +] +]]> + + + + + + + + + + + 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). + + 3 + + + + + + diff --git a/gradle/quality/pmd/category/java/documentation.xml b/gradle/quality/pmd/category/java/documentation.xml new file mode 100644 index 0000000..34b351a --- /dev/null +++ b/gradle/quality/pmd/category/java/documentation.xml @@ -0,0 +1,144 @@ + + + + + + Rules that are related to code documentation. + + + + + A rule for the politically correct... we don't want to offend anyone. + + 3 + + + + + + + + Denotes whether comments are required (or unwanted) for specific language elements. + + 3 + + + + + + + + Determines whether the dimensions of non-header comments found are within the specified limits. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/quality/pmd/category/java/errorprone.xml b/gradle/quality/pmd/category/java/errorprone.xml new file mode 100644 index 0000000..cf289c3 --- /dev/null +++ b/gradle/quality/pmd/category/java/errorprone.xml @@ -0,0 +1,3383 @@ + + + + + + Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors. + + + + + Avoid assignments in operands; this can make code more complicated and harder to read. + + 3 + + + + + + + + Identifies a possible unsafe usage of a static field. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Use of the term 'assert' will conflict with newer versions of Java since it is a reserved word. + + 2 + + + //VariableDeclaratorId[@Image='assert'] + + + + + + + + + + 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. + + 2 + + 25) { + break; + } +} +]]> + + + + + + 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. + + 3 + + + + + + + + Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the + original error, causing other, more subtle problems later on. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Code containing duplicate String literals can usually be improved by declaring the String as a constant field. + + 3 + + + + + + + + Use of the term 'enum' will conflict with newer versions of Java since it is a reserved word. + + 2 + + + //VariableDeclaratorId[@Image='enum'] + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Each caught exception type should be handled in its own catch clause. + + 3 + + + + + + + + + + + + + + + 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". + + 3 + + + + + + + + + + + = 0) { } // alternative approach + + if (aDouble > 0.0) {} // magic number 0.0 + if (aDouble >= Double.MIN_VALUE) {} // preferred approach +} +]]> + + + + + + 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. + + 2 + + + + + + + + + + + + + + + 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. + + 2 + + + + + + + + Integer literals should not start with zero since this denotes that the rest of literal will be + interpreted as an octal value. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + The null check is broken since it will throw a NullPointerException itself. + It is likely that you used || instead of && or vice versa. + + 2 + + + + + + + Super should be called at the start of the method + 3 + + + + + + + + + + + + + + + Super should be called at the end of the method + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + The java Manual says "By convention, classes that implement this interface should override + Object.clone (which is protected) with a public method." + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + The method clone() should throw a CloneNotSupportedException. + + 3 + + + + + + + + + + + + + + + Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use. + + 3 + + + + + + + + Use equals() to compare object references; avoid comparing them with ==. + + 3 + + + + + + + + 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. + + 1 + + + + + + + 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. + + 5 + + dd-anomaly + foo(buz); + buz = 2; +} // buz is undefined when leaving scope -> du-anomaly +]]> + + + + + + 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. + + 2 + + + + + + + + + + + + + + + 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(). + + 3 + + + + + + + + + + + + + + + Extend Exception or RuntimeException instead of Throwable. + + 3 + + + + + + + + + + + + + + + Use Environment.getExternalStorageDirectory() instead of "/sdcard" + + 3 + + + //Literal[starts-with(@Image,'"/sdcard')] + + + + + + + + + + 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" + + 4 + + + //FinallyStatement[descendant::ThrowStatement] + + + + + + + + + + Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change. + + 4 + + + + + + + + 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). + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + + Empty finalize methods serve no purpose and should be removed. Note that Oracle has declared Object.finalize() as deprecated since JDK 9. + + 3 + + + + + + + + + + + + + + + Empty finally blocks serve no purpose and should be removed. + + 3 + + + + + + + + + + + + + + + Empty If Statement finds instances where a condition is checked but nothing is done about it. + + 3 + + + + + + + + + + + + + + + Empty initializers serve no purpose and should be removed. + + 3 + + + //Initializer/Block[count(*)=0] + + + + + + + + + + Empty block statements serve no purpose and should be removed. + + 3 + + + //BlockStatement/Statement/Block[count(*) = 0] + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Empty switch statements serve no purpose and should be removed. + + 3 + + + //SwitchStatement[count(*) = 1] + + + + + + + + + + Empty synchronized blocks serve no purpose and should be removed. + + 3 + + + //SynchronizedStatement/Block[1][count(*) = 0] + + + + + + + + + + Avoid empty try blocks - what's the point? + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Tests for null should not use the equals() method. The '==' operator should be used instead. + + 1 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + 0]] +]]> + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Avoid idempotent operations - they have no effect. + + 3 + + + + + + + + There is no need to import a type that lives in the same package. + + 3 + + + + + + + + Avoid instantiating an object just to call getClass() on it; use the .class public member instead. + + 4 + + + + + + + + + + + + + + + Check for messages in slf4j loggers with non matching number of arguments and placeholders. + + 5 + + + + + + + + Avoid jumbled loop incrementers - its usually a mistake, and is confusing even if intentional. + + 3 + + + + + + + + + + + + + + Some JUnit framework methods are easy to misspell. + + 3 + + + + + + + + + + + + + + + The suite() method in a JUnit test needs to be both public and static. + + 3 + + + + + + + + + + + + + + + In most cases, the Logger reference can be declared as static and final. + + 2 + + + + + + + + + + + + + + + Non-constructor methods should not have the same name as the enclosing class. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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). + + 3 + + + + + + + + + + + + + + + A class that has private constructors and does not have any static methods or fields cannot be used. + + 3 + + + + + + + + + + + + + + + Normally only one logger is used in each class. + + 2 + + + + + + + + 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. + + 3 + + + //SwitchStatement//BlockStatement/Statement/LabeledStatement + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Object clone() should be implemented with super.clone(). + + 2 + + + + 0 +] +]]> + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + 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. + + 1 + + + + + + + + + + + + + + + Avoid returning from a finally block, this can discard exceptions. + + 3 + + + + //FinallyStatement//ReturnStatement except //FinallyStatement//(MethodDeclaration|LambdaExpression)//ReturnStatement + + + + + + + + + + Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate + formatting is used. + + 3 + + + + + + + + + + + + + + + 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. + + 2 + + + + + + + + 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. + + 2 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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 + ``` + + 4 + + + + + + + + + + + + + + + The method name and parameter number are suspiciously close to equals(Object), which can denote an + intention to override the equals(Object) method. + + 2 + + + + + + + + + + + + + + + The method name and return type are suspiciously close to hashCode(), which may denote an intention + to override the hashCode() method. + + 3 + + + + + + + + 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". + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Do not use "if" statements whose conditionals are always true or always false. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals() + + 3 + + + + + + + + Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methods + on the wrapper classes instead. + + 3 + + + + + + + + After checking an object reference for null, you should invoke equals() on that object rather than passing it to another object's equals() method. + + 3 + + + + + + + + + + + + + + + To make sure the full stacktrace is printed out, use the logging statement with two arguments: a String and a Throwable. + + 3 + + + + + + + + + + + + + + + Using '==' or '!=' to compare strings only works if intern version is used on both sides. + Use the equals() method instead. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + When doing String.toLowerCase()/toUpperCase() conversions, use Locales to avoids problems with languages that + have unusual conventions, i.e. Turkish. + + 3 + + + + + + + + + + + + + + + In J2EE, the getClassLoader() method might not work as expected. Use + Thread.currentThread().getContextClassLoader() instead. + + 3 + + + //PrimarySuffix[@Image='getClassLoader'] + + + + + + + + diff --git a/gradle/quality/pmd/category/java/multithreading.xml b/gradle/quality/pmd/category/java/multithreading.xml new file mode 100644 index 0000000..d3e8327 --- /dev/null +++ b/gradle/quality/pmd/category/java/multithreading.xml @@ -0,0 +1,393 @@ + + + + + + Rules that flag issues when dealing with multiple threads of execution. + + + + + 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. + + 3 + + + //MethodDeclaration[@Synchronized='true'] + + + + + + + + + + Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment + it contains methods that are not thread-safe. + + 3 + + + + + + + + + + + + + + + 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. + + 2 + + + //FieldDeclaration[contains(@Volatile,'true')] + + + + + + + + + + The J2EE specification explicitly forbids the use of threads. + + 3 + + + //ClassOrInterfaceType[@Image = 'Thread' or @Image = 'Runnable'] + + + + + + + + + + Explicitly calling Thread.run() method will execute in the caller's thread of control. Instead, call Thread.start() for the intended behavior. + + 4 + + + + + + + + + + + + + + + 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: <http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html> + or <http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html> + + 1 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + This rule has been deprecated in favor of the rule {% rule UnsynchronizedStaticFormatter %}. + + 3 + + + + + + + + Instances of `java.text.Format` are generally 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. + + 3 + + + + + + + + Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can + perform efficient map reads without blocking other threads. + + 3 + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/quality/pmd/category/java/performance.xml b/gradle/quality/pmd/category/java/performance.xml new file mode 100644 index 0000000..1ce2d8d --- /dev/null +++ b/gradle/quality/pmd/category/java/performance.xml @@ -0,0 +1,1006 @@ + + + + + + Rules that flag suboptimal code. + + + + + 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. + + 3 + + + + + + + + + + + + + + + Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods. + + 3 + + + + + + + + Instead of manually copying data between two arrays, use the efficient Arrays.copyOf or System.arraycopy method instead. + + 3 + + + + + + + + + + + + + + + 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)`. + + Please note, that the `java.nio` API does not throw a `FileNotFoundException` anymore, instead + it throws a `NoSuchFileException`. If your code dealt explicitly with a `FileNotFoundException`, + then this needs to be adjusted. Both exceptions are subclasses of `IOException`, so catching + that one covers both. + + 1 + + + + + + + + + + + + + + + New objects created within loops should be checked to see if they can created outside them and reused. + + 3 + + + + + + + + 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. + + 1 + + + + + + + + + + + + + + + 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) + + 3 + + + + + + + + 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. + + 2 + + + + + + + + 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. + + 2 + + + + + + + + + + + + + + + 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) + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + 3 + + 0) { + doSomething(); + } +} +]]> + + + + + + Avoid concatenating non-literals in a StringBuffer constructor or append() since intermediate buffers will + need to be be created and destroyed by the JVM. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + 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. + + 2 + + + + + + + + + + + + + + + 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. + + 2 + + + + + + + + + + + + + + + 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[]`. + + 3 + + + + + + + + + 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()]); +]]> + + + + + + 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). + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + 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. + + 2 + + + + + + + + + + + + + + + Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared. + + 2 + + + + + + + + Avoid calling toString() on objects already known to be string instances; this is unnecessary. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + + + + + + + + + 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. + + 3 + + + + + + + + ArrayList is a much better Collection implementation than Vector if thread-safe operation is not required. + + 3 + + + + 0] + //AllocationExpression/ClassOrInterfaceType + [@Image='Vector' or @Image='java.util.Vector'] +]]> + + + + + + + + + + + (Arrays.asList(...)) if that is inconvenient for you (e.g. because of concurrent access). +]]> + + 3 + + + + + + + + + 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 + } + } +} +]]> + + + + + + Use String.indexOf(char) when checking for the index of a single character; it executes faster. + + 3 + + + + + + + + No need to call String.valueOf to append to a string; just use the valueOf() argument directly. + + 3 + + + + + + + + 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. + + 3 + + + + + + + + Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("") + or StringBuffer.toString().length() == ... + + 3 + + + + + + + + + diff --git a/gradle/quality/pmd/category/java/security.xml b/gradle/quality/pmd/category/java/security.xml new file mode 100644 index 0000000..dbad352 --- /dev/null +++ b/gradle/quality/pmd/category/java/security.xml @@ -0,0 +1,65 @@ + + + + + + Rules that flag potential security flaws. + + + + + Do not use hard coded values for cryptographic operations. Please store keys outside of source code. + + 3 + + + + + + + + Do not use hard coded initialization vector in cryptographic operations. Please use a randomly generated IV. + + 3 + + + + + + diff --git a/gradle/quality/sonarqube.gradle b/gradle/quality/sonarqube.gradle new file mode 100644 index 0000000..8243dd3 --- /dev/null +++ b/gradle/quality/sonarqube.gradle @@ -0,0 +1,10 @@ +/* +sonarqube { + properties { + property "sonar.projectName", "${project.group} ${project.name}" + property "sonar.sourceEncoding", "UTF-8" + property "sonar.tests", "src/test/java" + property "sonar.scm.provider", "git" + } +} +*/ \ No newline at end of file diff --git a/gradle/quality/spotbugs.gradle b/gradle/quality/spotbugs.gradle new file mode 100644 index 0000000..e6bb167 --- /dev/null +++ b/gradle/quality/spotbugs.gradle @@ -0,0 +1,13 @@ + +spotbugs { + effort = "max" + reportLevel = "low" + ignoreFailures = true +} + +spotbugsMain { + reports { + xml.getRequired().set(false) + html.getRequired().set(true) + } +} diff --git a/gradle/repositories/maven.gradle b/gradle/repositories/maven.gradle new file mode 100644 index 0000000..ec58acb --- /dev/null +++ b/gradle/repositories/maven.gradle @@ -0,0 +1,4 @@ +repositories { + mavenLocal() + mavenCentral() +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..c1962a79e29d3e0ab67b14947c167a862655af9b 100644 GIT binary patch delta 40199 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 delta 37942 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/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index ac1b06f..6689b85 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/rpm-ant/build.gradle b/rpm-ant/build.gradle index cc2f3e5..8637635 100644 --- a/rpm-ant/build.gradle +++ b/rpm-ant/build.gradle @@ -2,5 +2,3 @@ dependencies { api project(':rpm-core') implementation libs.ant } - -apply from: rootProject.file('gradle/publishing/publication.gradle') diff --git a/rpm-core/build.gradle b/rpm-core/build.gradle index 9b49d25..e8deac0 100644 --- a/rpm-core/build.gradle +++ b/rpm-core/build.gradle @@ -3,5 +3,3 @@ dependencies { api libs.bzip2 api libs.xz } - -apply from: rootProject.file('gradle/publishing/publication.gradle') diff --git a/settings.gradle b/settings.gradle index defd083..0c419bf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1,8 @@ dependencyResolutionManagement { versionCatalogs { libs { - version('gradle', '7.4.2') - version('junit', '5.8.2') + version('gradle', '8.1.1') + version('junit', '5.9.3') library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit') library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit') library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')