Skip to content

Commit

Permalink
Merge branch 'pr-1916'
Browse files Browse the repository at this point in the history
  • Loading branch information
adangel committed Jul 23, 2019
2 parents 26e74b8 + 1898616 commit be67ad9
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 10 deletions.
3 changes: 3 additions & 0 deletions docs/pages/pmd/rules/java/errorprone.md
Original file line number Diff line number Diff line change
Expand Up @@ -2628,6 +2628,9 @@ A class that has private constructors and does not have any static methods or fi
./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration
and
count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) = count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private='true'])
and
not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration/
../Annotation/MarkerAnnotation/Name[pmd-java:typeIs('org.springframework.beans.factory.annotation.Autowired') or pmd-java:typeIs('javax.inject.Inject')])
)
and
not(.//MethodDeclaration[@Static='true'])
Expand Down
8 changes: 8 additions & 0 deletions docs/pages/release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ Being based on a proper Antlr grammar, CPD can:
* The Java rule {% rule "java/errorprone/CloseResource" %} [`java-errorprone`] now ignores by default
`java.io.ByteArrayInputStream`. Such streams do not need to be closed.

* The Java rule {% rule "java/errorprone/MissingStaticMethodInNonInstantiatableClass" %} (`java-errorprone`) has now
the new property `annotations`.
When one of the private constructors is annotated with one of the annotations, then the class is not considered
non-instantiatable anymore and no violation will be reported. By default, Spring's `@Autowired` and
Java EE's `@Inject` annotations are recognized.

### Fixed Issues

* core
Expand All @@ -41,6 +47,7 @@ Being based on a proper Antlr grammar, CPD can:
* [#1910](https://github.com/pmd/pmd/issues/1910): \[java] ATFD calculation problem
* java-errorprone
* [#1749](https://github.com/pmd/pmd/issues/1749): \[java] DD False Positive in DataflowAnomalyAnalysis
* [#1832](https://github.com/pmd/pmd/issues/1832): \[java] False positives for MissingStaticMethodInNonInstantiatableClass when DI is used
* [#1921](https://github.com/pmd/pmd/issues/1921): \[java] CloseResource false positive with ByteArrayInputStream
* java-multithreading
* [#1903](https://github.com/pmd/pmd/issues/1903): \[java] UnsynchronizedStaticFormatter doesn't allow block-level synchronization when using allowMethodLevelSynchronization=true
Expand All @@ -55,6 +62,7 @@ Being based on a proper Antlr grammar, CPD can:
* [#1892](https://github.com/pmd/pmd/pull/1892): \[lua] \[cpd] Added CPD support for Lua - [Maikel Steneker](https://github.com/maikelsteneker)
* [#1905](https://github.com/pmd/pmd/pull/1905): \[java] DataflowAnomalyAnalysis Rule in right order - [YoonhoChoi96](https://github.com/YoonhoChoi96)
* [#1908](https://github.com/pmd/pmd/pull/1908): \[doc] Update ruleset filename from deprecated basic.xml to quickstart.xml - [crunsk](https://github.com/crunsk)
* [#1916](https://github.com/pmd/pmd/pull/1916): \[java] Exclude Autowired and Inject for MissingStaticMethodInNonInstantiatableClass - [AnthonyKot](https://github.com/AnthonyKot)
* [#1917](https://github.com/pmd/pmd/pull/1917): \[core] Add 'no error' return option, and assign it to the cli when the help command is invoked - [Renato Oliveira](https://github.com/renatoliveira)

{% endtocmaker %}
Expand Down
33 changes: 23 additions & 10 deletions pmd-java/src/main/resources/category/java/errorprone.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2408,32 +2408,45 @@ public class Foo implements java.io.Serializable {
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingstaticmethodinnoninstantiatableclass">
<description>
A class that has private constructors and does not have any static methods or fields cannot be used.

When one of the private constructors is annotated with one of the annotations, then the class is not considered
non-instantiatable anymore and no violation will be reported.
See the property `annotations`.
</description>
<priority>3</priority>
<properties>
<property name="annotations" type="List[String]" delimiter="," value="org.springframework.beans.factory.annotation.Autowired, javax.inject.Inject" description="If a constructor is annotated with one of these annotations, then the class is ignored."/>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[@Nested='false']
//ClassOrInterfaceDeclaration[@Nested=false()]
[
(
(: at least one constructor :)
./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration
and
count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) = count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private='true'])
(: only private constructors :)
count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) = count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private=true()])
and
(: all constructors must not be annotated :)
(every $x in $annotations satisfies
not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration/
../Annotation/MarkerAnnotation/Name[pmd-java:typeIs($x)]))
)
and
not(.//MethodDeclaration[@Static='true'])
not(.//MethodDeclaration[@Static=true()])
and
not(.//FieldDeclaration[@Private='false'][@Static='true'])
not(.//FieldDeclaration[@Private=false()][@Static=true()])
and
not(.//ClassOrInterfaceDeclaration[@Nested='true']
[@Public='true']
[@Static='true']
[not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) or ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Public='true']]
not(.//ClassOrInterfaceDeclaration[@Nested=true()]
[@Public=true()]
[@Static=true()]
[not(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) or ./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Public=true()]]
[./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration
[@Public='true']
[@Public=true()]
[./ResultType/Type/ReferenceType/ClassOrInterfaceType
[@Image = //ClassOrInterfaceDeclaration[@Nested='false']/@Image]
[@Image = //ClassOrInterfaceDeclaration[@Nested=false()]/@Image]
]
]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,77 @@ public final class BacklogElementParameters {
}
]]></code>
</test-code>

<test-code>
<description>#1832 Check constructor injection with @Autowired or @Inject </description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import javax.inject.Inject;
import org.springframework.beans.factory.annotation.Autowired;
public class Foo {
private String arg;
@Autowired
private Foo() {}
@Inject
private Foo(String arg) {
this.arg = arg;
}
public void bar() {}
}
]]></code>
</test-code>

<test-code>
<description>#1832 fine with a least one constructor annotated with "Autowired</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.PersistenceConstructor;
public class Foo {
private String arg;
@PersistenceConstructor
private Foo() {}
@Autowired
private Foo(String arg) {
this.arg = arg;
}
public void bar() {}
}
]]></code>
</test-code>

<test-code>
<description>#1832 but fail with both private constructors annotated with @PersistenceConstructor</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
import org.springframework.data.annotation.PersistenceConstructor;
public class Foo {
private String arg;
@PersistenceConstructor
private Foo() {}
@PersistenceConstructor
private Foo(String arg) {
this.arg = arg;
}
public void bar() {}
}
]]></code>
</test-code>


</test-data>

0 comments on commit be67ad9

Please sign in to comment.