diff --git a/pom.xml b/pom.xml index ab31cbf7f..c17e77ed2 100644 --- a/pom.xml +++ b/pom.xml @@ -176,19 +176,19 @@ OF THE POSSIBILITY OF SUCH DAMAGE. org.hamcrest hamcrest-core - 2.2 + 3.0 test org.hamcrest hamcrest-library - 2.2 + 3.0 test org.slf4j slf4j-log4j12 - 2.0.13 + 2.0.16 test diff --git a/qulice-checkstyle/pom.xml b/qulice-checkstyle/pom.xml index 2d078b28c..0c0aed8cf 100644 --- a/qulice-checkstyle/pom.xml +++ b/qulice-checkstyle/pom.xml @@ -92,7 +92,7 @@ OF THE POSSIBILITY OF SUCH DAMAGE. org.apache.commons commons-lang3 - 3.14.0 + 3.16.0 test diff --git a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/JavadocTagsCheck.java b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/JavadocTagsCheck.java index bceeef883..49c27124f 100644 --- a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/JavadocTagsCheck.java +++ b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/JavadocTagsCheck.java @@ -131,8 +131,11 @@ public void visitToken(final DetailAST ast) { * @param text Text to find. * @return Line number with found text, or -1 if it wasn't found. */ - private static int findTrimmedTextUp(final String[] lines, - final int start, final String text) { + private static int findTrimmedTextUp( + final String[] lines, + final int start, + final String text + ) { int found = -1; for (int pos = start - 1; pos >= 0; pos -= 1) { if (lines[pos].trim().equals(text)) { @@ -172,8 +175,13 @@ private static int findCommentEnd(final String[] lines, final int start) { * @param tag Name of the tag. * @checkstyle ParameterNumber (3 lines) */ - private void findProhibited(final String[] lines, final int start, - final int cstart, final int cend, final String tag) { + private void findProhibited( + final String[] lines, + final int start, + final int cstart, + final int cend, + final String tag + ) { final List found = this.findTagLineNum(lines, cstart, cend, tag); if (!found.isEmpty()) { @@ -194,8 +202,12 @@ private void findProhibited(final String[] lines, final int start, * @return Line number with found tag or -1 otherwise. * @checkstyle ParameterNumber (3 lines) */ - private List findTagLineNum(final String[] lines, final int start, - final int end, final String tag) { + private List findTagLineNum( + final String[] lines, + final int start, + final int end, + final String tag + ) { final String prefix = String.format(" * @%s ", tag); final List found = new ArrayList<>(1); for (int pos = start; pos <= end; pos += 1) { diff --git a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/MultiLineCommentCheck.java b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/MultiLineCommentCheck.java index ed51b4eca..7df7235b0 100644 --- a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/MultiLineCommentCheck.java +++ b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/MultiLineCommentCheck.java @@ -38,21 +38,26 @@ /** * Multi line comment checker. + * Used by the checkstyle process multiple times as a singleton. * @since 0.23.1 */ public final class MultiLineCommentCheck extends AbstractCheck { /** * Pattern for check. + * It is not final as it is initialized from the configuration. */ private Pattern format = Pattern.compile("^$"); /** * The message to report for a match. + * It is not final as it is initialized from the configuration. */ private String message = ""; /** * Comment line. + * It is not final because the visitToken method is called many times + * during the class under test and the field is reinitialized with a new object. */ @SuppressWarnings("PMD.AvoidStringBufferField") private StringBuilder line; @@ -96,10 +101,27 @@ public void visitToken(final DetailAST ast) { } } + /** + * The method is called from checkstyle to configure this class. + * The parameter is set from the checks.xml file + * and + * property + * + * @param fmt Validatig regexp. + */ public void setFormat(final String fmt) { this.format = Pattern.compile(fmt); } + /** + * The method is called from checkstyle to configure this class. + * The parameter is set from the checks.xml file + * and + * + * property + * + * @param msg Error message. + */ public void setMessage(final String msg) { this.message = msg; } diff --git a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/ProhibitUnusedPrivateConstructorCheck.java b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/ProhibitUnusedPrivateConstructorCheck.java new file mode 100644 index 000000000..843ec9703 --- /dev/null +++ b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/ProhibitUnusedPrivateConstructorCheck.java @@ -0,0 +1,222 @@ +/* + * Copyright (c) 2011-2024 Qulice.com + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. 2) Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. 3) Neither the name of the Qulice.com nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.qulice.checkstyle; + +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import java.util.LinkedList; +import java.util.List; + +/** + * Checks that constructor, declared as private class is used more than once. + * + * @since 0.3 + */ +public final class ProhibitUnusedPrivateConstructorCheck extends AbstractCheck { + + @Override + public int[] getDefaultTokens() { + return new int[] {TokenTypes.CLASS_DEF}; + } + + @Override + public int[] getAcceptableTokens() { + return this.getDefaultTokens(); + } + + @Override + public int[] getRequiredTokens() { + return this.getDefaultTokens(); + } + + @Override + public void visitToken(final DetailAST ast) { + final DetailAST objblock = ast.findFirstToken(TokenTypes.OBJBLOCK); + if (objblock != null) { + this.checkConstructors(objblock); + } + } + + /** + * Collects all private constructors in a given object block. + * + * @param objblock Node which contains constructors + * @return List of DetailAST nodes representing the private constructors + */ + private static List collectPrivateConstructors(final DetailAST objblock) { + final List prvctors = new LinkedList<>(); + final DetailAST firstchld = objblock.getFirstChild(); + for (DetailAST child = firstchld; child != null; child = child.getNextSibling()) { + if (child.getType() == TokenTypes.CTOR_DEF && isPrivate(child)) { + prvctors.add(child); + } + } + return prvctors; + } + + /** + * Checks if a private constructor is used in the object block. + * + * @param privatector Node representing the private constructor + * @param objblock Node which contains constructors + * @return True if the private constructor is used, False otherwise + */ + private static boolean isPrivateConstructorUsed( + final DetailAST privatector, final DetailAST objblock) { + return + isPrivateCtorUsedInOtherCtors(privatector, objblock) + || + isPrivateCtorUsedInMethods(privatector, objblock); + } + + /** + * Checks if a private constructor is used in other constructors. + * + * @param privatector Node representing the private constructor + * @param objblock Node containing constructors + * @return True if the private constructor is used, False otherwise + */ + private static boolean isPrivateCtorUsedInOtherCtors( + final DetailAST privatector, final DetailAST objblock) { + final List allctors = collectAllConstructors(objblock); + return allctors.stream() + .anyMatch( + otherCtor -> otherCtor != privatector + && + isCallingConstructor(otherCtor, privatector)); + } + + /** + * Checks if a private constructor is used in methods of the object block. + * + * @param privatector Node representing the private constructor + * @param objblock Node containing methods + * @return True if the private constructor is used, False otherwise + */ + private static boolean isPrivateCtorUsedInMethods( + final DetailAST privatector, final DetailAST objblock) { + boolean result = false; + final DetailAST firstchld = objblock.getFirstChild(); + for (DetailAST child = firstchld; child != null; child = child.getNextSibling()) { + if (child.getType() == TokenTypes.METHOD_DEF + && + isCallingConstructor(child, privatector)) { + result = true; + break; + } + } + return result; + } + + /** + * Collects all constructors in a given object block. + * + * @param objblock Node which contains constructors + * @return List of DetailAST nodes representing all the constructors + */ + private static List collectAllConstructors(final DetailAST objblock) { + final List allctors = new LinkedList<>(); + final DetailAST firstchld = objblock.getFirstChild(); + for (DetailAST child = firstchld; child != null; child = child.getNextSibling()) { + if (child.getType() == TokenTypes.CTOR_DEF) { + allctors.add(child); + } + } + return allctors; + } + + /** + * Returns true if specified node has modifiers of type + * PRIVATE. + * + * @param node Node to check. + * @return True if specified node contains modifiers of type + * PRIVATE, else returns false. + */ + private static boolean isPrivate(final DetailAST node) { + final DetailAST modifiers = node.findFirstToken(TokenTypes.MODIFIERS); + return modifiers.getChildCount(TokenTypes.LITERAL_PRIVATE) > 0; + } + + private static boolean isCallingConstructor( + final DetailAST methodorctor, final DetailAST targetctor) { + boolean result = false; + final DetailAST body = methodorctor.findFirstToken(TokenTypes.SLIST); + if (body != null) { + DetailAST stmt = body.getFirstChild(); + while (stmt != null && !result) { + result = isMatchingConstructorCall(stmt, targetctor); + stmt = stmt.getNextSibling(); + } + } + return result; + } + + private static boolean isMatchingConstructorCall( + final DetailAST stmt, final DetailAST targetctor) { + return + stmt.getType() == TokenTypes.CTOR_CALL + && + matchesConstructorSignature(stmt, targetctor); + } + + private static boolean matchesConstructorSignature( + final DetailAST callexpr, final DetailAST ctor) { + final DetailAST callparams = callexpr.findFirstToken(TokenTypes.ELIST); + final DetailAST ctorparams = ctor.findFirstToken(TokenTypes.PARAMETERS); + return parametersCountMatch(callparams, ctorparams); + } + + private static boolean parametersCountMatch( + final DetailAST callparams, final DetailAST ctorparams) { + final int ncallparams = callparams.getChildCount(TokenTypes.EXPR); + final int nctorparams = ctorparams.getChildCount(TokenTypes.PARAMETER_DEF); + return ncallparams == nctorparams; + } + + /** + * Checks if private constructors are used. + * Logs a message if a private constructor is not used. + * + * @param objblock Node which contains constructors + */ + private void checkConstructors(final DetailAST objblock) { + final List prvctors = collectPrivateConstructors(objblock); + for (final DetailAST ctor : prvctors) { + if (!isPrivateConstructorUsed(ctor, objblock)) { + this.log(ctor.getLineNo(), "Unused private constructor."); + } + } + } + +} diff --git a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/RequiredJavaDocTag.java b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/RequiredJavaDocTag.java index 404be57f8..eddeb63b6 100644 --- a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/RequiredJavaDocTag.java +++ b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/RequiredJavaDocTag.java @@ -89,8 +89,11 @@ final class RequiredJavaDocTag { * @param patt Pattern for checking the contents of a tag in a string. * @param rep Reference to a method for writing a message to the log. */ - RequiredJavaDocTag(final String name, final Pattern patt, - final Reporter rep) { + RequiredJavaDocTag( + final String name, + final Pattern patt, + final Reporter rep + ) { this( name, Pattern.compile( @@ -112,8 +115,12 @@ final class RequiredJavaDocTag { * @param rep Reference to a method for writing a message to the log. * @checkstyle ParameterNumberCheck (3 lines) */ - RequiredJavaDocTag(final String cname, final Pattern ptag, - final Pattern patt, final Reporter rep) { + RequiredJavaDocTag( + final String cname, + final Pattern ptag, + final Pattern patt, + final Reporter rep + ) { this.name = cname; this.tag = ptag; this.content = patt; @@ -126,8 +133,11 @@ final class RequiredJavaDocTag { * @param start Line number where comment starts. * @param end Line number where comment ends. */ - public void matchTagFormat(final String[] lines, final int start, - final int end) { + public void matchTagFormat( + final String[] lines, + final int start, + final int end + ) { final Map found = new HashMap<>(1); for (int pos = start; pos <= end; pos += 1) { final String line = lines[pos]; diff --git a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/SingleLineCommentCheck.java b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/SingleLineCommentCheck.java index ed7d73cab..c2fe78a36 100644 --- a/qulice-checkstyle/src/main/java/com/qulice/checkstyle/SingleLineCommentCheck.java +++ b/qulice-checkstyle/src/main/java/com/qulice/checkstyle/SingleLineCommentCheck.java @@ -45,16 +45,20 @@ public final class SingleLineCommentCheck extends AbstractCheck { /** * Pattern for check. + * It is not final as it is initialized from the configuration. */ private Pattern format = Pattern.compile("^$"); /** * The message to report for a match. + * It is not final as it is initialized from the configuration. */ private String message = ""; /** * Comment line. + * It is not final because the visitToken method is called many times + * during the class under test and the field is reinitialized with a new object. */ @SuppressWarnings("PMD.AvoidStringBufferField") private StringBuilder line; @@ -104,10 +108,27 @@ public void visitToken(final DetailAST ast) { } } + /** + * The method is called from checkstyle to configure this class. + * The parameter is set from the checks.xml file + * and + * property + * + * @param fmt Validatig regexp. + */ public void setFormat(final String fmt) { this.format = Pattern.compile(fmt); } + /** + * The method is called from checkstyle to configure this class. + * The parameter is set from the checks.xml file + * and + * + * property + * + * @param msg Error message. + */ public void setMessage(final String msg) { this.message = msg; } diff --git a/qulice-checkstyle/src/test/java/com/qulice/checkstyle/ChecksTest.java b/qulice-checkstyle/src/test/java/com/qulice/checkstyle/ChecksTest.java index e2e4864ff..b5a520d3a 100644 --- a/qulice-checkstyle/src/test/java/com/qulice/checkstyle/ChecksTest.java +++ b/qulice-checkstyle/src/test/java/com/qulice/checkstyle/ChecksTest.java @@ -196,7 +196,8 @@ private static Stream checks() { "JavadocTagsCheck", "ProhibitNonFinalClassesCheck", "QualifyInnerClassCheck", - "CommentCheck" + "CommentCheck", + "ProhibitUnusedPrivateConstructorCheck" ).map(s -> String.format("ChecksTest/%s", s)); } diff --git a/qulice-checkstyle/src/test/java/com/qulice/checkstyle/RequiredJavaDocTagTest.java b/qulice-checkstyle/src/test/java/com/qulice/checkstyle/RequiredJavaDocTagTest.java index 8a8b48d9a..f8f83fe0c 100644 --- a/qulice-checkstyle/src/test/java/com/qulice/checkstyle/RequiredJavaDocTagTest.java +++ b/qulice-checkstyle/src/test/java/com/qulice/checkstyle/RequiredJavaDocTagTest.java @@ -32,9 +32,13 @@ import java.text.MessageFormat; import java.util.regex.Pattern; +import java.util.stream.Stream; +import org.hamcrest.Matcher; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; /** * Test case for {@link RequiredJavaDocTag} class. @@ -58,50 +62,42 @@ final class RequiredJavaDocTagTest { this.writer ); - @Test - void success() { - final String[] lines = {" *", " * @since 0.3", " *"}; + @ParameterizedTest + @MethodSource("params") + void success(final String[] lines, final String reason, final Matcher expected) { this.tag.matchTagFormat(lines, 0, 2); MatcherAssert.assertThat( - "Empty string expected", + reason, this.writer.formattedMessage(), - Matchers.emptyString() + expected ); } - @Test - void successWithSpaces() { - final String[] lines = {" *", " * @since 0.3", " *"}; - this.tag.matchTagFormat(lines, 0, 2); - MatcherAssert.assertThat( - "Empty string expected", - this.writer.formattedMessage(), - Matchers.emptyString() - ); - } - - @Test - void tagNotFound() { - final String[] lines = {" *", " * @sinc 0.3", " *"}; - this.tag.matchTagFormat(lines, 0, 2); - MatcherAssert.assertThat( - "Expected tag not found", - this.writer.formattedMessage(), - Matchers.equalTo("Missing '@since' tag in class/interface comment") - ); - } - - @Test - void tagNotMatched() { - final String[] lines = {" *", " * @since 0.3.4.4.", " *"}; - this.tag.matchTagFormat(lines, 0, 2); - MatcherAssert.assertThat( - "Regular expression non-match expected", - this.writer.formattedMessage(), - Matchers.equalTo( - String.format( - "Tag text '0.3.4.4.' does not match the pattern '%s'", - "^\\d+(\\.\\d+){1,2}(\\.[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" + private static Stream params() { + return Stream.of( + Arguments.arguments( + new String[] {" *", " * @since 0.3", " *"}, + "Empty string expected", + Matchers.emptyString() + ), + Arguments.arguments( + new String[] {" *", " * @since 0.3", " *"}, + "Empty string expected", + Matchers.emptyString() + ), + Arguments.arguments( + new String[] {" *", " * @sinc 0.3", " *"}, + "Expected tag not found", + Matchers.equalTo("Missing '@since' tag in class/interface comment") + ), + Arguments.arguments( + new String[] {" *", " * @since 0.3.4.4.", " *"}, + "Regular expression non-match expected", + Matchers.equalTo( + String.format( + "Tag text '0.3.4.4.' does not match the pattern '%s'", + "^\\d+(\\.\\d+){1,2}(\\.[0-9A-Za-z-]+(\\.[0-9A-Za-z-]+)*)?$" + ) ) ) ); diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/CommentCheck/Valid.java b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/CommentCheck/Valid.java index c2933bf27..a34f532cb 100644 --- a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/CommentCheck/Valid.java +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/CommentCheck/Valid.java @@ -12,14 +12,29 @@ public final class Valid { /** * Valid multiline comment */ - private static String VALID_CSTYLE_LITERAL = "/* C-style comment */"; + private static String VALID_CSTYLE_LITERAL = " /* C-style comment */"; + + /** + * Valid multiline comment starts with two spaces + */ + private static String VALID_CSTYLE_LITERAL_WITH_TWO_SP = " /* C-style comment */"; /** Valid single-line comment. */ private static String SINGLE_LINE_LITERAL = - "/** first sentence in a comment should start with a capital letter */"; + " /** first sentence in a comment should start with a capital letter */"; + + /** Valid single-line comment starts with two spaces. */ + private static String SINGLE_LINE_LITERAL_WITH_TWO_SP = + " /** first sentence in a comment should start with a capital letter */"; /** Valid multiline comment */ public void main() { } + + /** Valid multiline comment starts with two spaces + */ + public void mainTwo() { + } + } diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Invalid.java b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Invalid.java new file mode 100644 index 000000000..4e776fbbd --- /dev/null +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Invalid.java @@ -0,0 +1,23 @@ +package com.qulice.checkstyle.ChecksTest.ProhibitUnusedPrivateConstructorCheck; + +/* + * This is not a real Java class. It won't be compiled ever. It is used + * only as a text resource in integration.ChecksIT. + */ +public final class Invalid { + + private final String s; + + public Invalid(String s) { + this.s = s; + } + + private Invalid(int x) { + this(String.valueOf(x)); + } + + public static Invalid create() { + return new Invalid("0"); + } + +} \ No newline at end of file diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Valid.java b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Valid.java new file mode 100644 index 000000000..2943502be --- /dev/null +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/Valid.java @@ -0,0 +1,18 @@ +package com.qulice.checkstyle.ChecksTest.ProhibitUnusedPrivateConstructorCheck; +/* + * This is not a real Java class. It won't be compiled ever. It is used + * only as a text resource in integration.ChecksIT. + */ +public final class Valid { + + private final int i; + + public Valid(final String s) { + this(s.length()); + } + + private Valid(int i) { + this.i = i; + } + +} \ No newline at end of file diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/config.xml b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/config.xml new file mode 100644 index 000000000..35ff7fa56 --- /dev/null +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/config.xml @@ -0,0 +1,37 @@ + + + + + + + + diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/violations.txt b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/violations.txt new file mode 100644 index 000000000..a03db43b0 --- /dev/null +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ChecksTest/ProhibitUnusedPrivateConstructorCheck/violations.txt @@ -0,0 +1 @@ +15:Unused private constructor. \ No newline at end of file diff --git a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ValidSingleLineCommentCheck.java b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ValidSingleLineCommentCheck.java index 69d08abfb..3732c86c6 100644 --- a/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ValidSingleLineCommentCheck.java +++ b/qulice-checkstyle/src/test/resources/com/qulice/checkstyle/ValidSingleLineCommentCheck.java @@ -25,6 +25,8 @@ public final class ValidSingleLineCommentCheck { /** * Valid multi line literal. + * We need to add the @checkstyle ArrayTrailingCommaCheck to pass the test + * {@link com.qulice.checkstyle.CheckstyleValidatorTest#acceptsValidSingleLineComment} * @checkstyle ArrayTrailingCommaCheck (6 lines) */ public static final String[] MULTILINE_LITERAL = { diff --git a/qulice-maven-plugin/src/main/java/com/qulice/maven/CheckMojo.java b/qulice-maven-plugin/src/main/java/com/qulice/maven/CheckMojo.java index 1f227d12c..6edd804af 100644 --- a/qulice-maven-plugin/src/main/java/com/qulice/maven/CheckMojo.java +++ b/qulice-maven-plugin/src/main/java/com/qulice/maven/CheckMojo.java @@ -58,7 +58,8 @@ * @since 0.3 */ @Mojo(name = "check", defaultPhase = LifecyclePhase.VERIFY, - requiresDependencyResolution = ResolutionScope.TEST) + requiresDependencyResolution = ResolutionScope.TEST, + threadSafe = true) public final class CheckMojo extends AbstractQuliceMojo { /**