Giter Club home page Giter Club logo

pmd / pmd Goto Github PK

View Code? Open in Web Editor NEW
4.7K 4.7K 1.5K 464.88 MB

An extensible multilanguage static code analyzer.

Home Page: https://pmd.github.io

License: Other

Java 75.30% XSLT 0.77% CSS 0.01% JavaScript 0.17% HTML 0.29% C++ 0.01% Shell 0.54% PLSQL 0.95% Scala 0.08% Batchfile 0.07% TypeScript 0.01% ANTLR 2.83% Apex 9.92% Ruby 0.04% Kotlin 9.01% Modelica 0.01% C# 0.01%
apex code-analysis code-quality java linter plsql static-analysis static-code-analysis swift

pmd's Introduction

PMD - source code analyzer

PMD Logo

Join the chat Build Status Maven Central Reproducible Builds Coverage Status Codacy Badge Contributor Covenant Documentation (latest)

PMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth. It supports many languages. It can be extended with custom rules. It uses JavaCC and Antlr to parse source files into abstract syntax trees (AST) and runs rules against them to find violations. Rules can be written in Java or using a XPath query.

It supports Java, JavaScript, Salesforce.com Apex and Visualforce, Modelica, PLSQL, Apache Velocity, HTML, XML and XSL. Scala is supported, but there are currently no Scala rules available.

Additionally, it includes CPD, the copy-paste-detector. CPD finds duplicated code in C/C++, C#, Dart, Fortran, Gherkin, Go, Groovy, HTML, Java, JavaScript, JSP, Kotlin, Lua, Matlab, Modelica, Objective-C, Perl, PHP, PLSQL, Python, Ruby, Salesforce.com Apex and Visualforce, Scala, Swift, T-SQL, Apache Velocity, and XML.

In the future we hope to add support for data/control flow analysis and automatic (quick) fixes where it makes sense.

๐Ÿš€ Installation and Usage

Download the latest binary zip from the releases and extract it somewhere.

Execute bin/pmd check or bin\pmd.bat check.

See also Getting Started

Demo:

This shows how PMD analyses openjdk:

Demo

There are plugins for Maven and Gradle as well as for various IDEs. See Tools / Integrations

โ„น๏ธ How to get support?

๐Ÿค Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Our latest source of PMD can be found on GitHub. Fork us!

The rule designer is developed over at pmd/pmd-designer. Please see its README for developer documentation.

๐Ÿ’ต Financial Contributors

Become a financial contributor and help us sustain our community. Contribute

โœจ Contributors

This project follows the all-contributors specification. Contributions of any kind welcome!

See credits for the complete list.

๐Ÿ“ License

BSD Style

pmd's People

Contributors

aaronhurst-google avatar adangel avatar akshatbahety avatar borovikovd avatar djydewang avatar drofff avatar eklimo avatar gibarsin avatar gwilymatgearset avatar jbartolotta-sfdc avatar jeffhube avatar jonathanwiesel avatar josephallen avatar jsotuyod avatar kris-scheibe avatar lynnbroe avatar maikelsteneker avatar matthargett avatar oowekyala avatar piotrszymanski-sc avatar pmd-bot avatar prophet1906 avatar rpelisse avatar rsoesemann avatar scwells72 avatar sergeygorbaty avatar sturton avatar tprouvot avatar wener-tiobe avatar xenoamess avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pmd's Issues

Eclipse update-site and update-site-latest not working with eclipse.

Update site latest is not working in Eclipse Neon .2. There is no content.xml at https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site/

Error Message:

Unable to read repository at https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site-latest/content.xml.
Unable to read repository at https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site-latest/content.xml.
Received fatal alert: handshake_failure

[javascript] template strings are not correctly parsed

Rule Set: N/A

Description: ECMAScript 2015 (ES6) added support for template strings, delimited by backsticks (`). The current grammar does not support this properly, meaning template strings throw lexical errors.

Code Sample demonstrating the issue:

var markup = `<p>${content}</p>`;

Running PMD through: Any

[java] UselessParentheses: Parentheses in return statement are incorrectly reported as useless

Rule Set:
unnecessary.html#UselessParentheses

Code Sample demonstrating the issue:

These are incorrectly reported as useless parentheses:

return (mNumber != null ? mNumber.equals(team.mNumber) : team.mNumber == null)
        && (mKey != null ? mKey.equals(team.mKey) : team.mKey == null)
        && (mTemplateKey != null ? mTemplateKey.equals(team.mTemplateKey) : team.mTemplateKey == null)
        && (mName != null ? mName.equals(team.mName) : team.mName == null);

Removing them would result in nested ternary operations returning an incorrect boolean.

Running PMD through: Gradle

[core] RFC: Analyzing embedded snippets from other languages

Problem

Supported languages such as JSP (and unsupported languages such as PHP, VisualForce and Lightning) allow to embed snippets of code in supported languages such as JavaScript (and unsupported languages such as CSS).

However, the parser and rules applied per file are determined by file extension. That means, that given a project using a ruleset with both JS rules and JSP rules, inconsistent rule application can occur:

File test.jsp, jsp rules applied:

<script href="/test.js"></script> <!-- test.js will be parsed and analyzed by JS rules -->
<script> <!-- This snippet may contain whatever, no JS rules will ever check it -->
var test = "something";
</script>

Objective

Embedded code snippets should be parsed and analyzed the same way stand-alone files are.

Proposal

Each language parser should, upon detecting an embeded snippet, make sure to call a proper PMD helper with the snippet contents & detected language to use. Such helper will:

  1. Make sure the detected language is supported, showing a warning otherwise
  2. Synchronously start a new PMD analysis using the same ruleset on the contents of the snippet. This way the same rules are applied on the snippet that are applied to standalone files. The source file and line numbers should not be altered. It may be of use to allow the Context to know it's an embedded snippet.
  3. Resume parsing of the holder file as is.

By having this logic in the parser, it's enabled by default for all supported languages, and guaranteed to occur only once per file.

Difficulties

The holder languages tend to allow to mix the embedded snippets with expressions in the original language, such as:

<script>
var s = "<c:out val="${name}"/>";
</script>

These should probably be analyzed from the perspective of both languages.

Regarding the holder language, these expressions are of interest to be analyzed on their own (ie: don't allow unescaped values). They should probably be transformed into child nodes of the <script> tag in the AST which rules can visit and report on.

Regarding to the snippet, these expressions should be either removed or replaced with literals that won't change the syntax. This way, the embedded language will have no idea those values came from the holder language. This could be challenging, since the developer could use them anywhere, and we don't want these placeholders introducing false positives in the embedded language ruleset. For instance:

var s = "${stringVar}";
var i = ${intVar};

${methodNameSentFromController}();
${anotherVar}[4] = "test me";

What value could be passed as placeholder for all 4 alternatives? From a parsers' perspective, the only alternative I can think of valid in all 4 contexts is (function() {}). Where the last alternative would produce a runtime error, but the parser, and available rules will probably never notice.

These snippets are specific to each embedded language. This however means:

  1. The embedded language opts-in to being embedded, providing a placeholder factory.
  2. The holder language opts-in to parsing and analyzing embedded snippets by handling them properly in their parsers.

Also of note, since the embedded language has no idea that those are placeholders coming from a host language (as to not modify the parsers for the embedded languages), this means we can go as far as enforcing:

<script>
var userData = '{! JSENCODE(userData)}';
</script>

but not actually enforcing:

<script>
var userData = JSON.parse('{! JSENCODE(userData)}');
</script>

I'm not really happy with this, but can't think of a better way around it short of having he embedded language also know of the holder language and this means making changes to the parsers that will be hard to mantain and extend in the future.

@adangel @sgorbaty I'd love to listen to your feedback.

[core] shortnames option is broken with relative paths

Description:

When using the shortnames option with a relative file path, the report is broken.

For instance, using "../" as target dir, the report will produce paths such as:

ome/jmsotuyo/monits/pmd/./pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/complexity/StdCyclomaticComplexityRule.java

RuleContext.getSourceCodeFilename() and RuleContext.getSourceCodeFile() both return invalid paths, and in the case of the later, point to a non-existing file, making all features depending on it flaky.

Without the shortnames option, the path is properly generated:

/home/jmsotuyo/monits/pmd/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/complexity/StdCyclomaticComplexityRule.java

Running PMD through: Any

[java] AccessorMethodGeneration: Method inside static inner class incorrectly reported

Rule Set: design.html#AccessorMethodGeneration

Code Sample demonstrating the issue:

public static final Creator<Team> CREATOR = new Creator<Team>() {
    @Override
    public Team createFromParcel(Parcel source) {
        return new Team(source.readString(),
                        source.readString(),
                        source.readString(),
                        source.readString(),
                        source.readString(),
                        source.readString(),
                        getBooleanForInt(source.readInt()), // These are the offending lines
                        getBooleanForInt(source.readInt()), // same
                        getBooleanForInt(source.readInt()), // same
                        source.readLong());
    }

    @Override
    public Team[] newArray(int size) {
        return new Team[size];
    }

    private boolean getBooleanForInt(int value) {
        return value == 1;
    }
};

Running PMD through: Gradle

[java] Issue with PropertyDescriptor

Rule Set:

AvoidUsingHardCodedIP

Description:

I get the following error message when I try to configure the parameter violationSuppressRegex for the rule AvoidUsingHardCodedIP.

There is already a PropertyDescriptor with name 'violationSuppressRegex' defined on Rule AvoidUsingHardCodedIP.

Code Sample demonstrating the issue:

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         name="PMD Rules"
         xmlns="http://pmd.sf.net/ruleset/1.0.0"
         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
         xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>
        PMD rules for Play Framework.
    </description>

    <rule   name="AvoidUsingHardCodedIP"
            since="4.1"
            message="Do not hard code the IP address ${variableName}"
            class="net.sourceforge.pmd.lang.java.rule.basic.AvoidUsingHardCodedIPRule"
            externalInfoUrl="${pmd.website.baseurl}/rules/java/basic.html#AvoidUsingHardCodedIP">
        <description>
            <![CDATA[
Application with hard-coded IP addresses can become impossible to deploy in some cases.
Externalizing IP adresses is preferable.
	    	]]>
        </description>
        <priority>3</priority>
        <properties>
            <property name="pattern" type="String" description="Regular Expression" value='^"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"$'/>
            <property name="violationSuppressRegex" type="String" description="Suppress violations with messages matching a regular expression" value='^"127\.0\.0\.1"$'/>
        </properties>
        <example>
            <![CDATA[
public class Foo {
	private String ip = "15.45.35.12"; 	// not recommended
	private String ip = "127.0.0.1"; 	// allowed
}
	    ]]>
        </example>
    </rule>
</ruleset>

Running PMD through: CLI (v. 5.5.2)

D:\Users\thiba\Downloads\pmd-bin-5.5.2\bin\pmd.bat -format text -rulesets .gitlab-ci/pmd-ruleset.xml -dir app

[java] LoD false positive

Please, prefix the report title with the language it applies to within brackets, such as [java] or [apex]. If not specific to a language, you can use [core]

Rule Set: java-coupling/LawOfDemeter

Description:

LoD reports a false positive when method calls are placed between the var declaration and assignment.

Code Sample demonstrating the issue:

public class Foo {
    public void example() {
        String something;
        C c = new C();
        c.doIt();
        something = "no worries";
    }
}

Running PMD through: Any

Placeholder report for PR #266

[java] SingularField false positive with switch in method that both assigns and reads field

Affects PMD Version: 5.5.1...6.55.0

Rule: SingularField

Description:

I have the following JAX-RS event listener that uses a Prometheus Summary to measure the time of all non-404 responses. It violates the java/design/SingularField rule.

Code Sample demonstrating the issue:

// package, imports

@Provider
public class LatencyRequestEventListener implements RequestEventListener {
    private static final Summary SUMMARY_LATENCY_SECONDS = โ€ฆ;

    private final ResourceInfo resourceInfo;

    private Summary.Timer timer; // BREAKS HERE

    LatencyRequestEventListener(final ResourceInfo resourceInfo) {
        this.resourceInfo = resourceInfo;
    }

    @Override
    public void onEvent(final RequestEvent event) {
        switch (event.getType()) {
            case RESOURCE_METHOD_START:
                final ResourceMethod matchedResourceMethod = event.getUriInfo().getMatchedResourceMethod();

                if (matchedResourceMethod == null) {
                    return;
                }

                timer = SUMMARY_LATENCY_SECONDS // ASSIGN FIELD
                    .labels(
                        matchedResourceMethod.getHttpMethod()
                        , resourceInfo.getResourceClass().getSimpleName() + "." + resourceInfo.getResourceMethod().getName()
                    )
                    .startTimer();
                break; // Don't keep going (both cases cannot be reached in the same call)
            case FINISHED:
                if (timer != null) {
                    timer.observeDuration(); // READ FIELD
                }
        }
    }
}

Expected outcome:

PMD reports a violation at line 25, but that's wrong. That's a false positive.

This results in the following error:

/path/to/project/โ€ฆ/listeners/LatencyRequestEventListener.java:25: Perhaps 'timer' could be replaced by a local variable.

timer can't be a local variable, so I don't think it's correct to report this rule violated.

I understand that the rule is violated if a field is only accessed by a single method. I also acknowledge that having the same method be called twice to first assign a field (the RESOURCE_METHOD_START case) and then read the field (FINISHED) may not be a good design. However, that's how the JAX-RS people designed the RequestEventListener class.

If I pull the code for the RESOURCE_METHOD_START case into a separate method, it passes with no problem since multiple methods access the field.

Is this a bug, or am I doing something wrong?

EDIT: As a funky side note, pulling the configuration of the Timer into a method makes the code legal, despite still only referencing the timer field in onEvent(โ€ฆ):

private static Summary.Child configureTimer(
    final Summary summary,
    final String httpMethod
    , final String handlerName
) {
    return summary
        .labels(httpMethod, handlerName);
}

@Override
public void onEvent(final RequestEvent event) {
    switch (event.getType()) {
        case RESOURCE_METHOD_START:
            final ResourceMethod matchedResourceMethod = event.getUriInfo().getMatchedResourceMethod();
            if (matchedResourceMethod != null) {
                timer = configureTimer(
                    SUMMARY_LATENCY_SECONDS,
                    matchedResourceMethod.getHttpMethod()
                    , resourceInfo.getResourceClass().getSimpleName() + "." + resourceInfo.getResourceMethod().getName()
                ).startTimer();
            }
            break;
        case FINISHED:
            if (timer != null) {
                timer.observeDuration();
            }
    }
}

[Apex] CDP Gui doesn't display Apex as supported language (and won't run on it)

I downloaded the latest PMD bin 5.4.1 and ran the CPD Gui from my Mac OS command line.
I tried to check some Apex classes *.cls files but failed as the extension is not show in the pull down. It also didn't work with the option to enter a custom extension.

bildschirmfoto 2017-01-10 um 14 18 40

When I compare the Apex CDP files at
https://github.com/pmd/pmd/tree/master/pmd-apex/src/main/java/net/sourceforge/pmd/cpd
with other languages everything looks fine and enabled.

FYI: @adangel

[java] UnusedModifier doesn't check annotations inner classes

Rule Set: unused/UnusedModifier

Description:
Nested classes in annotations are public static by default, no other modifiers are allowed. Explicitly setting them matches this rule's criteria:

For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.

The same applies to inner interfaces and annotations on annotations, which are public by default.

Code Sample demonstrating the issue:

public @interface Test {
  public static Inner { }
  public interface Interface { }
  public @interface InnerAnnotation { }
}

PMD will find no violations on this annotation, 4 violations are expected.

Running PMD through: Any

Relate to #246

[apex]ย NCSS Method length is incorrect when using method chaining

If you analyze the following source code with the NcssMethodCountRule

https://github.com/pmd/pmd/blob/master/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/complexity/NcssMethodCountRule.java

@isTest
private class AcceptanceTests_Test {
    
    @isTest
    private static void test() {  

        // Setup
        Opportunity o1 = new Opportunity()
                                    .add(new Contact().foo(1)  .bar(1).year(2012)  .bar(1).price(5)  .vol(100))
                                    .add(new Contact().foo(1)  .bar(2).year(2013)  .bar(1).price(5)  .vol(110))
                                    .add(new Contact().foo(1)  .bar(3).year(2014)  .bar(1).price(5)  .vol(120))
                                    .add(new Contact().foo(1)  .bar(4).year(2015)  .bar(1).price(5)  .vol(130))
                                    .persist();

        Opportunity o2 = new Opportunity()
                                    .add(new Contact().foo(1)  .PRS(1).year(2012)  .bar(1).price(5)  .vol(110))
                                    .add(new Contact().foo(1)  .PRS(2).year(2013)  .bar(1).price(5)  .vol(120))
                                    .add(new Contact().foo(1)  .PRS(3).year(2014)  .bar(1).price(5)  .vol(130))
                                    .add(new Contact().foo(1)  .PRS(4).year(2015)  .bar(1).price(5)  .vol(140))
                                    .persist();

        Opportunity o3 = new Opportunity()
                                    .add(new Contact().foo(1)  .PRS(1).year(2012)  .bar(1).price(5)  .vol(110))
                                    .add(new Contact().foo(1)  .PRS(2).year(2013)  .bar(1).price(5)  .vol(120))
                                    .add(new Contact().foo(1)  .PRS(3).year(2014)  .bar(1).price(5)  .vol(130))
                                    .add(new Contact().foo(1)  .PRS(4).year(2015)  .bar(1).price(5)  .vol(140))
                                    .persist();
        

        // Exercise     
        callMethod();
       

        // Verify
        System.assert(attribute());
    }
}

the test method marked as issue with over 80 NCSS. Actually it is less than 30. The method chaining in // Setup seems to confuse the PMD line detection.
cursor_und_adm_acceptancetests_test_cls_at_master_ _up2go_adm

[core] Remove duplicate code between PMD Processors and PMDRunnable

Currently MonoThreadProcessor and MultiThreadProcessor + PmdRunnable do pretty much the same, and in doing so, they are repeating a lot of code with even some slight inconsistencies.

For instance, MonoThreadProcessor calls rs.start(ctx); for the rulesets once per file. MultiThreadProcessor on the other hand, does so only once, and not even on the RuleSets instance being used (this means both GenericClassCounterRule and CommentContentRule are broken unless run with -threads 0).

We can't kill MonoThreadProcessor (it's used from ant by default, and not launching threads has advantages for tasks such as profiling / benchmarking), but those classes could certainly share more code to provide a more concise implementation. For instance, ee could probably pull all logic up to AbstractPMDProcessor and just let as extension point the strategy for running a given PmdRunnable (with the MonoThreadProcessor simply doing call()). This would require creating a new PmdRunnable per file even on mono thread AND we would probably have to get rid of PmdThread (or at least make sure PmdRunnable doesn't depend on it), but is the cleanest alternative I've come up with so far.

[java] UnusedModifier doesn't check annotations

Rule Set: unused/UnusedModifier

Description:
Annotation elements are public abstract by default, no other modifiers are allowed. Explicitly setting them matches this rule's criteria:

For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.

The same applies to fields on annotations, which are public static final by default.

Code Sample demonstrating the issue:

public @interface Test {
  public static final String DEFAULT_MESSAGE = "message";
  public abstract String message() default DEFAULT_MESSAGE;
}

PMD will find no violations on this annotation, 5 violations are expected.

Running PMD through: Any

P.S. This class should probably go to the unnecessary ruleset rather the unused one... even the unit tests' description usually start with "Unnecessary ..."

[core] How to wrap CPD as a rule

This is more a discussion item that an issue, but I post it here to mention the experts (e.g. @adangel @jsotuyod ) to get some feedback.

I am the creator of the Apex language module and of ApexMetrics which wraps PMD and makes it available to the Code Climate platform for code analysis. PMD and CodeClimate are a perfect match as both work on a per file basis and know the concept of issues of a certain severity.

Besides PMD I am a heavy user of the Copy Paste Detector that is part of PMD. But only as a local standalone tool. I would like to create a CopyPasteRule instead and wonder if that is doable?

As nobody has done it in the last 10 years I fear its just not doable because of tthe way PMD works. I mean Visitor pattern, issues checked per file.

What do you think?

[java] UnnecessaryLocalBeforeReturn: ClassCastException in switch case with local variable returned

Please, prefix the report title with the language it applies to within brackets, such as [java] or [apex]. If not specific to a language, you can use [core]

Rule Set:
UnnecessaryLocalBeforeReturn

Description:

java.lang.ClassCastException: net.sourceforge.pmd.lang.java.ast.ASTSwitchStatement cannot be cast to net.sourceforge.pmd.lang.java.ast.ASTBlock
        at net.sourceforge.pmd.lang.java.rule.design.UnnecessaryLocalBeforeReturnRule.hasAssertStatement(UnnecessaryLocalBeforeReturnRule.java:101)
        at net.sourceforge.pmd.lang.java.rule.design.UnnecessaryLocalBeforeReturnRule.visit(UnnecessaryLocalBeforeReturnRule.java:52)

Code Sample demonstrating the issue:

    public static int m() {
        switch (0) {
            default:
                int i = 0;
                return i;
        }
    }

Running PMD through: Gradle

[java] UnusedModifier doesn't check static keyword on nested enum declaration

Rule Set: unused/UnusedModifier

Description:
Enums are static by default. Explicitly setting them matches this rule's criteria:

For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.

Code Sample demonstrating the issue:

public @interface Test {
  public static enum EnumSample {
    TEST;
  }
}

PMD will find no violations on this annotation, 1 violation is expected.

The behavior is consistent when nested in classes, annotations and interfaces.

Running PMD through: Any

[core] How to specify custom path variable and access the value in any rule?

Rule Set:
PMD-JAVA

Description:
I need to be able to customize some values in some rules ( new rules I am working on) using a configuration file, how can I have the file path as command line parameter in run.sh script and then access the value in Java rules.

Sample run command:

./run.sh pmd -d path/to/project -f textcolor -R rulesets/java/design.xml 

I want to achieve something like being able to specify:

./run.sh pmd -d path/to/project -f textcolor -R rulesets/java/design.xml -customization /path/to/file

And get the value of the -customization parameter in one of the rules.

How would you guys recommend me to do it? I need to avoid recompilation of PMD for each configuration change, so I need to access the content of the files at run time. Would appreciate the help! Thanks a lot.

Running PMD through: [CLI]

[java] SingularField with lambdas as final fields

Students of mine are using PMD to check their code for style errors, and are getting a false positive on the SingularField checker when the field is used inside a lambda expression. Iโ€™ve found https://sourceforge.net/p/pmd/bugs/1307/ online, which appears to be closed and resolved a year ago, but the code below is still problematic.

Iโ€™ve narrowed the problem down to a tiny reproduction. I am using PMD 5.5.1 in class, though Iโ€™ve tested the example below with PMD 5.5.2 as well. The code below triggers a SingularField error for timer1, but not for timer2:

/** Dummy class. */
public final class Test {
  private Timer timer1;
  private Timer timer2;

  /** Dummy constructor. */
  public Timer() {
    this.timer1 = new Timer(0, e -> {
      // do nothing for now
    });
    this.timer2 = new Timer(0, e -> {
      // do nothing for now
    });
  }

  /** Use a lambda expression to reference timer1 -- triggers SingularField error. */
  private final Runnable play1 = () -> {
    this.timer1.start();
  };

  /** Use an anonymous class to reference timer2 -- no error. */
  private final Runnable play2 = new Runnable() {
    @Override
    public void run() {
      this.timer2.start();
    }
  };
}

It seems that PMD isnโ€™t recognizing the lambda syntax properly. I tried being more explicit and saying Test.this.timer1 to make it really clear that Iโ€™m accessing a field, Iโ€™ve tried eliminating the this. before timer1, and Iโ€™ve tried changing the finality and visibility of the play1 lambda; none of them affected the error.

[java] [doc] ConsecutiveAppendsShouldReuse is it really an optimization?

Rule Set:
ConsecutiveAppendsShouldReuse

Description:
This is presented as a performance optimization. This is wrong, it doesn't really optimize anything and it's a waste of time to "fix". And if someone's code is more readable without it, they should avoid the "fix".
The description is misleading.

Code Sample demonstrating the issue:
Not relevant.

Running PMD through: [CLI | Ant | Maven | Gradle | Designer | Other]
Doesn't matter.

[java] New Rule: UnnecessaryLocal

Rule Set: probably java-unnecessary

Description:
See discussion in #221:

this rule could be expanded to all "unnecessary" variables, not just return statements. We could add a property to allow such variables if declared as final. The Java code will produce an extra store / load instruction in bytecode, but being final, the JIT will remove them and effectively be the same for long running processes.

Also deprecate the rule UnnecessaryLocalBeforeReturn

We should think about the following problem: if the whole java-design ruleset is active, and we have both rules UnnecessaryLocalBeforeReturn and the new UnnecessaryLocal, they might report the same issues...

[java] RedundantFieldInitializer report for annotation field not explicitly marked as final

Rule Set: optimizations.html#RedundantFieldInitializer

Description: PMD incorrectly reports a redundant field initializer for final fields in an interface.

Code Sample demonstrating the issue:

@IntDef({MetricType.CHECKBOX, MetricType.COUNTER, MetricType.SPINNER, MetricType.NOTE})
@Retention(RetentionPolicy.SOURCE)
public @interface MetricType {
    int CHECKBOX = 0; // <<<<<<<< incorrectly reported as a redundant field initializer
    int COUNTER = 1;
    int SPINNER = 2;
    int NOTE = 3;
}

Running PMD through: Gradle

[java] SimplifiedTernary: Incorrect ternary operation can be simplified.

Rule Set: basic.html#SimplifiedTernary

Description: I have a special case where to save money in my database, I return null if a boolean value is false in a method of return type Boolean.

Code Sample demonstrating the issue:

@Nullable
public Boolean getHasCustomName() {
    return mHasCustomName ? true : null; // From my understanding of Java, this cannot be simplified.
}

Running PMD through: Gradle

[plsql] Ampersand '&' causes PMD processing error in sql file - Lexical error in file

When using PMD for [PLSQL] I am getting a Lexical error when parsing files with &.

Rule Set:

  • n/a - not a rule but in the lexical analysis.

Description:
It seems to be caused by the ampersand, since if I remove it, the script is processed without issues.
I do, however need the ampersand for variable inclusion.

Several places on oracle.com this is being used:
https://blogs.oracle.com/opal/entry/sqlplus_101_substitution_varia#9_4

Code Sample demonstrating the issue:

--both define and spool are SQL*Plus commands, and they should not be ended with a semi-colon.
define patch_name = acme_module
spool &patch_name..log

Running PMD through:
CLI

Using this command

    pmd -V -d spool_sub.sql -f html -R ruleset.xml

Gives this error

Counting for net.sourceforge.pmd.lang.plsql.ast.ExecutableCode
Counting for net.sourceforge.pmd.lang.plsql.ast.OracleObject
Loaded rule NcssObjectCount
Loaded rule NcssMethodCount
Loaded rule TooManyFields
Loaded rule ExcessivePackageSpecificationLength
Loaded rule NPathComplexity
Loaded rule TooManyMethods
Loaded rule CyclomaticComplexity
Loaded rule ExcessiveTypeLength
Loaded rule ExcessiveParameterList
Loaded rule ExcessiveObjectLength
Loaded rule ExcessiveMethodLength
Using PLSQL version: PLSQL
Counting for net.sourceforge.pmd.lang.plsql.ast.ExecutableCode
Counting for net.sourceforge.pmd.lang.plsql.ast.OracleObject
Loaded rule CyclomaticComplexity
Loaded rule NPathComplexity
Loaded rule ExcessiveParameterList
Loaded rule TooManyMethods
Loaded rule ExcessiveObjectLength
Loaded rule ExcessiveMethodLength
Loaded rule NcssMethodCount
Loaded rule ExcessivePackageSpecificationLength
Loaded rule NcssObjectCount
Loaded rule TooManyFields
Loaded rule ExcessiveTypeLength
Counting for net.sourceforge.pmd.lang.plsql.ast.ExecutableCode
Counting for net.sourceforge.pmd.lang.plsql.ast.OracleObject
Processing C:\db\spool_sub.sql
Error while processing file: C:\db\spool_sub.sql
about:blank
net.sourceforge.pmd.lang.ast.TokenMgrError: Lexical error in C:\db\spool_sub.sql at line 3, column 7.  Encountered: "&" (38), after : ""
	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParserTokenManager.getNextToken(PLSQLParserTokenManager.java:4459)
	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.jj_consume_token(PLSQLParser.java:39778)
	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.SqlPlusCommand(PLSQLParser.java:384)
	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.Input(PLSQLParser.java:198)
	at net.sourceforge.pmd.lang.plsql.PLSQLParser.parse(PLSQLParser.java:47)
	at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:91)
	at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:138)
	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:76)
	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:43)
	at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
	at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:25)
	at java.util.concurrent.FutureTask.run(FutureTask.java:262)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:745)

<html><head><title>PMD</title></head><body>
<center><h3>PMD report</h3></center><center><h3>Problems found</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>#</th><th>File</th><th>Line</th><th>Problem</th></tr>
</table><hr/><center><h3>Processing errors</h3></center><table align="center" cellspacing="0" cellpadding="3"><tr>
<th>File</th><th>Problem</th></tr>
<tr bgcolor="lightgrey"> 
<td>C:\db\spool_sub.sql</td>
<td>Error while processing C:\db\spool_sub.sql</td>
</tr>
</table></body></html>

Add topics to PMD's github project

Recently GitHub released a new features called topics, which are basically tags.

We should add tags to help discovery / search. My suggested topics:

  • code-analysis
  • code-quality
  • static-analysis
  • static-code-analysis
  • linter
  • java
  • apex
  • plsql
  • swift

Feel free to suggest more!

[JAVA] XPath rules don't catch error cases found in Designer.

I'm trying to build a custom rule to detect if specific variables declared as PropertyKey are always declared as public static final. I am using version 5.5.2, following the tutorial, used the designer to create the XPath rules, and verified they are correct on real code. But when running through Gradle on the whole project, PMD doesn't flag the errors.

The rule as written:

    <rule name="PropertyKeys must be public static final"
          message="ProperyKey definition must be public static final"
          class="net.sourceforge.pmd.lang.rule.XPathRule"
          language="java">
        <description>
            PropertyKey definition must be public static final
        </description>
        <priority>3</priority>
        <properties>
            <property name="xpath">
                <value>
        //FieldDeclaration[./Type/ReferenceType/ClassOrInterfaceType[typeof(@Image, 'mme.foundation.properties', 'PropertyKey')] and
        (@Static='false' or @Final='false' or @Public='false') ]
                </value>
            </property>
        </properties>
    </rule>

And an example failure case not found:

package foo;

import mme.foundation.PropertyDefs;
import mme.foundation.properties.PropertyKey;

    @ProviderFor(PropertyDefs.class)
    public static class EndpointProps extends PropertyDefs {
        private static final PropertyKey<Map<String, String>> ServiceKey =
                PropertyKey.Map(
                        "KeyName",
                        ImmutableMap.of(
                                "endpoint/key", "endpoint/value"));
    }

Running PMD through: [CLI | Ant | Maven | Gradle | Designer | Other]
Gradle

[java] Parse error with local class with 2 or more annotations

Hello guys,

I found another issue when analyzing open-source project 'spring' (https://github.com/spring-projects/spring-framework). Can you please take a look?

NOTE: The problems seems to be the custom annotation @Configuration, after its removal the analyzer does not complain.

PMD version:
5.5.2

Rule Set:
java-basic

Description:

Error while processing file: spring-framework\spring-context\src\test\java\org\springframework\context\annotation\configuration\BeanAnnotationAttributePropagationTests.java
net.sourceforge.pmd.lang.java.ast.ParseException: Encountered "" at line 121, column 17.
Was expecting one of:

        at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:10875)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:10759)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.BlockStatement(JavaParser.java:4629)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.Block(JavaParser.java:4575)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.MethodDeclaration(JavaParser.java:1554)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBodyDeclaration(JavaParser.java:1246)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1162)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:586)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:476)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:222)
        at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:56)
        at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:95)
        at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:142)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:80)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:47)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:79)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:25)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Code Sample demonstrating the issue:

	@Test
	public void defaultLazyConfigurationPropagatesToIndividualBeans() {
		@Lazy @Configuration class Config {
			@Bean Object foo() { return null; }
		}

		assertTrue("@Bean methods declared in a @Lazy @Configuration should be lazily instantiated",
				beanDef(Config.class).isLazyInit());
	}

Running PMD through: [CLI]

java -cp * net.sourceforge.pmd.PMD -d "spring-framework\spring-web-reactive\src\main\java\org\springframewor
k\web\reactive\function" -f text -R java-basic -verbose

[apex] Add Braces Rule Set

Can you make me the assignee of this issue? I see so many Apex devs not using braces in for loops and other block types. It makes me shiver.

Issue while downloading pmd-plugin from Eclipse Mars(4.5.2)

I get the following exception:

[Unable to read repository at https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site/site.xml.
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]

[core] Zip file stream closes spuriously when loading rulesets

Description:

We get spurious IOExceptions when running pmd in our CI servers. This happens on PMD 5.5.1 and 5.5.2, but not on 5.5.0. We cannot use 5.5.3 right now because of a different issue, so status there is unknown. More information can be provided on request, because I don't know what more to provide.

[10:43:07][Running build...] java.io.IOException: Stream closed
[10:43:07][Running build...] 	at java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67)
[10:43:07][Running build...] 	at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:142)
[10:43:07][Running build...] 	at java.io.FilterInputStream.read(FilterInputStream.java:133)
[10:43:07][Running build...] 	at java.io.FilterInputStream.read(FilterInputStream.java:107)
[10:43:07][Running build...] 	at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1792)
[10:43:07][Running build...] 	at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
[10:43:07][Running build...] 	at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744)
[10:43:07][Running build...] 	at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:462)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactoryCompatibility.filterRuleSetFile(RuleSetFactoryCompatibility.java:84)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetNode(RuleSetFactory.java:249)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:202)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:197)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetReferenceNode(RuleSetFactory.java:359)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleNode(RuleSetFactory.java:317)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetNode(RuleSetFactory.java:272)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:202)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:197)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSets(RuleSetFactory.java:161)
[10:43:07][Running build...] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSets(RuleSetFactory.java:145)
[10:43:07][Running build...] 	at net.sourceforge.pmd.ant.internal.PMDTaskImpl.doTask(PMDTaskImpl.java:119)
[10:43:07][Running build...] 	at net.sourceforge.pmd.ant.internal.PMDTaskImpl.execute(PMDTaskImpl.java:269)
[10:43:07][Running build...] 	at net.sourceforge.pmd.ant.PMDTask.execute(PMDTask.java:47)
[10:43:07][Running build...] 	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
[10:43:07][Running build...] 	at sun.reflect.GeneratedMethodAccessor1039.invoke(Unknown Source)
[10:43:07][Running build...] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[10:43:07][Running build...] 	at java.lang.reflect.Method.invoke(Method.java:498)
[10:43:07][Running build...] 	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[10:43:07][Running build...] 	at groovy.util.AntBuilder.performTask(AntBuilder.java:327)
[10:43:07][Running build...] 	at groovy.util.AntBuilder.nodeCompleted(AntBuilder.java:272)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.ant.BasicAntBuilder.nodeCompleted(BasicAntBuilder.java:78)
[10:43:07][Running build...] 	at sun.reflect.GeneratedMethodAccessor927.invoke(Unknown Source)
[10:43:07][Running build...] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[10:43:07][Running build...] 	at java.lang.reflect.Method.invoke(Method.java:498)
[10:43:07][Running build...] 	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
[10:43:07][Running build...] 	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
[10:43:07][Running build...] 	at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:382)
[10:43:07][Running build...] 	at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:170)
[10:43:07][Running build...] 	at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:163)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.antbuilder.AntBuilderDelegate.nodeCompleted(AntBuilderDelegate.java:118)
[10:43:07][Running build...] 	at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:154)
[10:43:07][Running build...] 	at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
[10:43:07][Running build...] 	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
[10:43:07][Running build...] 	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
[10:43:07][Running build...] 	at org.gradle.api.plugins.quality.internal.PmdInvoker$_invoke_closure2.doCall(PmdInvoker.groovy:62)
[10:43:07][Running build...] 	at sun.reflect.GeneratedMethodAccessor1103.invoke(Unknown Source)
[10:43:07][Running build...] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[10:43:07][Running build...] 	at java.lang.reflect.Method.invoke(Method.java:498)
[10:43:07][Running build...] 	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
[10:43:07][Running build...] 	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
[10:43:07][Running build...] 	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
[10:43:07][Running build...] 	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
[10:43:07][Running build...] 	at groovy.lang.Closure.call(Closure.java:414)
[10:43:07][Running build...] 	at groovy.lang.Closure.call(Closure.java:430)
[10:43:07][Running build...] 	at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:70)
[10:43:07][Running build...] 	at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:52)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder$2.execute(DefaultIsolatedAntBuilder.java:151)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder$2.execute(DefaultIsolatedAntBuilder.java:133)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.antbuilder.ClassPathToClassLoaderCache.withCachedClassLoader(ClassPathToClassLoaderCache.java:134)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder.execute(DefaultIsolatedAntBuilder.java:127)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.IsolatedAntBuilder$execute$0.call(Unknown Source)
[10:43:07][Running build...] 	at org.gradle.api.plugins.quality.internal.PmdInvoker.invoke(PmdInvoker.groovy:60)
[10:43:07][Running build...] :libs:assertion:pmd FAILED
[10:43:07][Running build...] 	at org.gradle.api.plugins.quality.Pmd.run(Pmd.java:98)
[10:43:07][Running build...] 	at sun.reflect.GeneratedMethodAccessor1101.invoke(Unknown Source)
[10:43:07][Running build...] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[10:43:07][Running build...] 	at java.lang.reflect.Method.invoke(Method.java:498)
[10:43:07][Running build...] 	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:141)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
[10:43:07][Running build...] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:123)
[10:43:07][Running build...] 	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:632)
[10:43:07][Running build...] 	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:615)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:95)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:76)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
[10:43:07][Running build...] 	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)
[10:43:07][Running build...] 	at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
[10:43:07][Running build...] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
[10:43:07][Running build...] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
[10:43:07][Running build...] :libs:assertion:pmdPublish
[10:43:07][Running build...] 	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
[10:43:07][Running build...] 	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
[10:43:07][Running build...] 	at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
[10:43:07][Running build...] 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[10:43:07][Running build...] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[10:43:07][Running build...] 	at java.lang.Thread.run(Thread.java:745)

Running PMD through: Gradle

[apex] Make Rule suppression work

We need a way to suppress rules in certain situations in Apex code as we do in Java. In Java thats easy because Java allows PMD to add own annotations like @SuppressWarnings("PMD").

There is no way to do that in Apex. Maybe someone comes up with an idea what we could use instead. Maybe comments?

@sergeygorbaty What do you think?

[java] Parse error on annotation fields with generics

Hello guys,

I found an issue when analyzing open-source project 'caffeine' (https://github.com/ben-manes/caffeine). Can you please take a look?

PMD version:
5.5.2

Rule Set:
java-basic

Description:

Error while processing file: caffeine\src\test\java\com\github\benmanes\caffeine\cache\testing\CacheSpec.java
net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "=" "= "" at line 360, column 56.
Was expecting:
    "(" ...

        at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:10875)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:10759)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AnnotationMethodDeclaration(JavaParser.java:6396)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AnnotationTypeMemberDeclaration(JavaParser.java:6318)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AnnotationTypeBody(JavaParser.java:6259)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AnnotationTypeDeclaration(JavaParser.java:6194)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:482)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:222)
        at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:56)
        at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:95)
        at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:142)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:80)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:47)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:79)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:25)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Code Sample demonstrating the issue:

public @interface CacheSpec {
  // FIXME: A hack to allow the NEGATIVE loader's return value to be retained on refresh
  static final ThreadLocal<Interner<Integer>> interner =
      ThreadLocal.withInitial(Interners::newStrongInterner);
}

Running PMD through: [CLI]

java -cp * net.sourceforge.pmd.PMD -d "...caffeine\caffeine\src\test\java\com\github\benmanes\caffeine\cache\testing" -f text -R java-basic -verbose

[java] UnusedLocalVariable false positive

Rule Set:
UnusedLocalVariable

Description:
When one of the variables is enclosed in (unnecessary) parentheses, it triggers a false positive. In the example below, the variable a gets flagged as an UnusedLocalVariable (but the variable b does not).

Code Sample demonstrating the issue:

public class Test {
ย  ย  public static void main(String[] args) {
ย  ย  ย  ย  double a = 4.0;ย 
ย  ย  ย  ย  double b = 2.0;ย 
ย  ย  ย  ย  double result = Math.sqrt((a) - b);
ย  ย  ย  ย  System.out.println(result);
ย  ย  }
}

**Running PMD 5.5.2 through: CLI

[java] CPD runs into NPE when analyzing Lucene

I use pmd-4.2.6.jar to detect clones with "net.sourceforge.pmd.cpd.GUI" (java -Xmx4g -XX:-UseGCOverheadLimit -cp pmd-4.2.6.jar net.sourceforge.pmd.cpd.GUI). To this version, I run with parameters -Xmx4g -XX:-UseGCOverheadLimit (I use Linux 64bits with 28GB of RAM). To detect clones I use "Ignore Literals and Identifiers=true" and "Scan subdiretories=true". This version is OK.

Today, I updated to latest version PMD-5.5.2 (5th November 2016). I runned this version with script "run.sh" (./run.sh cpdgui) in folder "bind". However this version show some erros:

Error 1: When the flag "Ignore identifiers" is true, the tool show the follow message:
java.lang.NullPointerException
at net.sourceforge.pmd.cpd.JavaTokenizer$ConstructorDetector.processToken(JavaTokenizer.java:235)
at net.sourceforge.pmd.cpd.JavaTokenizer.processToken(JavaTokenizer.java:76)
at net.sourceforge.pmd.cpd.JavaTokenizer.tokenize(JavaTokenizer.java:54)
at net.sourceforge.pmd.cpd.CPD.addAndThrowLexicalError(CPD.java:143)
at net.sourceforge.pmd.cpd.CPD.add(CPD.java:138)
at net.sourceforge.pmd.cpd.CPD.add(CPD.java:103)
at net.sourceforge.pmd.cpd.CPD.add(CPD.java:67)
at net.sourceforge.pmd.cpd.CPD.addDirectory(CPD.java:77)
at net.sourceforge.pmd.cpd.CPD.addRecursively(CPD.java:62)
at net.sourceforge.pmd.cpd.GUI.go(GUI.java:624)
at net.sourceforge.pmd.cpd.GUI.access$500(GUI.java:70)
at net.sourceforge.pmd.cpd.GUI$GoListener$1.run(GUI.java:198)
at java.lang.Thread.run(Unknown Source)

Error 2: Quando o sinalizador "Ignorar identificadores" for FALSE, "Ignorar literais" รฉ VERDADEIRO e "Ignorar Anotaรงรตes" รฉ VERDADEIRO, a ferramenta mostrar a seguinte mensagem:
Exception in thread "Thread-1" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at net.sourceforge.pmd.cpd.SourceCode.getSlice(SourceCode.java:173)
at net.sourceforge.pmd.cpd.MatchAlgorithm.findMatches(MatchAlgorithm.java:83)
at net.sourceforge.pmd.cpd.CPD.go(CPD.java:50)
at net.sourceforge.pmd.cpd.GUI.go(GUI.java:631)
at net.sourceforge.pmd.cpd.GUI.access$500(GUI.java:70)
at net.sourceforge.pmd.cpd.GUI$GoListener$1.run(GUI.java:198)
at java.lang.Thread.run(Unknown Source)

To try fix this last error, I also runned the version 5.5.2 with this parameters: "-Xmx4g -XX:-UseGCOverheadLimit", "-Xmx6g -XX:-UseGCOverheadLimit". But this not works.

In all executions, I used "Scan Subdirectories=TRUE" and "Duplicate chunks=75" and "File Encoding=UTF-8".

My Java version:
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

The source code that I analysed is Lucene (http://lucene.apache.org/solr/)

[core] Render config errors

Report.configErrors() stores configuration errors for rules, but those are not used in any renderer.

We should start rendering these, exposing all errors to the user. This feature would be a good place to start registering missing classes during analysis, as discussed here

Checklist:

  • Add config errors to renderers
  • #3914
    • Add missing classes as config errors
    • in type resolution in general
    • in MissingOverrideRule (see #1267)
  • Review no phony missing classes are reported (specially regarding generics)
    • WIP: Found and fixed a couple of scenarios. See #225 and #226. I still see a few generics references we shouldn't.
  • Avoid duplicate dysfunctional rules report
    • Make RuleSets deep-copyable

[java] CPD: OutOfMemory when analyzing Lucene

see original ticket #185

jsotuyod commented 9 days ago

As for the OOM, the problem is the sheer number of duplicate code violations being found on
Lucene's source code when using ignore literals.

With 6GB of Heap Space, current PMD versions are able to find over 37500 instances of duplicate
code of length 75+.

Even after doing some things to improve allocations / GC, this is simply too much to keep in memory.
We will have to refactor our grouping stage code to report and discard matches on to go, rather than
passing them all at once.


Related Pull request: #198


jsotuyod commented 9 days ago โ€ข edited

I did some improvements to the codebase, and CPD is now able to analyze the lucene source code
given a sufficiently large heap (~7-8G) even when using --ignore-literals.

Bare in mind that --ignore-literals may not be the best option when analyzing Lucene. The source
code has plenty of large arrays of strings (words in different languages), which to CPD are just a
sequence of N string literals, and being ignored, duplicate code to be removed; and is therefore
currently producing a plain text report of over 800MB (much larger as XML). Such arrays should
probably either be ignored by CPD (see CPD Suppression), or moved out of the Java code into
resource files loaded at runtime.

Still a complete rewrite of the CPD renderers is needed. Rendering to a String in memory is
unsustainable. Once that's done the needed memory for analysis will drop dramatically.

[apex] False Positives on ApexXSSFromURLParamRule

FYI: @sergeygorbaty

Rule:

ApexXSSFromURLParamRule

Description:
This rule even seems to apply in cases where NO data is taken from the URL. Instead I construct a URL in my code. Eighter the detection is wrong or the error message.

Code Sample demonstrating the issue:

cprm-pm_saveastemplatectrl_cls_at_master_ _up2go_cprm-pm

Running PMD through: [CLI | Ant | Maven | Gradle | Designer | Other]
CodeClimate engine ApexMetrics

[java] NPE - Inflater has been closed when running PMD

The build fails randomly with PMD exception, see below

Description:
Exception

[pmd] :scripts:pmdTestjava.lang.NullPointerException: Inflater has been closed
[pmd] 	at java.util.zip.Inflater.ensureOpen(Inflater.java:389)
[pmd] 	at java.util.zip.Inflater.inflate(Inflater.java:257)
[pmd] 	at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:152)
[pmd] 	at java.io.FilterInputStream.read(FilterInputStream.java:133)
[pmd] 	at java.io.FilterInputStream.read(FilterInputStream.java:107)
[pmd] 	at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1792)
[pmd] 	at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
[pmd] 	at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744)
[pmd] 	at org.apache.commons.io.IOUtils.toByteArray(IOUtils.java:462)
[pmd] 	at net.sourceforge.pmd.RuleSetFactoryCompatibility.filterRuleSetFile(RuleSetFactoryCompatibility.java:84)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetNode(RuleSetFactory.java:249)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:202)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:197)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetReferenceNode(RuleSetFactory.java:359)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleNode(RuleSetFactory.java:317)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.parseRuleSetNode(RuleSetFactory.java:272)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:202)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSet(RuleSetFactory.java:197)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSets(RuleSetFactory.java:161)
[pmd] 	at net.sourceforge.pmd.RuleSetFactory.createRuleSets(RuleSetFactory.java:145)
[pmd] 	at net.sourceforge.pmd.RulesetsFactoryUtils.getRuleSets(RulesetsFactoryUtils.java:31)
[pmd] 	at net.sourceforge.pmd.processor.AbstractPMDProcessor.createRuleSets(AbstractPMDProcessor.java:63)
[pmd] 	at net.sourceforge.pmd.processor.MonoThreadProcessor.processFiles(MonoThreadProcessor.java:41)
[pmd] 	at net.sourceforge.pmd.PMD.processFiles(PMD.java:367)
[pmd] 	at net.sourceforge.pmd.ant.internal.PMDTaskImpl.doTask(PMDTaskImpl.java:188)
[pmd] 	at net.sourceforge.pmd.ant.internal.PMDTaskImpl.execute(PMDTaskImpl.java:269)
[pmd] 	at net.sourceforge.pmd.ant.PMDTask.execute(PMDTask.java:47)
[pmd] 	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[pmd] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[pmd] 	at java.lang.reflect.Method.invoke(Method.java:498)
[pmd] 	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
[pmd] 	at groovy.util.AntBuilder.performTask(AntBuilder.java:327)
[pmd] 	at groovy.util.AntBuilder.nodeCompleted(AntBuilder.java:272)
[pmd] 	at org.gradle.api.internal.project.ant.BasicAntBuilder.nodeCompleted(BasicAntBuilder.java:78)
[pmd] 	at sun.reflect.GeneratedMethodAccessor124.invoke(Unknown Source)
[pmd] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[pmd] 	at java.lang.reflect.Method.invoke(Method.java:498)
[pmd] 	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
[pmd] 	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
[pmd] 	at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:382)
[pmd] 	at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:170)
[pmd] 	at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:163)
[pmd] 	at org.gradle.api.internal.project.antbuilder.AntBuilderDelegate.nodeCompleted(AntBuilderDelegate.java:118)
[pmd] 	at groovy.util.BuilderSupport.doInvokeMethod(BuilderSupport.java:154)
[pmd] 	at groovy.util.BuilderSupport.invokeMethod(BuilderSupport.java:67)
[pmd] 	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:48)
[pmd] 	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
[pmd] 	at org.gradle.api.plugins.quality.internal.PmdInvoker$_invoke_closure2.doCall(PmdInvoker.groovy:62)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[pmd] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[pmd] 	at java.lang.reflect.Method.invoke(Method.java:498)
[pmd] 	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
[pmd] 	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
[pmd] 	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
[pmd] 	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)
[pmd] 	at groovy.lang.Closure.call(Closure.java:414)
[pmd] 	at groovy.lang.Closure.call(Closure.java:430)
[pmd] 	at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:70)
[pmd] 	at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:52)
[pmd] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder$2.execute(DefaultIsolatedAntBuilder.java:151)
[pmd] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder$2.execute(DefaultIsolatedAntBuilder.java:133)
[pmd] 	at org.gradle.api.internal.project.antbuilder.ClassPathToClassLoaderCache.withCachedClassLoader(ClassPathToClassLoaderCache.java:134)
[pmd] 	at org.gradle.api.internal.project.antbuilder.DefaultIsolatedAntBuilder.execute(DefaultIsolatedAntBuilder.java:127)
[pmd] 	at org.gradle.api.internal.project.IsolatedAntBuilder$execute$2.call(Unknown Source)
[pmd] 	at org.gradle.api.plugins.quality.internal.PmdInvoker.invoke(PmdInvoker.groovy:60)
[pmd] 	at org.gradle.api.plugins.quality.Pmd.run(Pmd.java:93)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[pmd] 	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[pmd] 	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[pmd] 	at java.lang.reflect.Method.invoke(Method.java:498)
[pmd] 	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
[pmd] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.doExecute(DefaultTaskClassInfoStore.java:136)
[pmd] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:129)
[pmd] 	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:118)
[pmd] 	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:623)
[pmd] 	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:606)
[pmd] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
[pmd] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
[pmd] 	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
[pmd] 	at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
[pmd] 	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64)
[pmd] 	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
[pmd] 	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
[pmd] 	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
[pmd] 	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
[pmd] 	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
[pmd] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:233)
[pmd] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
[pmd] 	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:74)
[pmd] 	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:55)
[pmd] 	at org.gradle.execution.taskgraph.ParallelTaskPlanExecutor.process(ParallelTaskPlanExecutor.java:50)
[pmd] 	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
[pmd] 	at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
[pmd] 	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
[pmd] 	at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
[pmd] 	at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
[pmd] 	at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
[pmd] 	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
[pmd] 	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:186)
[pmd] 	at org.gradle.internal.Factories$1.create(Factories.java:22)
[pmd] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
[pmd] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:183)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:33)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:112)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:106)
[pmd] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
[pmd] 	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
[pmd] 	at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:92)
[pmd] 	at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:66)
[pmd] 	at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
[pmd] 	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
[pmd] 	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
[pmd] 	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
[pmd] 	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:79)
[pmd] 	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:51)
[pmd] 	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:59)
[pmd] 	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
[pmd] 	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
[pmd] 	at org.gradle.util.Swapper.swap(Swapper.java:38)
[pmd] 	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
[pmd] 	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
[pmd] 	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.HintGCAfterBuild.execute(HintGCAfterBuild.java:44)
[pmd] 	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
[pmd] 	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
[pmd] 	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:293)
[pmd] 	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
[pmd] 	at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
[pmd] 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[pmd] 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[pmd] 	at java.lang.Thread.run(Thread.java:745)

Running PMD through: [CLI] Jenkins

[java] [doc] NonThreadSafeSingleton: Be more explicit as to why double checked locking is not recommended

Rule Set: design.html#NonThreadSafeSingleton

Code Sample demonstrating the issue:

if (sDatabase == null) { // <<<<<<<< incorrectly reported as not being thread safe. While this is technically true for this if statement, the double lock pattern is common enough that PMD should know about it.
    synchronized (BaseHelper.class) {
        if (sDatabase == null) {
            sDatabase = FirebaseDatabase.getInstance();
            sDatabase.setPersistenceEnabled(true);
        }
    }
}

Running PMD through: Gradle

[java] Parse error on method reference with generics

Hello guys,

I found an issue when analyzing open-source project 'spring' (https://github.com/spring-projects/spring-framework). Can you please take a look?

PMD version:
5.5.2

Rule Set:
java-basic

Description:

Error while processing file: spring-framework\spring-web-reactive\src\main\java\org\springframework\web\reactive\function\BodyExtractors.java
net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "::" ":: "" at line 121, column 52.
Was expecting one of:
    ")" ...
    "," ...
    "++" ...
    "--" ...

        at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:10875)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:10759)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.Arguments(JavaParser.java:4187)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.PrimarySuffix(JavaParser.java:4016)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.PrimaryExpression(JavaParser.java:3668)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.PostfixExpression(JavaParser.java:3502)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.UnaryExpressionNotPlusMinus(JavaParser.java:3464)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.UnaryExpression(JavaParser.java:3316)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.MultiplicativeExpression(JavaParser.java:3231)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AdditiveExpression(JavaParser.java:3178)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ShiftExpression(JavaParser.java:3123)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.RelationalExpression(JavaParser.java:3062)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.InstanceOfExpression(JavaParser.java:3026)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.EqualityExpression(JavaParser.java:2973)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.AndExpression(JavaParser.java:2933)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ExclusiveOrExpression(JavaParser.java:2893)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.InclusiveOrExpression(JavaParser.java:2853)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ConditionalAndExpression(JavaParser.java:2813)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ConditionalOrExpression(JavaParser.java:2773)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ConditionalExpression(JavaParser.java:2734)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.Expression(JavaParser.java:2593)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ReturnStatement(JavaParser.java:5396)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.Statement(JavaParser.java:4488)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.BlockStatement(JavaParser.java:4617)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.Block(JavaParser.java:4575)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.MethodDeclaration(JavaParser.java:1554)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBodyDeclaration(JavaParser.java:1246)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1162)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:586)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:476)
        at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:222)
        at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:56)
        at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:95)
        at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:142)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:80)
        at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:47)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:79)
        at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:25)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

Code Sample demonstrating the issue:

	private static <T, S extends Publisher<T>> S readWithMessageReaders(
			ReactiveHttpInputMessage inputMessage,
			BodyExtractor.Context context,
			ResolvableType elementType,
			Function<HttpMessageReader<T>, S> readerFunction,
			Function<Throwable, S> unsupportedError) {

		MediaType contentType = contentType(inputMessage);
		Supplier<Stream<HttpMessageReader<?>>> messageReaders = context.messageReaders();
		return messageReaders.get()
				.filter(r -> r.canRead(elementType, contentType))
				.findFirst()
				.map(BodyExtractors::<T>cast)
				.map(readerFunction)
				.orElseGet(() -> {
					List<MediaType> supportedMediaTypes = messageReaders.get()
							.flatMap(reader -> reader.getReadableMediaTypes().stream())
							.collect(Collectors.toList());
					UnsupportedMediaTypeException error =
							new UnsupportedMediaTypeException(contentType, supportedMediaTypes);
					return unsupportedError.apply(error);
				});
	}

also happens for another file (BodyInserters.java):

	private static HttpMessageWriter<Resource> resourceHttpMessageWriter(BodyInserter.Context context) {
		return context.messageWriters().get()
				.filter(messageWriter -> messageWriter.canWrite(RESOURCE_TYPE, null))
				.findFirst()
				.map(BodyInserters::<Resource>cast)
				.orElseThrow(() -> new IllegalStateException(
						"Could not find HttpMessageWriter that supports Resources."));
	}

and another file (RouterFunctionsTests.java):

	@Test
	public void toHttpHandler() throws Exception {
		HandlerStrategies strategies = mock(HandlerStrategies.class);
		when(strategies.messageReaders()).thenReturn(
				Stream::<HttpMessageReader<?>>empty);
		when(strategies.messageWriters()).thenReturn(
				Stream::<HttpMessageWriter<?>>empty);
		when(strategies.viewResolvers()).thenReturn(
				Stream::<ViewResolver>empty);

		ServerRequest request = mock(ServerRequest.class);
		ServerResponse response = mock(ServerResponse.class);
		when(response.writeTo(any(ServerWebExchange.class), eq(strategies))).thenReturn(Mono.empty());

		HandlerFunction<ServerResponse> handlerFunction = mock(HandlerFunction.class);
		when(handlerFunction.handle(any(ServerRequest.class))).thenReturn(Mono.just(response));

		RouterFunction<ServerResponse> routerFunction = mock(RouterFunction.class);
		when(routerFunction.route(any(ServerRequest.class))).thenReturn(Mono.just(handlerFunction));

		RequestPredicate requestPredicate = mock(RequestPredicate.class);
		when(requestPredicate.test(request)).thenReturn(false);


		HttpHandler result = RouterFunctions.toHttpHandler(routerFunction, strategies);
		assertNotNull(result);

		MockServerHttpRequest httpRequest =
				new MockServerHttpRequest(HttpMethod.GET, "http://localhost");
		MockServerHttpResponse serverHttpResponse = new MockServerHttpResponse();
		result.handle(httpRequest, serverHttpResponse);
	}

Running PMD through: [CLI]

java -cp * net.sourceforge.pmd.PMD -d "spring-framework\spring-web-reactive\src\main\java\org\springframewor
k\web\reactive\function" -f text -R java-basic -verbose

[java] InvalidLogMessageFormat doesn't handle formats assembled via multi-stage concatenation

Rule Set:
Logging-Java/InvalidSlf4jMessageFormat
Now: InvalidLogMessageFormat

Description:
Some of our code assembles SLF4J format strings in multiple stages; a method might define a message format containing a placeholder, then an error format that adds to the message format, etc. However, InvalidSlf4jMessageFormat only checks the number of placeholders in the most recent concatenation, eg if message contained 2 placeholders and error added one more, then InvalidSlf4jMessageFormat would expect only one argument when it is used.

Code Sample demonstrating the issue:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4JMessageFormatConcatenation {
    private static final Logger LOG = LoggerFactory.getLogger(Slf4JMessageFormatConcatenation.class);

    public void run() {
        String message = "Field: {}";
        // some code
        String error = message + ", error: {}";
        
        LOG.error(error, "fieldValue", "errorMessage");
    }
}

Running PMD through:
Maven

[java] ConfusingTernary should treat != null as positive condition

Rule Set: ConfusingTernary

Description:

ConfusingTernary should treat negative comparisons with null as a positive condtion.

The condition "!= null" is often used to mean "the item is present" rather than "the item is not absent".

Rewriting using "== null" would make the code much harder to follow.

Code Sample demonstrating the issue:

if (parser.getArgumentById(VERSION_OPT) != null) {
...
} else if (parser.getArgumentById(HELP_OPT) != null) {
...
} else if (parser.getArgumentById(OPTIONS_OPT) != null) {
...
} else if (parser.getArgumentById(SERVER_OPT) != null) {
...

Running PMD through: Ant

[java] UnnecessaryLocalBeforeReturn: Enhance by checking usages

Rule Set: java-design

Description:
See discussion at #221:

We should probably drop the requirement for the declaration and the return being in consecutive lines, and simply check the number of uses of the variable being > 1. This also means no need for the current assert lookup.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.