An extensible multilanguage static code analyzer.

Overview

PMD

Join the chat at https://gitter.im/pmd/pmd Build Status Maven Central Reproducible Builds Coverage Status Codacy Badge Contributor Covenant

About

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 Java, JavaScript, Salesforce.com Apex and Visualforce, Modelica, PLSQL, Apache Velocity, XML, XSL, Scala.

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

Support

Source

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.

Website

More information can be found on our Website.

Comments
  • PMD-3546925	 PLSQL Language for PMD

    PMD-3546925 PLSQL Language for PMD

    Patch to:- add Oracle PL/SQL language to PMD languages add PL/SQL as an option to CPD

    AST is derived from PLDoc parser (pldoc.sourceforge.net) 1.3.2.

    The AST also covers a subset of SQL*Plus.

    opened by sturton 88
  • Call For Logo

    Call For Logo

    PMD’s logo was great for a long time. But now we want to take the opportunity with the next major release to change our logo in order to use a more “politically correct” one. As you probably know, PMD’s current logo is showing a gun with the tagline “Don’t shoot the messenger”. While this was probably intended as a joke when PMD was a minor tool 12 years back, it might be offensive nowadays / not aligned with corporate policies from organizations that would otherwise benefit from PMD. PMD is in no way glorifying weapons or violence - PMD is about software quality, and helping developers improve their craft. Having a logo that illustrates those values without negative connotations makes it possible to use the logo in presentations without warning audiences.

    Now comes your part: If you have a good idea for a logo, please share it with us! Maybe you like to design logos or you are even a professional designer, then that’s your chance :smile:

    This issue here is used to collect the suggestions and let all of you vote. Each suggested logo has its own comment, and everybody can vote for a logo with a “thumbs up” (:+1:). The votes are open until the end of May 2019. The logo, that has the most votes will win.

    Note: If you submit a logo, you must hold the rights for the logo and be willing to concede such rights to the PMD project free of charge upon being selected.

    opened by adangel 39
  • [core] Allow XML dumps of ASTs

    [core] Allow XML dumps of ASTs

    Checkstyle provides a command-line option that displays the AST tree for a single file. I know this can be done through the Rule Designer. Is there a possibility that PMD will allow for the AST tree to be output via the CLI? Better still, output the AST as an xml doc?

    I assume the Xpath works on elements specified in the grammar. It would be easier to work with an xml document that mimics the tree structure so that the Xpath can be tested independently and then integrated into rule changes, if needed. JavaParser allows for xml to be output for a Java source.

    We could add an "export to XML" option in the designer. We could even let this XML document be dumpable from the designer CLI, without starting the GUI. But I don't think the value added to adding this to the PMD CLI would justify the added complexity.

    opened by oowekyala 33
  • [java] imports/UnusedImport rule not considering static inner classes of imports

    [java] imports/UnusedImport rule not considering static inner classes of imports

    Rule Set: java-imports/UnusedImports

    Code Sample demonstrating the issue:

    import com.supercilex.robotscouter.util.IoHelper;
    
    public class Foo {
        /** {@link SpreadsheetExporter#writeAndShareTeams(Fragment, IoHelper.RequestHandler, List)} */ This should be considered an import
        public void foo() {}
    }
    

    Running PMD through: Gradle

    a:bug has:pr 
    opened by SUPERCILEX 32
  • [java] Ignore unused declarations that have special name

    [java] Ignore unused declarations that have special name

    Implemented solution via #3066:

    The following rules are affected:

    The following variable names are ignored:

    • any name starting with ignored, e.g. ignoredParameter
    • any name starting with unused, e.g. unusedVar

    Is your feature request related to a problem? Please describe. UnusedLocalVariable, UnusedFormalParameter flag all unused variables.

    Describe the solution you'd like Please add a property to the rule specifying a pattern such as starts with $, _ or unused for the variable name so that variables that meet the criteria are excluded. Additionally, you could support custom annotations that mark the variables as Unused. e.g., @Unused or @Ignored. E.g., https://github.com/Lanchon/r8/blob/e22a77d26e30615bfc9b5f598bb0f58f10dd082c/src/test/java/com/android/tools/r8/shaking/ifrule/IfOnAnnotationTestClasses.java

    Describe alternatives you've considered Example code flagged by ForLoopCanBeForEach when usual for loop used:

    @SuppressWarnings("PMD.UnusedLocalVariable")
      @Override
      public Solution solve() {
        int[] dp = new int[capacity + 1];
    
        List<Item> itemsList = new ArrayList<>(items.length);
        int i = 0;
        for (int dpVal : dp) {
          for (Item item : items) {
            if (item.weight <= i) {
              int includedVal = dp[i - item.weight] + item.value;
              if (includedVal > dp[i]) dp[i] = includedVal;
            }
          }
          ++i;
        }
        path(items, capacity, dp, itemsList);
        itemsList = Item.pack(itemsList);
        return new Solution(itemsList, dp[capacity]);
      }
    

    Additional context Haskell/Python style Error-prone

    Also see #2923

    Referenced from: https://github.com/pmd/pmd/issues/2838

    an:enhancement 
    opened by Fernal73 29
  • SourceForge: Role and purpose

    SourceForge: Role and purpose

    Description:

    Can anyone tell me what role and purpose does SourceForge continue to serve PMD as?

    I signed up at the group and apart from an update email from Oracle wrt to upcoming Java releases, there is no activity on the group discussions.

    As far as I can see, this list is defunct. If it's being used, it's mainly as an referenced archive and a mailing list.

    You can easily create a Google group, one for PMD developers and another for users to answer more general questions.

    Existing users can be migrated to these groups with their permission.

    There appears to be some commit activity visible for pmd-core.

    https://sourceforge.net/projects/pmd/

    Additionally, the site is not mobile-friendly either.

    a:question 
    opened by Fernal73 27
  • [apex] ApexCRUDViolation: Recognize User Mode in SOQL + DML

    [apex] ApexCRUDViolation: Recognize User Mode in SOQL + DML

    Affects PMD Version:

    Rule: ApexCRUDViolation

    Description: With the upcoming Winter '23 (API Version 56) Salesforce is going to add more native capabilities to enforce CRUD and FLS security in SOQL queries and DML statements as described here https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_enforce_usermode.htm.

    Currently, the usage of such new features is ignored by PMD and marked as a CRUD Violation. Therefor the rule needs to be extended to recognize and handle them correctly.

    Code Sample demonstrating the issue:

    public class UserMode {
    	public void coverAllCasesWithTest() {
                    // SOQL Queries cases
                    
                    Contact c;
                    // Should be flagged a critical issue
                    c = [SELECT Name FROM Contact];
                    // Should be ignored
    		c = [SELECT Name FROM Contact WITH USER_MODE];
                    // Should be at best a warning because it ignores CRUD but explicitly
    		c = [SELECT Name FROM Contact WITH SYSTEM_MODE];
    
                    // DML cases
    
                    // Should be flagged a critical issue
                   insert contact;
    
                    // Should be ignored
                   insert as user contact;
    
                    // Should be at best a warning because it ignores CRUD but explicitly
    		insert as system contact;
    
                   // ...and for ALL other occurrences of System.AccessLevel
    	}
    }
    

    This issue should cover all cases with the optional accessLevel parameter. See Dynamic SOQL. Database.getQueryLocator methods Search.query methods Database DML methods (insert, update, upsert, merge, delete, undelete, and convertLead) Includes the *Immediate and *Async methods, such as insertImmediate and deleteAsync.

    This issuers should be easy to contribute as we can just look at how the related earlier enhancements were done: https://github.com/pmd/pmd/issues/2210

    an:enhancement a:false-negative 
    opened by rsoesemann 24
  • Apex_CustomRule: Check existence of specific class / method name using count function

    Apex_CustomRule: Check existence of specific class / method name using count function

    I'm writing customrule to verify an ApexTestClass has specific class (with specific name e.g. "bulkApexTest") implemented. To achieve this, I'm planning the following

    Check the ApexTestClass not having class with name = 'bulkApexTest'. To do this, I was trying using count function (//UserClass[count(/UserClassMethods[@Image="bulkApexTest"])=0]. But this expression is not returning the expected results. please find the sample code below.

    /*************************************************************************************************** Class Name: AddSite_CX ****************************************************************************************************/

    public class AddSite_CX {
    public Site_Contacts__c siteContactObj {get; set;} Public Case caseRecord {get; Set;} Public String contactId {get; set;} Public String siteContactRecordTypeId {get; set;} Public String locIdString {get; set;} Public String locIAddressString {get; set;} Public String siteSFId {get; set;} Public Boolean showSaveButton{get; set;} Public String noValue{get; set;} Public Boolean throwError {get; Set;} Public Boolean hasrecords {get; set;} Public Boolean showAdvSearchComponent {get; set;} Public String caseId {get; set;} Public String newSiteId {get; set;} Public Set setRelatedSites {get; set;} Public Map<String, Id> mapOfSiteRecordTypeNamesAndId {get; set;} Public AddressSearch_CX.addressWrapper unStructuredAddress {get; set;}

    public AddSite_CX(ApexPages.StandardController sController){          
        throwError = False;
        caseRecord = new Case();
        caseRecord = (Case)sController.getRecord();
        if (caseRecord!=null)
        {
            caseRecord = [select id, status, casenumber,site__c from case where id=:caseRecord.Id];
            caseId = caseRecord.Id;
        } 
        
        if(caseRecord.status=='Closed')
        {
            throwError = True;
            ApexPages.Message PageErrorMessage = new ApexPages.Message(ApexPages.Severity.ERROR,HelperUtility.getErrorMessage('032'));
            ApexPages.addMessage(PageErrorMessage);
        }  
    }
    
    public AddSite_CX(ApexPages.StandardSetController controller) {  
       showSaveButton = False;
       throwError = False;
       showAdvSearchComponent = False;
       contactId  = ApexPages.currentPage().getParameters().get('id');
       // Get the RecordType Id of SiteContact by passing the RecordType Name - Default RecordType is 'Customer Service' 
       // Using CustomLabel: DefaultSiteContactRecordType - Customer Service
       Id siteContactRecordTypeId = Schema.SObjectType.Site_Contacts__c.getRecordTypeInfosByName().get(Label.DefaultSiteContactRecordType).getRecordTypeId();
       siteContactObj = new Site_Contacts__c(RecordTypeID=siteContactRecordTypeId, Related_Contact__c=contactId);
       // Prepare map of Site Record Type and its corresponding ID
       mapOfSiteRecordTypeNamesAndId = new Map<String, Id>();
       mapOfSiteRecordTypeNamesAndId = HelperUtility.pullAllRecordTypes('site__c');
       // Prepare a set of RelatedSite ids
       setRelatedSites = new Set<String>(); 
       for(Site_Contacts__c c: [select id,Related_Contact__c,Related_Site__c from Site_Contacts__c where Related_Contact__c =: contactId])
           setRelatedSites.add(c.Related_Site__c);
           
       system.debug('***setRelatedSites*'+setRelatedSites);    
       system.debug('***mapofCaseRecordTypeNameandId*'+mapOfSiteRecordTypeNamesAndId );
    } 
    
    public pagereference saveSiteContact()
    {        
        pagereference p;
         List<Site__c> s = new List<Site__c>();
        // Site is available in SF map that ID to the related Site
        // If the Searched Site is already Associated to the Contact throw error message.
        // If Site is not available in SF create a new Unverified Site and map that ID to the related site.
        
        system.debug('****siteSFId'+siteSFId);
        if(siteSFId!=null && siteSFId!='')
        {
           If(setRelatedSites.size()>0)
              checkAssociatedSite(setRelatedSites, siteSFId);
           else
              siteContactObj.Related_Site__c = siteSFId;  
        }
        else
        {            
            Site__c newUnverifiedSite = new Site__c();
            if(HelperUtility.checkNullValue(locIdString))
               s = [select id, Location_Id__c from Site__c where Location_Id__c=: locIdString];            
           try{
                If(HelperUtility.checkNullValue(locIAddressString))
                {
                    // If a Site is available with the Location Id
                    if(s.size()>0)
                      newUnverifiedSite = s[0];                   
                    else
                    { 
                         newUnverifiedSite.RecordTypeID= (HelperUtility.checkNullValue(locIdString))? mapOfSiteRecordTypeNamesAndId.get('Verified') : mapOfSiteRecordTypeNamesAndId.get('Unverified');                       
                         newUnverifiedSite.Site_Address__c= 'locIAddressString';
                         newUnverifiedSite.Location_Id__c=locIdString;
                         newUnverifiedSite.Name = locIAddressString;                                                               
                    }
    
                    // perform ServiceQualification from External System.                   
                    newUnverifiedSite = HelperUtility.executeServiceQualification(newUnverifiedSite, newUnverifiedSite.Location_Id__c);   
                    System.debug('*** newUnverifiedSite ==>'+ newUnverifiedSite);
                    Upsert newUnverifiedSite; 
    
                    // Check If the site is already Associated with Contact or not                     
                   If(setRelatedSites.size()>0)
                      checkAssociatedSite(setRelatedSites, string.valueof(newUnverifiedSite.id));                       
                    else
                      siteContactObj.Related_Site__c=newUnverifiedSite.id;  
                }
                else
                {
                    throwError = True;
                    ApexPages.Message PageErrorMessage = new ApexPages.Message(ApexPages.Severity.ERROR,HelperUtility.getErrorMessage('005'));
                    ApexPages.addMessage(PageErrorMessage);
                }
            }
            catch(exception ex)
            {
               apexpages.addmessages(ex);
            }
        }
        // Insert SiteContact once we have associated Site.
        if(siteContactObj.Related_Site__c!=null)
        {
            insert siteContactObj;
            p = new PageReference('/'+siteContactObj.id);
            p.setRedirect(true);
        }
        else {
            p=null;
            showSaveButton = True;
        }                
        return p; 
    }
    
     public class sWrapper{
        public string technologyType { get; set; }
        public integer serviceClass { get; set; }
        public string rolloutType { get; set; }
    }
    
    public void getaddressDetails()
    {
        system.debug('*** siteSFId ==>'+ siteSFId );
        system.debug('*** locIdString ==>'+ locIdString);
        system.debug('*** locIAddressString ==>'+ locIAddressString); 
        if(HelperUtility.checkNullValue(siteSFId) || HelperUtility.checkNullValue(locIdString))
         hasrecords = True;
    }
    
    Public void flipAddressComponent(){
        showAdvSearchComponent = True;
    }
    
    Public void checkAssociatedSite(set<String> relatedSites, string relatedSiteId)
    {
        If(!relatedSites.contains(relatedSiteId))
            siteContactObj.Related_Site__c=relatedSiteId;
        else
        {
            throwError = True;
            ApexPages.Message PageErrorMessage = new ApexPages.Message(ApexPages.Severity.ERROR,HelperUtility.getErrorMessage('004'));
            ApexPages.addMessage(PageErrorMessage);
        }  
    
    }
    

    public pagereference updateCaseWithSiteInfo(){ system.debug('*** newSiteId ==>'+ newSiteId);
    case c= [select id,site__c,site__r.name from case where id=:caseId]; c.site__c = ID.valueof(newSiteId); update c;

       // Get all SiteContacts for the related site               
       set<string> setSiteContacts = new set<String>();
       if(newSiteId!=null)
       {
            for(Site_Contacts__c siteC : [Select id, Related_Contact__c, Related_Site__c, Role__c from Site_Contacts__c where Related_Site__c =: newSiteId])
            {
                setSiteContacts.add(siteC.Related_Contact__c);
            }
       }
       // Create siteContacts which are not already associated.
       List<Site_Contacts__c> lstSC = new List<Site_Contacts__c>();       
       for(Case_Contact__c cc: [Select id, Case__c, Case__r.Site__c, Contact__c, Role__c from Case_Contact__c where Case__c=:c.Id])
       {
          if(!setSiteContacts.Contains(string.valueof(cc.Contact__c)))
          {
                Site_Contacts__c sc = new Site_Contacts__c();
                sc.Related_Contact__c = cc.Contact__c;
                sc.Related_Site__c = cc.Case__r.Site__c;
                sc.Role__c = cc.Role__c ;
                lstSC.add(sc);
          }
        }
        // Insert SiteContacts.
        if(lstSC.size()>0)
         upsert lstSC;
        
        pagereference p;       
        p = new pagereference('/'+caseId);
        p.setRedirect(true);
        return p;
    }     
    
    @RemoteAction
    public static string getAddressSearchData(AddressSearch_CX.addressWrapper selectedAddress, string cId){
       site__c s = HelperUtility.instantiateUnStructuredVerifiedSite(selectedAddress);
       upsert s;      
       return string.valueof(s.id);
    }
    
     public class bulkApexTest
    {
        Public string technologyType
        public string serviceClass
        public string Isbulk
    
    newsArticles = [SELECT Id, KnowledgeArticleId FROM News__kav WHERE PublishStatus = 'Draft' AND Language = 'en_US' ORDER BY Title];
        for (News__kav article : newsArticles) 
        {
            KbManagement.PublishingService.publishArticle(article.KnowledgeArticleId, true);
            articleIds.add(article.Id);
        }
    }
    
    @RemoteAction
    public static AddressSearch_CX.addressWrapper createUnverifiedSite(AddressSearch_CX.StructuredAddress inputAddress){
        site__c siteRec = HelperUtility.instantiateStructuredUnVerifiedSite(inputAddress);
        insert siteRec;
        AddressSearch_CX.addressWrapper createdUnverifiedAddress = new AddressSearch_CX.addressWrapper ();
        List<Site__c> siteRecords = [SELECT Id, Name, Site_Address__c, Location_Id__c, Asset_Number__c FROM site__c WHERE Id =: siteRec.id LIMIT 1];
        createdUnverifiedAddress.address = siteRecords.get(0).Site_Address__c;
        createdUnverifiedAddress.locationId = siteRecords.get(0).Location_Id__c;
        createdUnverifiedAddress.addressFrom =  'UnVerified';
        createdUnverifiedAddress.assetNumber = siteRecords.get(0).Asset_Number__c;
        createdUnverifiedAddress.sfRecordId = siteRecords.get(0).Id;
        createdUnverifiedAddress.SiteSfRecordName = siteRecords.get(0).Name;
        return createdUnverifiedAddress;
    }
    
    a:question 
    opened by haigsn 24
  • [ui] XPath AutoComplete

    [ui] XPath AutoComplete

    So the feature is in very early stages as we discussed the basic rudimentary setup is there I have used a basic contains check to look out for the suggestions of XPath.

    Working on the UI that's a part I need help around @oowekyala
    maybe some guidelines.

    is:WIP 
    opened by akshatbahety 23
  • [apex] Add custom Codacy.com Time-to-Fix property to ruleset.xml

    [apex] Add custom Codacy.com Time-to-Fix property to ruleset.xml

    Before submitting a PR, please check that:

    • [x] The PR is submitted against master. The PMD team will merge back to support branches as needed.
    • [x] mvn test passes.
    • [x] mvn checkstyle:check passes. Check this for more info

    PR Description: PMD change to solve https://github.com/codacy/codacy-pmdjava/issues/29 where Codacy.com always showed 5min to fix for each PMD issue.

    opened by rsoesemann 23
  • [apex] Make Rule suppression work

    [apex] Make Rule suppression work

    Before submitting a PR, please check that:

    • [x] The PR is submitted against master. The PMD team will merge back to support branches as needed.
    • [x] mvn test passes.
    • [x] mvn checkstyle:check passes. Check this for more info

    PR Description: Enables PMD-like rule suppression for the Apex language and by that implements https://github.com/pmd/pmd/issues/265.

    Not all suppression variations from Java could be ported due to the limitations of the current Apex parser to recognize undefined Annotation parameters.

    Those will work on classes, interfaces, member and method variables, methods and method parameters:

    • @SupressWarnings('PMD') to supress all Apex rules
    • @SupressWarnings('all') to supress all Apex rules
    • @SupressWarnings('PMD.ARuleName') to supress only the rule named ARuleName
    • @SupressWarnings('PMD.ARuleName, PMD.AnotherRuleName') to supress only the rule named ARuleName or AnotherRuleName
    an:enhancement 
    opened by rsoesemann 23
  • UseLocaleWithCaseConversions

    UseLocaleWithCaseConversions

        <dependency>
            <groupId>com.github.f4b6a3</groupId>
            <artifactId>ulid-creator</artifactId>
            <version>5.1.0</version>
        </dependency>
    
    public static String generateUlid(boolean uppercase)
    {
        Ulid ulid = Ulid.fast();
        return uppercase ? ulid.toString() : ulid.toLowerCase(); // here problem
    }
    

    UseLocaleWithCaseConversions: When doing a String.toLowerCase()/toUpperCase() call, use a Locale

    a:bug 
    opened by winhkey 0
  • [java] CommentDefaultAccessModifier ignoredAnnotations should include

    [java] CommentDefaultAccessModifier ignoredAnnotations should include "org.junit.jupiter.api.extension.RegisterExtension" by default

    Affects PMD Version:

    6.52.0

    Rule:

    CommentDefaultAccessModifier

    https://pmd.sourceforge.io/pmd-6.52.0/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier

    Description:

    Code Sample demonstrating the issue:

    
    import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
    import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
    import org.junit.jupiter.api.extension.RegisterExtension;
    
    class SomeTest {
    
      @RegisterExtension
      static final WireMockExtension WIRE_MOCK_EXTENSION =
          WireMockExtension.newInstance()
              .options(wireMockConfig().dynamicPort().notifier(new ConsoleNotifier(true)))
              .build();
    }
    

    Expected outcome:

    Default value of "ignoredAnnotations" should include "org.junit.jupiter.api.extension.RegisterExtension"

    good first issue a:false-positive 
    opened by koalalam 0
  • JUnitTestsShouldIncludeAssert -

    JUnitTestsShouldIncludeAssert - "assert" with CompletionStage

    Affects PMD Version:

    6.52.0

    JDK version: 17

    Rule:

    JUnitTestsShouldIncludeAssert

    https://pmd.sourceforge.io/pmd-6.52.0/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert

    Description:

    Code Sample demonstrating the issue:

       CompletionStage<Object> future = ...;
       future.whenComplete(
            (data, exception) -> {
              assertNotNull(data, "Data shouldn't be null"); 
            });
    

    Expected outcome:

    PMD recognizes "assertNotNull".

    a:false-positive 
    opened by koalalam 0
  • [plsql] Parsing exception COMPOUND TRIGGER

    [plsql] Parsing exception COMPOUND TRIGGER

    Affects PMD Version:

    This error was testing in the following versions:

    • 6.52.0
    • 6.51.0

    Description:

    Trying to analyze pl/sql code in a Compound Trigger PMD raises an exception error that indicates "Error while parsing".

    Exception Stacktrace:

    net.sourceforge.pmd.PMDException: Error while parsing C:\testfolder\example_trigger.sql
    	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:124)
    	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:100)
    	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:62)
    	at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:85)
    	at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:29)
    	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
    	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
    	at java.base/java.lang.Thread.run(Thread.java:832)
    Caused by: net.sourceforge.pmd.lang.plsql.ast.ParseException: Encountered "  "l_number_one "" at line 5, column 4.
    Was expecting:
        "BEGIN" ...
        
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.generateParseException(PLSQLParser.java)
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.jj_consume_token(PLSQLParser.java)
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.TriggerTimingPointSection(PLSQLParser.java:53993)
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.CompoundTriggerBlock(PLSQLParser.java:54808)
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.TriggerUnit(PLSQLParser.java:53919)
    	at net.sourceforge.pmd.lang.plsql.ast.PLSQLParser.Input(PLSQLParser.java:143)
    	at net.sourceforge.pmd.lang.plsql.PLSQLParser.parse(PLSQLParser.java:61)
    	at net.sourceforge.pmd.lang.AbstractParser.doParse(AbstractParser.java:44)
    	at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:136)
    	at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:200)
    	at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:118)
    	... 10 more
    

    Code Sample demonstrating the issue:

    --
    -- CREATE TABLE ONLY FOR INSTALLATION PURPOSES IN A DATABASE
    CREATE TABLE TEST_TABLE
    (
      COL_ONE    VARCHAR2(10),
      COL_TWO    VARCHAR2(10),
      COL_THREE  VARCHAR2(10)
    );
    --
    -- TRIGGER EXAMPLE
    CREATE OR REPLACE TRIGGER EXAMPLE_TRIGGER
       FOR INSERT ON TEST_TABLE
       COMPOUND TRIGGER
       --
       l_number_one NUMBER(2) := ROUND(DBMS_RANDOM.Value(1, 10));
       l_number_two NUMBER(2) := ROUND(DBMS_RANDOM.Value(1, 10));
       --
       BEFORE EACH ROW IS
          --
          l_tot_numbers NUMBER(2);
          --
       BEGIN
          --
          l_tot_numbers := l_number_one + l_number_two;
          --
          :NEW.col_one   := l_number_one;
          :NEW.col_two   := l_number_two;
          :NEW.col_three := l_tot_numbers;
          --
       EXCEPTION
          WHEN OTHERS THEN
             RAISE_APPLICATION_ERROR(-20001, 'ERROR AT EXAMPLE_TRIGGER - BEFORE EACH ROW' || CHR(10) || SQLERRM);
       END BEFORE EACH ROW;
       --
       --
       AFTER STATEMENT IS
       BEGIN
          --
          DBMS_OUTPUT.Put_Line('This is just an example!');
          --
       EXCEPTION
          WHEN OTHERS THEN
             RAISE_APPLICATION_ERROR(-20002, 'ERROR AT EXAMPLE_TRIGGER - AFTER STATEMENT' || CHR(10) || SQLERRM);
       END AFTER STATEMENT;
       --
    END EXAMPLE_TRIGGER;
    

    Steps to reproduce:

    1. Put the code above ("Code Sample demonstrating the issue" section) in example_trigger.sql
    2. Execute PMD analyzer from CLI.
    3. See the error showed in the "Exception Stacktrace" section.

    Running PMD through: [CLI]

    a:bug 
    opened by hgodinez89 0
  • [java] False positive about the rule CommentDefaultAccessModifier

    [java] False positive about the rule CommentDefaultAccessModifier

    Affects PMD Version:6.50.0

    Rule:CommentDefaultAccessModifier

    Please provide the rule name and a link to the rule documentation: https://pmd.sourceforge.io/pmd-6.52.0/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier

    Description: In the rule CommentDefaultAccessModifier, I found PMD can raise a wanring for org.testng.annotations.Test, but when I used org.junit.jupiter.api.Test`, it does not report the warning, hence I think this is a false positive because these two annotations are equal and the behavior should be consistent.

    Code Sample demonstrating the issue:

    import org.testng.annotations.Test;
    public class C {
        @Test
        void foo() {
            synchronized (this) {}
        }
    }
    

    Expected outcome:

    PMD should not report a violation at line 3. This is a false positive.

    Running PMD through: [Maven]

    a:false-positive 
    opened by LynnBroe 0
  • [java] A crash bug about Test

    [java] A crash bug about Test

    Affects PMD Version:6.50.0

    Description:

    I run PMD to detect the following code example, and it crashed.

    Exception Stacktrace:

    Exception in thread "main" java.lang.annotation.AnnotationTypeMismatchException: Incorrectly typed data found for annotation element public abstract java.lang.Class[] com.beust.jcommander.Parameter.validateValueWith() (Found data of type class java.lang.Class[class net.sourceforge.pmd.cli.PMDParameters$RulePriorityValidator])
    	at java.base/sun.reflect.annotation.AnnotationTypeMismatchExceptionProxy.generateException(AnnotationTypeMismatchExceptionProxy.java:57)
    	at java.base/sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:86)
    	at com.sun.proxy.$Proxy1.validateValueWith(Unknown Source)
    	at com.beust.jcommander.WrappedParameter.validateValueWith(WrappedParameter.java:64)
    	at com.beust.jcommander.ParameterDescription.validateValueParameter(ParameterDescription.java:350)
    	at com.beust.jcommander.ParameterDescription.validateDefaultValues(ParameterDescription.java:164)
    	at com.beust.jcommander.ParameterDescription.init(ParameterDescription.java:157)
    	at com.beust.jcommander.ParameterDescription.<init>(ParameterDescription.java:65)
    	at com.beust.jcommander.JCommander.addDescription(JCommander.java:631)
    	at com.beust.jcommander.JCommander.createDescriptions(JCommander.java:601)
    	at com.beust.jcommander.JCommander.<init>(JCommander.java:252)
    	at com.beust.jcommander.JCommander.<init>(JCommander.java:238)
    	at com.beust.jcommander.JCommander.<init>(JCommander.java:230)
    	at net.sourceforge.pmd.cli.PmdParametersParseResult.extractParameters(PmdParametersParseResult.java:104)
    	at net.sourceforge.pmd.PMD.runPmd(PMD.java:452)
    	at net.sourceforge.pmd.PMD.main(PMD.java:418)
    	at /class/path/of/my/code
    

    Code Sample demonstrating the issue:

    @org.junit.jupiter.api.Test
    void foo() {
        synchronized (this) {}
    }
    

    Steps to reproduce: Directly use PMD to detect the code example.

    Running PMD through: [Maven]

    a:bug 
    opened by LynnBroe 0
Releases(pmd_releases/6.53.0)
  • pmd_releases/6.53.0(Dec 31, 2022)

    31-December-2022 - 6.53.0

    The PMD team is pleased to announce PMD 6.53.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Modified rules

    • The Java rule UnusedPrivateField has a new property reportForAnnotations. This is a list of fully qualified names of the annotation types that should be reported anyway. If an unused field has any of these annotations, then it is reported. If it has any other annotation, then it is still considered to be used and is not reported.

    Deprecated rules

    Fixed Issues

    • core
      • #4248: [core] Can't analyze sources in zip files
    • apex-security
      • #4146: [apex] ApexCRUDViolation: Recognize User Mode in SOQL + DML
    • java
      • #4266: [java] PMD fails to process a record with lambda in compact constructor
    • java-bestpractices
      • #4166: [java] UnusedPrivateField doesn't find annotated unused private fields anymore
      • #4250: [java] WhileLoopWithLiteralBoolean - false negative with complex expressions still occurs in PMD 6.52.0
    • java-design
      • #2127: [java] Deprecate rules ExcessiveClassLength and ExcessiveMethodLength
    • java-errorprone
      • #4164: [java][doc] AvoidAssertAsIdentifier and AvoidEnumAsIdentifier - clarify use case
    • java-multithreading
      • #4210: [java] DoNotUseThreads report duplicate warnings

    API Changes

    Deprecated APIs

    For removal

    These classes / APIs have been deprecated and will be removed with PMD 7.0.0.

    External Contributions

    • #4244: [apex] ApexCRUDViolation: user mode and system mode with test cases added - Tarush Singh (@Tarush-Singh35)
    • #4274: [java] Fix finding lambda scope in record compact constructor - kdebski85 (@kdebski85)

    Stats

    • 43 commits
    • 17 closed tickets & PRs
    • Days since last release: 35
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.53.0.zip(42.58 MB)
    pmd-doc-6.53.0.zip(5.52 MB)
    pmd-src-6.53.0.zip(15.37 MB)
  • pmd_releases/6.52.0(Nov 26, 2022)

    26-November-2022 - 6.52.0

    The PMD team is pleased to announce PMD 6.52.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    New rules

    <rule ref="category/java/design.xml/InvalidJavaBean"/>
    

    Renamed rules

    • The Java rule BeanMembersShouldSerialize has been renamed to NonSerializableClass. It has been revamped to only check for classes that are marked with Serializable and reports each field in it, that is not serializable.

      The property prefix has been deprecated, since in a serializable class all fields have to be serializable regardless of the name.

    Modified rules

    • The rule ClassNamingConventions has a new property testClassPattern, which is applied to test classes. By default, test classes should end with the suffix "Test". Test classes are top-level classes, that either inherit from JUnit 3 TestCase or have at least one method annotated with the Test annotations from JUnit4/5 or TestNG.

    • The property ignoredAnnotations of rule ImmutableField has been deprecated and doesn't have any effect anymore. Since PMD 6.47.0, the rule only considers fields, that are initialized once and never changed. If the field is just declared but never explicitly initialized, it won't be reported. That's the typical case when a framework sets the field value by reflection. Therefore, the property is not needed anymore. If there is a special case where this rule misidentifies fields as immutable, then the rule should be suppressed for these fields explicitly.

    Fixed Issues

    • cli
      • #4215: NullPointerException when trying to open designer
    • doc
      • #4207: [doc] List all languages in rule doc
    • java
      • #3643: [java] More parser edge cases
      • #4152: [java] Parse error on array type annotations
    • java-codestyle
      • #2867: [java] Separate pattern for test classes in ClassNamingConventions rule for Java
      • #4201: [java] CommentDefaultAccessModifier should consider lombok's @Value
    • java-design
      • #4175: [java] ImmutableField - deprecate property ignoredAnnotations
      • #4177: [java] New Rule InvalidJavaBean
      • #4188: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal false positive with Lombok's @NoArgsConstructor
      • #4189: [java] AbstractClassWithoutAnyMethod should consider lombok's @AllArgsConstructor
      • #4200: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal should consider lombok's @Value
    • java-errorprone
      • #1668: [java] BeanMembersShouldSerialize is extremely noisy
      • #4172: [java] InvalidLogMessageFormat false positive on externally formatted strings
      • #4174: [java] MissingStaticMethodInNonInstantiatableClass does not consider nested builder class
      • #4176: [java] Rename BeanMembersShouldSerialize to NonSerializableClass
      • #4185: [java] InvalidLogMessageFormat rule produces a NPE
      • #4224: [java] MissingStaticMethodInNonInstantiatableClass should consider Lombok's @UtilityClass
      • #4225: [java] MissingStaticMethodInNonInstantiatableClass should consider Lombok's @NoArgsConstructor
    • java-performance
      • #4183: [java] AvoidArrayLoops regression: from false negative to false positive with final variables

    API Changes

    PMD CLI

    • PMD now supports a new --use-version flag, which receives a language-version pair (such as java-8 or apex-54). This supersedes the usage of -language / -l and -version / -v, allowing for multiple versions to be set in a single run. PMD 7 will completely remove support for -language and -version in favor of this new flag.

    • Support for -V is being deprecated in favor of --verbose in preparation for PMD 7. In PMD 7, -v will enable verbose mode and -V will show the PMD version for consistency with most Unix/Linux tools.

    • Support for -min is being deprecated in favor of --minimum-priority for consistency with most Unix/Linux tools, where -min would be equivalent to -m -i -n.

    CPD CLI

    • CPD now supports using -d or --dir as an alias to --files, in favor of consistency with PMD. PMD 7 will remove support for --files in favor of these new flags.

    Linux run.sh parameters

    • Using run.sh cpdgui will now warn about it being deprecated. Use run.sh cpd-gui instead.

    • The old designer (run.sh designerold) is completely deprecated and will be removed in PMD 7. Switch to the new JavaFX designer: run.sh designer.

    • The old visual AST viewer (run.sh bgastviewer) is completely deprecated and will be removed in PMD 7. Switch to the new JavaFX designer: run.sh designer for a visual tool, or use run.sh ast-dump for a text-based alternative.

    Deprecated API

    External Contributions

    • #4184: [java][doc] TestClassWithoutTestCases - fix small typo in description - Valery Yatsynovich (@valfirst)
    • #4198: [doc] Add supported CPD languages - Jeroen van Wilgenburg (@jvwilge)
    • #4202: [java] Fix #4200 and #4201: ClassWithOnlyPrivateConstructorsShouldBeFinal, CommentDefaultAccessModifier: Exclude lombok @Value annotation - Lynn (@LynnBroe)
    • #4205: [doc] Clarify Scala support (no built-in rules) - Eldrick Wega (@Eldrick19)
    • #4226: [visualforce] Replace uses of Jorje types in pmd-visualforce - Aaron Hurst (@aaronhurst-google)
    • #4227: [java] Fix #4225 MissingStaticMethodInNonInstantiatableClass: Exclude lombok's @NoArgsConstructor annotation - Lynn (@LynnBroe)
    • #4228: [java] Fix #4224 MissingStaticMethodInNonInstantiatableClass: Exclude lombok's UtilityClass - Lynn (@LynnBroe)
    • #4232: [doc] Fixing typos - Andreas Deininger (@deining)

    Stats

    • 96 commits
    • 40 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.52.0.zip(42.58 MB)
    pmd-doc-6.52.0.zip(5.51 MB)
    pmd-src-6.52.0.zip(15.36 MB)
  • pmd_releases/6.51.0(Oct 29, 2022)

    29-October-2022 - 6.51.0

    The PMD team is pleased to announce PMD 6.51.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    New Rules

    <rule ref="category/apex/bestpractices.xml/ApexUnitTestClassShouldHaveRunAs"/>
    

    The rule is part of the quickstart.xml ruleset.

    Modified Rules

    • The Java rule TestClassWithoutTestCases has a new property testClassPattern. This is used to detect empty test classes by name. Previously this rule could only detect empty JUnit3 test cases properly. To switch back to the old behavior, this property can be set to an empty value which disables the test class detection by pattern.

    Fixed Issues

    • apex
      • #4149: [apex] New rule: ApexUnitTestClassShouldHaveRunAs
    • doc
      • #4144: [doc] Update docs to reflect supported languages
      • #4163: [doc] Broken links on page "Architecture Decisions"
    • java-bestpractices
      • #4140: [java] [doc] AccessorClassGeneration violations hidden with Java 11
    • java-codestyle
      • #4139: [java] UnnecessaryFullyQualifiedName FP when the same simple class name exists in the current package
    • java-documentation
      • #4141: [java] UncommentedEmptyConstructor FP when constructor annotated with @Autowired
    • java-performance
      • #1167: [java] AvoidArrayLoops false positive on double assignment
      • #2080: [java] StringToString rule false-positive with field access
      • #2692: [java] [doc] AvoidArrayLoops flags copy assignment in same array as sub-optimal
      • #3437: [java] StringToString doesn't trigger on Bar.class.getSimpleName().toString()
      • #3681: [java] StringToString doesn't trigger on string literals
      • #3847: [java] AvoidArrayLoops should consider final variables
      • #3977: [java] StringToString false-positive with local method name confusion
      • #4091: [java] AvoidArrayLoops false negative with do-while loops
      • #4148: [java] UseArrayListInsteadOfVector ignores Vector when other classes are imported
    • java-errorprone
      • #929: [java] Inconsistent results with TestClassWithoutTestCases
      • #2636: [java] TestClassWithoutTestCases false positive with JUnit5 ParameterizedTest
    • javascript
      • #4165: [javascript] InaccurateNumericLiteral underscore separator notation false positive

    API Changes

    No changes.

    External Contributions

    • #4142: [java] fix #4141 Update UncommentedEmptyConstructor - ignore @Autowired annotations - Lynn (@LynnBroe)
    • #4147: [java] Added support for Do-While for AvoidArrayLoops - Yasar Shaikh (@yasarshaikh)
    • #4150: [apex] New rule ApexUnitTestClassShouldHaveRunAs #4149 - Thomas Prouvot (@tprouvot)

    Stats

    • 63 commits
    • 28 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.51.0.zip(42.56 MB)
    pmd-doc-6.51.0.zip(5.50 MB)
    pmd-src-6.51.0.zip(15.34 MB)
  • pmd_releases/6.50.0(Sep 30, 2022)

    30-September-2022 - 6.50.0

    The PMD team is pleased to announce PMD 6.50.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Lua now supports additionally Luau

    This release of PMD adds support for Luau, a gradually typed language derived from Lua. This means, that the Lua language in PMD can now parse both Lua and Luau.

    Modified rules

    • The Java rule UnusedPrivateField now ignores private fields, if the fields are annotated with any annotation or the enclosing class has any annotation. Annotations often enable a framework (such as dependency injection, mocking or e.g. Lombok) which use the fields by reflection or other means. This usage can't be detected by static code analysis. Previously these frameworks where explicitly allowed by listing their annotations in the property "ignoredAnnotations", but that turned out to be prone of false positive for any not explicitly considered framework. That's why the property "ignoredAnnotations" has been deprecated for this rule.
    • The Java rule CommentDefaultAccessModifier now by default ignores JUnit5 annotated methods. This behavior can be customized using the property ignoredAnnotations.

    Fixed Issues

    • cli
      • #4118: [cli] run.sh designer reports "integer expression expected"
    • core
      • #4116: [core] Missing --file arg in TreeExport CLI example
    • doc
      • #4072: [doc] Add architecture decision records
      • #4109: [doc] Add page for 3rd party rulesets
      • #4124: [doc] Fix typos in Java rule docs
    • java
      • #3431: [java] Add sample java project to regression-tester which uses new language constructs
    • java-bestpractices
      • #4033: [java] UnusedPrivateField - false positive with Lombok @ToString.Include
      • #4037: [java] UnusedPrivateField - false positive with Spring @SpyBean
    • java-codestyle
      • #3859: [java] CommentDefaultAccessModifier is triggered in JUnit5 test class
      • #4085: [java] UnnecessaryFullyQualifiedName false positive when nested and non-nested classes with the same name and in the same package are used together
      • #4133: [java] UnnecessaryFullyQualifiedName - FP for inner class pkg.ClassA.Foo implementing pkg.Foo
    • java-design
      • #4090: [java] FinalFieldCouldBeStatic false positive with non-static synchronized block (regression in 6.48, worked with 6.47)
    • java-errorprone
      • #1718: [java] ConstructorCallsOverridableMethod false positive when calling super method
      • #2348: [java] ConstructorCallsOverridableMethod occurs when unused overloaded method is defined
      • #4099: [java] ConstructorCallsOverridableMethod should consider method calls with var access
    • scala
      • #4138: [scala] Upgrade scala-library to 2.12.7 / 2.13.9 and scalameta to 4.6.0

    API Changes

    CPD CLI

    • CPD now supports the --ignore-literal-sequences argument when analyzing Lua code.

    Financial Contributions

    Many thanks to our sponsors:

    External Contributions

    • #4066: [lua] Add support for Luau syntax and skipping literal sequences in CPD - Matt Hargett (@matthargett)
    • #4100: [java] Update UnusedPrivateFieldRule - ignore any annotations - Lynn (@LynnBroe)
    • #4116: [core] Fix missing --file arg in TreeExport CLI example - mohan-chinnappan-n (@mohan-chinnappan-n)
    • #4124: [doc] Fix typos in Java rule docs - Piotrek Żygieło (@pzygielo)
    • #4128: [java] Fix False-positive UnnecessaryFullyQualifiedName when nested and non-nest… #4103 - Oleg Andreych (@OlegAndreych)
    • #4130: [ci] GitHub Workflows security hardening - Alex (@sashashura)
    • #4131: [doc] TooFewBranchesForASwitchStatement - Use "if-else" instead of "if-then" - Suvashri (@Suvashri)
    • #4137: [java] Fixes 3859: Exclude junit5 test methods from the commentDefaultAccessModifierRule - Luis Alcantar (@lfalcantar)

    Stats

    • 100 commits
    • 26 closed tickets & PRs
    • Days since last release: 29
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.50.0.zip(42.57 MB)
    pmd-doc-6.50.0.zip(5.50 MB)
    pmd-src-6.50.0.zip(15.33 MB)
  • pmd_releases/6.49.0(Aug 31, 2022)

    31-August-2022 - 6.49.0

    The PMD team is pleased to announce PMD 6.49.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Updated PMD Designer

    This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog.

    Fixed Issues

    • apex
      • #4096: [apex] ApexAssertionsShouldIncludeMessage and ApexUnitTestClassShouldHaveAsserts: support new Assert class (introduced with Apex v56.0)
    • core
      • #3970: [core] FileCollector.addFile ignores language parameter
    • java-codestyle
      • #4082: [java] UnnecessaryImport false positive for on-demand imports of nested classes

    API Changes

    Deprecated API

    External Contributions

    • #4081: [apex] Remove Jorje leaks outside ast package - @eklimo
    • #4083: [java] UnnecessaryImport false positive for on-demand imports of nested classes (fix for #4082) - @abyss638
    • #4092: [apex] Implement ApexQualifiableNode for ASTUserEnum - @aaronhurst-google
    • #4095: [core] CPD: Added begin and end token to XML reports - @pacvz
    • #4097: [apex] ApexUnitTestClassShouldHaveAssertsRule: Support new Assert class (Apex v56.0) - @tprouvot
    • #4104: [doc] Add MegaLinter in the list of integrations - @nvuillam

    Stats

    • 49 commits
    • 10 closed tickets & PRs
    • Days since last release: 32
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.49.0.zip(41.29 MB)
    pmd-doc-6.49.0.zip(5.46 MB)
    pmd-src-6.49.0.zip(15.31 MB)
  • pmd_releases/6.48.0(Jul 30, 2022)

    30-July-2022 - 6.48.0

    The PMD team is pleased to announce PMD 6.48.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Java 19 Support

    This release of PMD brings support for Java 19. There are no new standard language features.

    PMD supports JEP 427: Pattern Matching for switch (Third Preview) and JEP 405: Record Patterns (Preview) as preview language features.

    In order to analyze a project with PMD that uses these language features, you'll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 19-preview:

    export PMD_JAVA_OPTS=--enable-preview
    ./run.sh pmd -language java -version 19-preview ...
    

    Note: Support for Java 17 preview language features have been removed. The version "17-preview" is no longer available.

    Gherkin support

    Thanks to the contribution from Anne Brouwers PMD now has CPD support for the Gherkin language. It is used to defined test cases for the Cucumber testing tool for behavior-driven development.

    Being based on a proper Antlr grammar, CPD can:

    Fixed Issues

    • apex
      • #4056: [apex] ApexSOQLInjection: Add support count query
    • core
      • #3796: [core] CPD should also provide a --debug flag
      • #4021: [core] CPD: Add total number of tokens to XML reports
      • #4031: [core] If report is written to stdout, stdout should not be closed
      • #4051: [doc] Additional rulesets are not listed in documentation
      • #4053: [core] Allow building PMD under Java 18+
    • java
      • #4015: [java] Support JDK 19
    • java-bestpractices
      • #3455: [java] WhileLoopWithLiteralBoolean - false negative with complex expressions
    • java-design
      • #3729: [java] TooManyMethods ignores "real" methods which are named like getters or setters
      • #3949: [java] FinalFieldCouldBeStatic - false negative with unnecessary parenthesis
    • java-performance
      • #3625: [java] AddEmptyString - false negative with empty var
    • lua
      • #4061: [lua] Fix several related Lua parsing issues found when using CPD
    • test
      • #3302: [test] Improve xml test schema
      • #3758: [test] Move pmd-test to java 8
      • #3976: [test] Extract xml schema module

    API Changes

    CPD CLI

    • CPD has a new CLI option --debug. This option has the same behavior as in PMD. It enables more verbose logging output.

    Rule Test Framework

    • The module "pmd-test", which contains support classes to write rule tests, now requires Java 8. If you depend on this module for testing your own custom rules, you'll need to make sure to use at least Java 8.
    • The new module "pmd-test-schema" contains now the XSD schema and the code to parse the rule test XML files. The schema has been extracted in order to easily share it with other tools like the Rule Designer or IDE plugins.
    • Test schema changes:
      • The attribute isRegressionTest of test-code is deprecated. The new attribute disabled should be used instead for defining whether a rule test should be skipped or not.
      • The attributes reinitializeRule and useAuxClasspath of test-code are deprecated and assumed true. They will not be replaced.
      • The new attribute focused of test-code allows disabling all tests except the focused one temporarily.
    • More information about the rule test framework can be found in the documentation: Testing your rules

    Deprecated API

    • The experimental Java AST class ASTGuardedPattern has been deprecated and will be removed. It was introduced for Java 17 and Java 18 Preview as part of pattern matching for switch, but it is no longer supported with Java 19 Preview.
    • The interface CPDRenderer is deprecated. For custom CPD renderers the new interface CPDReportRenderer should be used.
    • The class TestDescriptor is deprecated, replaced with RuleTestDescriptor.
    • Many methods of RuleTst have been deprecated as internal API.

    Experimental APIs

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    Financial Contributions

    Many thanks to our sponsors:

    External Contributions

    • #3984: [java] Fix AddEmptyString false-negative issue - @LiGaOg
    • #3988: [java] Modify WhileLoopWithLiteralBoolean to meet the missing case #3455 - @VoidxHoshi
    • #3992: [java] FinalFieldCouldBeStatic - fix false negative with unnecessary parenthesis - @dalizi007
    • #3994: [java] TooManyMethods - improve getter/setter detection (#3729) - @341816041
    • #4017: Add Gherkin support to CPD - @ASBrouwers
    • #4021: [core] CPD: Add total number of tokens to XML reports - @maikelsteneker
    • #4056: [apex] ApexSOQLInjection: Add support count query - @gwilymatgearset
    • #4061: [lua] Fix several related Lua parsing issues found when using CPD - @matthargett

    Stats

    • 102 commits
    • 26 closed tickets & PRs
    • Days since last release: 35
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.48.0.zip(41.27 MB)
    pmd-doc-6.48.0.zip(5.46 MB)
    pmd-src-6.48.0.zip(15.30 MB)
  • pmd_releases/6.47.0(Jun 25, 2022)

    25-June-2022 - 6.47.0

    The PMD team is pleased to announce PMD 6.47.0.

    This is a minor release.

    Table Of Contents

    Fixed Issues

    • core
      • #3999: [cli] All files are analyzed despite parameter --file-list
      • #4009: [core] Cannot build PMD with Temurin 17
    • java-bestpractices
      • #3824: [java] UnusedPrivateField: Do not flag fields annotated with @Version
      • #3825: [java] UnusedPrivateField: Do not flag fields annotated with @Id or @EmbeddedId
    • java-design
      • #3823: [java] ImmutableField: Do not flag fields in @Entity
      • #3981: [java] ImmutableField reports fields annotated with @Value (Spring)
      • #3998: [java] ImmutableField reports fields annotated with @Captor (Mockito)
      • #4004: [java] ImmutableField reports fields annotated with @GwtMock (GwtMockito) and @Spy (Mockito)
      • #4008: [java] ImmutableField not reporting fields that are only initialized in the declaration
      • #4011: [java] ImmutableField: Do not flag fields annotated with @Inject
      • #4020: [java] ImmutableField reports fields annotated with @FindBy and @FindBys (Selenium)
    • java-errorprone
      • #3936: [java] AvoidFieldNameMatchingMethodName should consider enum class
      • #3937: [java] AvoidDuplicateLiterals - uncompilable test cases

    API Changes

    No changes.

    External Contributions

    • #3985: [java] Fix false negative problem about Enum in AvoidFieldNameMatchingMethodName #3936 - @Scrsloota
    • #3993: [java] AvoidDuplicateLiterals - Add the method "buz" definition to test cases - @dalizi007
    • #4002: [java] ImmutableField - Ignore fields annotated with @Value (Spring) or @Captor (Mockito) - @jjlharrison
    • #4003: [java] UnusedPrivateField - Ignore fields annotated with @Id/@EmbeddedId/@Version (JPA) or @Mock/@Spy/@MockBean (Mockito/Spring) - @jjlharrison
    • #4006: [doc] Fix eclipse plugin update site URL - @shiomiyan
    • #4010: [core] Bump kotlin to version 1.7.0 - @maikelsteneker

    Stats

    • 45 commits
    • 23 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.47.0.zip(41.22 MB)
    pmd-doc-6.47.0.zip(5.44 MB)
    pmd-src-6.47.0.zip(15.24 MB)
  • pmd_releases/6.46.0(May 28, 2022)

    28-May-2022 - 6.46.0

    The PMD team is pleased to announce PMD 6.46.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    CLI improvements

    The PMD CLI now allows repeating the --dir (-d) and --rulesets (-R) options, as well as providing several space-separated arguments to either of them. For instance:

    pmd -d src/main/java src/test/java -R rset1.xml -R rset2.xml
    

    This also allows globs to be used on the CLI if your shell supports shell expansion. For instance, the above can be written

    pmd -d src/*/java -R rset*.xml
    

    Please use theses new forms instead of using comma-separated lists as argument to these options.

    C# Improvements

    When executing CPD on C# sources, the option --ignore-annotations is now supported as well. It ignores C# attributes when detecting duplicated code. This option can also be enabled via the CPD GUI. See #3974 for details.

    New Rules

    This release ships with 2 new Java rules.

    • EmptyControlStatement reports many instances of empty things, e.g. control statements whose body is empty, as well as empty initializers.

      EmptyControlStatement also works for empty for and do loops, while there were previously no corresponding rules.

      This new rule replaces the rules EmptyFinallyBlock, EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, and EmptyWhileStmt.

    <rule ref="category/java/codestyle.xml/EmptyControlStatement"/>
    

    The rule is part of the quickstart.xml ruleset.

    • UnnecessarySemicolon reports semicolons that are unnecessary (so called "empty statements" and "empty declarations").

      This new rule replaces the rule EmptyStatementNotInLoop.

    <rule ref="category/java/codestyle.xml/UnnecessarySemicolon"/>
    

    The rule is part of the quickstart.xml ruleset.

    Deprecated Rules

    Fixed Issues

    • cli
      • #1445: [core] Allow CLI to take globs as parameters
    • core
      • #2352: [core] Deprecate <lang>-<ruleset> hyphen notation for ruleset references
      • #3787: [core] Internalize some methods in Ant Formatter
      • #3835: [core] Deprecate system properties of CPDCommandLineInterface
      • #3942: [core] common-io path traversal vulnerability (CVE-2021-29425)
    • cs (c#)
      • #3974: [cs] Add option to ignore C# attributes (annotations)
    • go
      • #2752: [go] Error parsing unicode values
    • html
      • #3955: [html] Improvements for handling text and comment nodes
      • #3978: [html] Add additional file extensions htm, xhtml, xht, shtml
    • java
      • #3423: [java] Error processing identifiers with Unicode
    • java-bestpractices
      • #3954: [java] NPE in UseCollectionIsEmptyRule when .size() is called in a record
    • java-design
      • #3874: [java] ImmutableField reports fields annotated with @Autowired (Spring) and @Mock (Mockito)
    • java-errorprone
      • #3096: [java] EmptyStatementNotInLoop FP in 6.30.0 with IfStatement
    • java-performance
      • #3379: [java] UseArraysAsList must ignore primitive arrays
      • #3965: [java] UseArraysAsList false positive with non-trivial loops
    • javascript
      • #2605: [js] Support unicode characters
      • #3948: [js] Invalid operator error for method property in object literal
    • python
      • #2604: [python] Support unicode identifiers

    API Changes

    Deprecated ruleset references

    Ruleset references with the following formats are now deprecated and will produce a warning when used on the CLI or in a ruleset XML file:

    • <lang-name>-<ruleset-name>, eg java-basic, which resolves to rulesets/java/basic.xml
    • the internal release number, eg 600, which resolves to rulesets/releases/600.xml

    Use the explicit forms of these references to be compatible with PMD 7.

    Deprecated API

    • toString is now deprecated. The format of this method will remain the same until PMD 7. The deprecation is intended to steer users away from relying on this format, as it may be changed in PMD 7.
    • getInputPaths and setInputPaths are now deprecated. A new set of methods have been added, which use lists and do not rely on comma splitting.

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    External Contributions

    • #3961: [java] Fix #3954 - NPE in UseCollectionIsEmptyRule with record - @flyhard
    • #3964: [java] Fix #3874 - ImmutableField: fix mockito/spring false positives - @lukelukes
    • #3974: [cs] Add option to ignore C# attributes (annotations) - @maikelsteneker

    Stats

    • 92 commits
    • 30 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.46.0.zip(40.99 MB)
    pmd-doc-6.46.0.zip(5.43 MB)
    pmd-src-6.46.0.zip(15.24 MB)
  • pmd_releases/6.45.0(Apr 30, 2022)

    30-April-2022 - 6.45.0

    The PMD team is pleased to announce PMD 6.45.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    PMD User Survey

    Help shape the future of PMD by telling us how you use it.

    Our little survey is still open in case you didn't participate yet. Please participate in our survey at https://forms.gle/4d8r1a1RDzfixHDc7.

    Thank you!

    Support for HTML

    This version of PMD ships a new language module to support analyzing of HTML. Support for HTML is experimental and might change without notice. The language implementation is not complete yet and the AST doesn't look well for text nodes and comment nodes and might be changed in the future. You can write your own rules, but we don't guarantee that the rules work with the next (minor) version of PMD without adjustments.

    Please give us feedback about how practical this new language is in discussions. Please report missing features or bugs as new issues.

    New rules

    • The HTML rule AvoidInlineStyles finds elements which use a style attribute. In order to help maintaining a webpage it is considered good practice to separate content and styles. Instead of inline styles one should use CSS files and classes.
        <rule ref="category/html/bestpractices.xml/AvoidInlineStyles" />
    
    • The HTML rule UnnecessaryTypeAttribute finds "link" and "script" elements which still have a "type" attribute. This is not necessary anymore since modern browsers automatically use CSS and JavaScript.
          <rule ref="category/html/bestpractices.xml/UnnecessaryTypeAttribute" />
    
    • The HTML rule UseAltAttributeForImages finds "img" elements without an "alt" attribute. An alternate text should always be provided in order to help screen readers.
          <rule ref="category/html/bestpractices.xml/UseAltAttributeForImages" />
    

    Modified rules

    • The Java rule UnusedPrivateField has a new property ignoredFieldNames. The default ignores serialization-specific fields (eg serialVersionUID). The property can be used to ignore more fields based on their name. Note that the rule used to ignore fields named IDENT, but doesn't anymore (add this value to the property to restore the old behaviour).

    Fixed Issues

    • core
      • #3792: [core] Allow to filter violations in Report
      • #3881: [core] SARIF renderer depends on platform default encoding
      • #3882: [core] Fix AssertionError about exhaustive switch
      • #3884: [core] XML report via ant task contains XML header twice
      • #3896: [core] Fix ast-dump CLI when reading from stdin
    • doc
      • #2505: [doc] Improve side bar to show release date
    • java
      • #3068: [java] Some tests should not depend on real rules
      • #3889: [java] Catch LinkageError in UselessOverridingMethodRule
    • java-bestpractices
      • #3910: [java] UnusedPrivateField - Allow the ignored fieldnames to be configurable
      • #1185: [java] ArrayIsStoredDirectly false positive with field access
      • #1474: [java] ArrayIsStoredDirectly false positive with method call
      • #3879 [java] ArrayIsStoredDirectly reports duplicated violation
      • #3929: [java] ArrayIsStoredDirectly should report the assignment rather than formal parameter
    • java-design
      • #3603: [java] SimplifiedTernary: no violation for 'condition ? true : false' case
    • java-performance
      • #3867: [java] UseArraysAsList with method call
    • plsql
      • #3687: [plsql] Parsing exception EXECUTE IMMEDIATE l_sql BULK COLLECT INTO statement
      • #3706: [plsql] Parsing exception CURSOR statement with parenthesis groupings

    API Changes

    Experimental APIs

    • Report has two new methods which allow limited mutations of a given report:
      • Report#filterViolations creates a new report with some violations removed with a given predicate based filter.
      • Report#union can combine two reports into a single new Report.
    • net.sourceforge.pmd.util.Predicate will be replaced in PMD7 with the standard Predicate interface from java8.
    • The module pmd-html is entirely experimental right now. Anything in the package net.sourceforge.pmd.lang.html should be used cautiously.

    External Contributions

    • #3883: [doc] Improve side bar by Adding Release Date - @jasonqiu98
    • #3910: [java] UnusedPrivateField - Allow the ignored fieldnames to be configurable - @laoseth
    • #3928: [plsql] Fix plsql parsing error in parenthesis groups - @LiGaOg
    • #3935: [plsql] Fix parser exception in EXECUTE IMMEDIATE BULK COLLECT #3687 - @Scrsloota
    • #3938: [java] Modify SimplifiedTernary to meet the missing case #3603 - @VoidxHoshi
    • #3943: chore: Set permissions for GitHub actions - @naveensrinivasan

    Stats

    • 97 commits
    • 31 closed tickets & PRs
    • Days since last release: 33
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.45.0.zip(41.17 MB)
    pmd-doc-6.45.0.zip(5.44 MB)
    pmd-src-6.45.0.zip(15.21 MB)
  • pmd_releases/6.44.0(Mar 27, 2022)

    27-March-2022 - 6.44.0

    The PMD team is pleased to announce PMD 6.44.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    PMD User Survey

    Help shape the future of PMD by telling us how you use it.

    Please participate in our survey at https://forms.gle/4d8r1a1RDzfixHDc7.

    Thank you!

    Java 18 Support

    This release of PMD brings support for Java 18. There are no new standard language features.

    PMD also supports JEP 420: Pattern Matching for switch (Second Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you'll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 18-preview:

    export PMD_JAVA_OPTS=--enable-preview
    ./run.sh pmd -language java -version 18-preview ...
    

    Note: Support for Java 16 preview language features have been removed. The version "16-preview" is no longer available.

    Better XML XPath support

    The new rule class DomXPathRule is intended to replace usage of the XPathRule for XML rules. This rule executes the XPath query in a different way, which sticks to the XPath specification. This means the expression is interpreted the same way in PMD as in all other XPath development tools that stick to the standard. You can for instance test the expression in an online XPath editor.

    Prefer using this class to define XPath rules: replace the value of the class attribute with net.sourceforge.pmd.lang.xml.rule.DomXPathRule like so:

    <rule name="MyXPathRule"
          language="xml"
          message="A message"
          class="net.sourceforge.pmd.lang.xml.rule.DomXPathRule">
    
          <properties>
            <property name="xpath">
                <value><![CDATA[
                /a/b/c[@attr = "5"]
                ]]></value>
            </property>
            <!-- Note: the property "version" is ignored, remove it. The query is XPath 2. -->
          </properties>
    </rule>
    

    The rule is more powerful than XPathRule, as it can now handle XML namespaces, comments and processing instructions. Please refer to the Javadoc of DomXPathRule for information about the differences with XPathRule and examples.

    XPathRule is still perfectly supported for all other languages, including Apex and Java.

    New XPath functions

    The new XPath functions pmd:startLine, pmd:endLine, pmd:startColumn, and pmd:endColumn are now available in XPath rules for all languages. They replace the node attributes @BeginLine, @EndLine and such. These attributes will be deprecated in a future release.

    Please refer to the documentation of these functions for more information, including usage samples.

    Note that the function pmd:endColumn returns an exclusive index, while the attribute @EndColumn is inclusive. This is for forward compatibility with PMD 7, which uses exclusive end indices.

    New programmatic API

    This release introduces a new programmatic API to replace the inflexible PMD class. Programmatic execution of PMD should now be done with a PMDConfiguration and a PmdAnalysis, for instance:

    PMDConfiguration config = new PMDConfiguration();
    config.setDefaultLanguageVersion(LanguageRegistry.findLanguageByTerseName("java").getVersion("11"));
    config.setInputPaths("src/main/java");
    config.prependAuxClasspath("target/classes");
    config.setMinimumPriority(RulePriority.HIGH);
    config.addRuleSet("rulesets/java/quickstart.xml");
    config.setReportFormat("xml");
    config.setReportFile("target/pmd-report.xml");
    
    try (PmdAnalysis pmd = PmdAnalysis.create(config)) {
        // note: don't use `config` once a PmdAnalysis has been created.
        // optional: add more rulesets
        pmd.addRuleSet(pmd.newRuleSetLoader().loadFromResource("custom-ruleset.xml"));
        // optional: add more files
        pmd.files().addFile(Paths.get("src", "main", "more-java", "ExtraSource.java"));
        // optional: add more renderers
        pmd.addRenderer(renderer);
    
        // or just call PMD
        pmd.performAnalysis();
    }
    

    The PMD class still supports methods related to CLI execution: runPmd and main. All other members are now deprecated for removal. The CLI itself remains compatible, if you run PMD via command-line, no action is required on your part.

    Fixed Issues

    • apex
      • #3817: [apex] Add designer bindings to display main attributes
    • apex-performance
      • #3773: [apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe()
    • core
      • #2693: [ci] Add integration tests with real open-source projects
      • #3299: [core] Deprecate system properties of PMDCommandLineInterface
    • java
      • #3809: [java] Support JDK 18
    • doc
      • #2504: [doc] Improve "Edit me on github" button
      • #3812: [doc] Documentation website table of contents broken on pages with many subheadings
    • java-design
      • #3850: [java] ImmutableField - false negative when field assigned in constructor conditionally
      • #3851: [java] ClassWithOnlyPrivateConstructorsShouldBeFinal - false negative when a compilation unit contains two class declarations
    • xml
      • #2766: [xml] XMLNS prefix is not pre-declared in xpath query
      • #3863: [xml] Make XPath rules work exactly as in the XPath spec

    API Changes

    Deprecated API

    Experimental APIs

    External Contributions

    • #3773: [apex] EagerlyLoadedDescribeSObjectResult false positives with SObjectField.getDescribe() - @filiprafalowicz
    • #3811: [doc] Improve "Edit me on github" button - @btjiong
    • #3836: [doc] Make TOC scrollable when too many subheadings - @JerritEic

    Stats

    • 124 commits
    • 23 closed tickets & PRs
    • Days since last release: 29
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.44.0.zip(40.76 MB)
    pmd-doc-6.44.0.zip(5.41 MB)
    pmd-src-6.44.0.zip(15.14 MB)
  • pmd_releases/6.43.0(Feb 26, 2022)

    26-February-2022 - 6.43.0

    The PMD team is pleased to announce PMD 6.43.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Fixed Issues

    • core
      • #3427: [core] Stop printing CLI usage text when exiting due to invalid parameters
      • #3768: [core] SARIF formatter reports multiple locations when it should report multiple results
    • doc
      • #2502: [doc] Add floating table-of-contents (toc) on the right
      • #3807: [doc] Document Ant Task parameter threads
    • java
      • #3698: [java] Parsing error with try-with-resources and qualified resource
    • java-bestpractices
      • #3605: [java] SwitchStmtsShouldHaveDefault triggered when default case is present
    • java-codestyle
      • #278: [java] ConfusingTernary should treat != null as positive condition
    • java-performance
      • #3374: [java] UseStringBufferForStringAppends: Wrong example in documentation
    • misc
      • #3759: [lang-test] Upgrade dokka maven plugin to 1.4.32
    • plsql
      • #3746: [plsql] Parsing exception "Less than or equal to/Greater than or equal to" operators in DML statements

    API Changes

    Deprecated API

    Some API deprecations were performed in core PMD classes, to improve compatibility with PMD 7.

    • Report: the constructor and other construction methods like addViolation or createReport
    • RuleContext: all constructors, getters and setters. A new set of stable methods, matching those in PMD 7, was added to replace the addViolation overloads of AbstractRule. In PMD 7, RuleContext will be the API to report violations, and it can already be used as such in PMD 6.
    • The field configuration is unused and will be removed.

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    Changed API

    It is now forbidden to report a violation:

    • With a null node
    • With a null message
    • With a null set of format arguments (prefer a zero-length array)

    Note that the message is set from the XML rule declaration, so this is only relevant if you instantiate rules manually.

    RuleContext now requires setting the current rule before calling apply. This is done automatically by RuleSet#apply and such. Creating and configuring a RuleContext manually is strongly advised against, as the lifecycle of RuleContext will change drastically in PMD 7.

    External Contributions

    Stats

    • 49 commits
    • 22 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.43.0.zip(40.73 MB)
    pmd-doc-6.43.0.zip(5.39 MB)
    pmd-src-6.43.0.zip(15.08 MB)
  • pmd_releases/6.42.0(Jan 29, 2022)

    29-January-2022 - 6.42.0

    The PMD team is pleased to announce PMD 6.42.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Javascript: Rhino updated to latest version 1.7.14

    Rhino, the implementation of JavaScript we use for parsing JavaScript code, has been updated to the latest version 1.7.14. Now language features like template strings can be parsed. However Rhino does not support all features of the latest EcmaScript standard.

    New rules

    • The new Java rule FinalParameterInAbstractMethod detects parameters that are declared as final in interfaces or abstract methods. Declaring the parameters as final is useless because the implementation may choose to not respect it.
        <rule ref="category/java/codestyle.xml/FinalParameterInAbstractMethod" />
    

    The rule is part of the quickstart.xml ruleset.

    Modified rules

    • The Apex rule ApexDoc has a new property reportProperty. If set to false (default is true if unspecified) doesn't report missing ApexDoc comments on properties. It allows you to enforce ApexDoc comments for classes and methods without requiring them for properties.

    Fixed Issues

    • core
      • #3328: [core] designer.bat errors when JAVAFX_HOME contains spaces
    • java
      • #3698: [java] Error resolving Symbol Table
    • java-bestpractices
      • #3209: [java] UnusedPrivateMethod false positive with static method and cast expression
      • #3468: [java] UnusedPrivateMethod false positive when outer class calls private static method on inner class
    • java-design
      • #3679: [java] Make FinalFieldCouldBeStatic detect constant variable
    • java-errorprone
      • #3644: [java] InvalidLogMessageFormat: false positives with logstash structured logging
      • #3686: [java] ReturnEmptyCollectionRatherThanNull - false negative with conditioned returns
      • #3701: [java] MissingStaticMethodInNonInstantiatableClass false positive with method inner classes
      • #3721: [java] ReturnEmptyCollectionRatherThanNull - false positive with stream and lambda
    • java-performance
      • #3492: [java] UselessStringValueOf: False positive when there is no initial String to append to
      • #3639: [java] UseStringBufferLength: false negative with empty string variable
      • #3712: [java] InsufficientStringBufferDeclaration false positive with StringBuilder.setLength(0)
    • javascript
      • #3703: [javascript] Error - no Node adapter class registered for XmlPropRef

    API Changes

    No changes.

    External Contributions

    Stats

    • 88 commits
    • 35 closed tickets & PRs
    • Days since last release: 62
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.42.0.zip(40.73 MB)
    pmd-doc-6.42.0.zip(5.38 MB)
    pmd-src-6.42.0.zip(15.07 MB)
  • pmd_releases/6.41.0(Nov 27, 2021)

    27-November-2021 - 6.41.0

    The PMD team is pleased to announce PMD 6.41.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    GitHub Action for PMD

    PMD now has its own official GitHub Action: GitHub Action for PMD. It can execute PMD with your own ruleset against your project. It creates a SARIF report which is uploaded as a build artifact. Furthermore the build can be failed based on the number of violations.

    Feedback and pull requests are welcome at https://github.com/pmd/pmd-github-action.

    Last release in 2021

    This minor release will be the last one in 2021. The next release is scheduled to be end of January 2022.

    Fixed Issues

    • core
      • #2954: Create GitHub Action for PMD
      • #3424: [core] Migrate CLI to using GNU-style long options
      • #3425: [core] Add a --version CLI option
      • #3593: [core] Ant task fails with Java17
      • #3635: [ci] Update sample projects for regression tester
    • java-bestpractices
      • #3595: [java] PrimitiveWrapperInstantiation: no violation on 'new Boolean(val)'
      • #3613: [java] ArrayIsStoredDirectly doesn't consider nested classes
      • #3614: [java] JUnitTestsShouldIncludeAssert doesn't consider nested classes
      • #3618: [java] UnusedFormalParameter doesn't consider anonymous classes
      • #3630: [java] MethodReturnsInternalArray doesn't consider anonymous classes
    • java-design
      • #3620: [java] SingularField doesn't consider anonymous classes defined in non-private fields
    • java-errorprone
      • #3624: [java] TestClassWithoutTestCases reports wrong classes in a file
    • java-performance
      • #3491: [java] UselessStringValueOf: False positive when valueOf(char [], int, int) is used

    API Changes

    Command Line Interface

    The command line options for PMD and CPD now use GNU-syle long options format. E.g. instead of -rulesets the preferred usage is now --rulesets. Alternatively one can still use the short option -R. Some options also have been renamed to a more consistent casing pattern at the same time (--fail-on-violation instead of -failOnViolation). The old single-dash options are still supported but are deprecated and will be removed with PMD 7. This change makes the command line interface more consistent within PMD and also less surprising compared to other cli tools.

    The changes in detail for PMD:

    |old option |new option| |-------------------------------|----------| | -rulesets | --rulesets (or -R) | | -uri | --uri | | -dir | --dir (or -d) | | -filelist | --file-list | | -ignorelist | --ignore-list | | -format | --format (or -f) | | -debug | --debug | | -verbose | --verbose | | -help | --help | | -encoding | --encoding | | -threads | --threads | | -benchmark | --benchmark | | -stress | --stress | | -shortnames | --short-names | | -showsuppressed | --show-suppressed | | -suppressmarker | --suppress-marker | | -minimumpriority | --minimum-priority | | -property | --property | | -reportfile | --report-file | | -force-language | --force-language | | -auxclasspath | --aux-classpath | | -failOnViolation | --fail-on-violation | | --failOnViolation | --fail-on-violation | | -norulesetcompatibility | --no-ruleset-compatibility | | -cache | --cache | | -no-cache | --no-cache |

    The changes in detail for CPD:

    |old option |new option| |-----------------------|----------| | --failOnViolation | --fail-on-violation | | -failOnViolation | --fail-on-violation | | --filelist | --file-list |

    External Contributions

    Stats

    • 80 commits
    • 23 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.41.0.zip(42.69 MB)
    pmd-doc-6.41.0.zip(5.38 MB)
    pmd-src-6.41.0.zip(15.04 MB)
  • pmd_releases/6.40.0(Oct 30, 2021)

    30-October-2021 - 6.40.0

    The PMD team is pleased to announce PMD 6.40.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Updated Apex Support

    • The Apex language support has been bumped to version 54.0 (Spring '22).

    New rules

        <rule ref="category/apex/performance.xml/EagerlyLoadedDescribeSObjectResult" />
    

    Modified rules

    • The Apex rule ApexUnitTestClassShouldHaveAsserts has a new property additionalAssertMethodPattern. When specified the pattern is evaluated against each invoked method name to determine whether it represents a test assertion in addition to the standard names.

    • The Apex rule ApexDoc has a new property reportMissingDescription. If set to false (default is true if unspecified) doesn't report an issue if the @description tag is missing. This is consistent with the ApexDoc dialect supported by derivatives such as SfApexDoc and also with analogous documentation tools for other languages, e.g., JavaDoc, ESDoc/JSDoc, etc.

    • The Apex rule ApexCRUDViolation has a couple of new properties: These allow specification of regular-expression-based patterns for additional methods that should be considered valid for pre-CRUD authorization beyond those offered by the system Apex checks and ESAPI, e.g., sirono-common's AuthorizationUtil class. Two new properties have been added per-CRUD operation, one to specify the naming pattern for a method that authorizes that operation and another to specify the argument passed to that method that contains the SObjectType instance of the type being authorized. Here is an example of these new properties:

      <rule ref="category/apex/security.xml/ApexCRUDViolation" message="...">
        <priority>3</priority>
        <properties>
          <property name="createAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Createable|Upsertable)"/>
          <!--
           There's one of these properties for each operation, and the default value is 0 so this is technically
           superfluous, but it's included it here for example purposes.
           -->
          <property name="createAuthMethodTypeParamIndex" value="0"/>
          <property name="readAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Accessible"/>
          <property name="updateAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Updateable|Upsertable)"/>
          <property name="deleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Deletable"/>
          <property name="undeleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Undeletable"/>
          <property name="mergeAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Mergeable"/>
        </properties>
      </rule>
      
    • The Apex rule EmptyStatementBlock has two new properties:

      Setting reportEmptyPrivateNoArgConstructor to false ignores empty private no-arg constructors that are commonly used in singleton pattern implementations and utility classes in support of prescribed best practices.

      Setting reportEmptyVirtualMethod to false ignores empty virtual methods that are commonly used in abstract base classes as default no-op implementations when derived classes typically only override a subset of virtual methods.

      By default, both properties are true to not change the default behaviour of this rule.

    • The Apex rule EmptyCatchBlock has two new properties modeled after the analgous Java rule:

      The allowCommentedBlocks property, when set to true (defaults to false), ignores empty blocks containing comments, e.g.:

      try {
          doSomethingThatThrowsAnExpectedException();
          System.assert(false, 'Expected to catch an exception.');
      } catch (Exception e) {
          // Expected
      }
      

      The allowExceptionNameRegex property is a regular expression for exception variable names for which empty catch blocks should be ignored by this rule. For example, using the default property value of ^(ignored|expected)$, the following empty catch blocks will not be reported:

      try {
          doSomethingThatThrowsAnExpectedException();
          System.assert(false, 'Expected to catch an exception.');
      } catch (IllegalStateException ignored) {
      } catch (NumberFormatException expected) {
      }
      
    • The Apex rule OneDeclarationPerLine has a new property reportInForLoopInitializer: If set to false (default is true if unspecified) doesn't report an issue for multiple declarations in a for loop's initializer section. This is support the common idiom of one declaration for the loop variable and another for the loop bounds condition, e.g.,

      for (Integer i = 0, numIterations = computeNumIterations(); i < numIterations; i++) {
      }
      
    • The Java rule ClassNamingConventions uses a different default value of the property utilityClassPattern: This rule was detecting utility classes by default since PMD 6.3.0 and enforcing the naming convention that utility classes has to be suffixed with Util or Helper or Constants. However this turned out to be not so useful as a default configuration, as there is no standard naming convention for utility classes.

      With PMD 6.40.0, the default value of this property has been changed to [A-Z][a-zA-Z0-9]* (Pascal case), effectively disabling the special handling of utility classes. This is the same default pattern used for concrete classes.

      This means, that the feature to enforce a naming convention for utility classes is now a opt-in feature and can be enabled on demand.

      To use the old behaviour, the property needs to be configured as follows:

      <rule ref="category/java/codestyle.xml/ClassNamingConventions">
          <properties>
              <property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)" />
          </properties>
      </rule>
      

    Fixed Issues

    • apex
      • #1089: [apex] ApexUnitTestClassShouldHaveAsserts: Test asserts in other methods not detected
      • #1090: [apex] ApexCRUDViolation: checks not detected if done in another method
      • #3532: [apex] Promote usage of consistent getDescribe() info
      • #3566: [apex] ApexDoc rule should not require "@description"
      • #3568: [apex] EmptyStatementBlock: should provide options to ignore empty private constructors and empty virtual methods
      • #3569: [apex] EmptyCatchBlock: should provide an option to ignore empty catch blocks in test methods
      • #3570: [apex] OneDeclarationPerLine: should provide an option to ignore multiple declarations in a for loop initializer
      • #3576: [apex] ApexCRUDViolation should provide an option to specify additional patterns for methods that encapsulate authorization checks
      • #3579: [apex] ApexCRUDViolation: false negative with undelete
    • java-bestpractices
      • #3542: [java] MissingOverride: False negative for enum method
    • java-codestyle
      • #1595: [java] Discuss default for utility classes in ClassNamingConventions
      • #3563: [java] The ClassNamingConventionsRule false-positive's on the class name "Constants"
    • java-errorprone
      • #3560: [java] InvalidLogMessageFormat: False positive with message and exception in a block inside a lambda
    • java-performance
      • #2364: [java] AddEmptyString false positive in annotation value
    • java-security
      • #3368: [java] HardcodedCryptoKey false negative with variable assignments

    API Changes

    Experimental APIs

    • The interface ASTCommentContainer has been added to the Apex AST. It provides a way to check whether a node contains at least one comment. Currently this is only implemented for ASTCatchBlockStatement and used by the rule EmptyCatchBlock. This information is also available via XPath attribute @ContainsComment.

    External Contributions

    • #3538: [apex] New rule EagerlyLoadedDescribeSObjectResult - Jonathan Wiesel
    • #3549: [java] Ignore AddEmptyString rule in annotations - Stanislav Myachenkov
    • #3561: [java] InvalidLogMessageFormat: False positive with message and exception in a block inside a lambda - Nicolas Filotto
    • #3565: [doc] Fix resource leak due to Files.walk - lujiefsi
    • #3571: [apex] Fix for #1089 - Added new configuration property additionalAssertMethodPattern to ApexUnitTestClassShouldHaveAssertsRule - Scott Wells
    • #3572: [apex] Fix for #3566 - Added new configuration property reportMissingDescription to ApexDocRule - Scott Wells
    • #3573: [apex] Fix for #3568 - Added new configuration properties reportEmptyPrivateNoArgConstructor and reportEmptyVirtualMethod to EmptyStatementBlock - Scott Wells
    • #3574: [apex] Fix for #3569 - Added new configuration properties allowCommentedBlocks and allowExceptionNameRegex to EmptyCatchBlock - Scott Wells
    • #3575: [apex] Fix for #3570 - Added new configuration property reportInForLoopInitializer to OneDeclarationPerLine - Scott Wells
    • #3577: [apex] Fix for #3576 - Added new configuration properties *AuthMethodPattern and *AuthMethodTypeParamIndex to ApexCRUDViolation rule - Scott Wells
    • #3578: [apex] ApexCRUDViolation: Documentation changes for #3576 - Scott Wells
    • #3580: [doc] Release notes updates for the changes in issue #3569 - Scott Wells
    • #3581: [apex] #3569 - Requested changes for code review feedback - Scott Wells

    Stats

    • 72 commits
    • 37 closed tickets & PRs
    • Days since last release: 34
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.40.0.zip(42.71 MB)
    pmd-doc-6.40.0.zip(5.37 MB)
    pmd-src-6.40.0.zip(15.03 MB)
  • pmd_releases/6.39.0(Sep 25, 2021)

    25-September-2021 - 6.39.0

    The PMD team is pleased to announce PMD 6.39.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    All Contributors

    PMD follows the All Contributors specification. Contributions of any kind welcome!

    See credits for our complete contributors list.

    Fixed Issues

    • core
      • #3499: [core] Fix XPath rulechain with combined node tests
    • java-errorprone
      • #3493: [java] AvoidAccessibilityAlteration: add tests and fix rule
    • javascript
      • #3516: [javascript] NPE while creating rule violation when specifying explicit line numbers
    • plsql
      • #3487: [plsql] Parsing exception OPEN ref_cursor_name FOR statement
      • #3515: [plsql] Parsing exception SELECT...INTO on Associative Arrays Types

    API Changes

    No changes.

    External Contributions

    • #3516: [javascript] NPE while creating rule violation when specifying explicit line numbers - Kevin Guerra

    Stats

    • 37 commits
    • 10 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.39.0.zip(42.54 MB)
    pmd-doc-6.39.0.zip(5.36 MB)
    pmd-src-6.39.0.zip(14.86 MB)
  • pmd_releases/6.38.0(Aug 28, 2021)

    28-August-2021 - 6.38.0

    The PMD team is pleased to announce PMD 6.38.0.

    This is a minor release.

    Table Of Contents

    Fixed Issues

    • apex
      • #3462: [apex] SOQL performed in a for-each loop doesn't trigger ApexCRUDViolationRule
      • #3484: [apex] ApexCRUDViolationRule maintains state across files
    • core
      • #3446: [core] Allow XPath rules to access the current file name
    • java-bestpractices
      • #3403: [java] MethodNamingConventions junit5TestPattern does not detect parameterized tests

    External Contributions

    Stats

    • 32 commits
    • 8 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.38.0.zip(42.54 MB)
    pmd-doc-6.38.0.zip(4.46 MB)
    pmd-src-6.38.0.zip(13.91 MB)
  • pmd_releases/6.37.0(Jul 31, 2021)

    31-July-2021 - 6.37.0

    The PMD team is pleased to announce PMD 6.37.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Java 17 Support

    This release of PMD brings support for Java 17. PMD supports JEP 409: Sealed Classes which has been promoted to be a standard language feature of Java 17.

    PMD also supports JEP 406: Pattern Matching for switch (Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you'll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 17-preview:

    export PMD_JAVA_OPTS=--enable-preview
    ./run.sh pmd -language java -version 17-preview ...
    

    Note: Support for Java 15 preview language features have been removed. The version "15-preview" is no longer available.

    Updated PMD Designer

    This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog.

    New rules

    This release ships with 3 new Java rules.

        <rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation" />
    

    The rule is part of the quickstart.xml ruleset.

        <rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion" />
    

    The rule is part of the quickstart.xml ruleset.

        <rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull" />
    

    The rule is part of the quickstart.xml ruleset.

    Renamed rules

    • The Java rule MissingBreakInSwitch has been renamed to ImplicitSwitchFallThrough (category error prone) to better reflect the rule's purpose: The rule finds implicit fall-through cases in switch statements, which are most likely unexpected. The old rule name described only one way how to avoid a fall-through, namely using break but continue, throw and return avoid a fall-through as well. This enables us to improve this rule in the future.

    Deprecated rules

    Fixed Issues

    • apex
      • #3201: [apex] ApexCRUDViolation doesn't report Database class DMLs, inline no-arg object instantiations and inline list initialization
      • #3329: [apex] ApexCRUDViolation doesn't report SOQL for loops
    • core
      • #1603: [core] Language version comparison
      • #2133: [xml] Allow to check Salesforce XML Metadata using XPath rules
      • #3377: [core] NPE when specifying report file in current directory in PMD CLI
      • #3387: [core] CPD should avoid unnecessary copies when running with --skip-lexical-errors
    • java-bestpractices
      • #2908: [java] Merge Junit assertion simplification rules
      • #3235: [java] UseTryWithResources false positive when closeable is provided as a method argument or class field
    • java-errorprone
      • #3361: [java] Rename rule MissingBreakInSwitch to ImplicitSwitchFallThrough
      • #3382: [java] New rule ReturnEmptyCollectionRatherThanNull
    • java-performance
      • #3420: [java] NPE in InefficientStringBuffering with Records

    API Changes

    PMD CLI

    • PMD has a new CLI option -force-language. With that a language can be forced to be used for all input files, irrespective of filenames. When using this option, the automatic language selection by extension is disabled and all files are tried to be parsed with the given language. Parsing errors are ignored and unparsable files are skipped.

      This option allows to use the xml language for files, that don't use xml as extension. See also the examples on PMD CLI reference.

    Experimental APIs

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    External Contributions

    Stats

    • 82 commits
    • 29 closed tickets & PRs
    • Days since last release: 35
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.37.0.zip(42.53 MB)
    pmd-doc-6.37.0.zip(4.45 MB)
    pmd-src-6.37.0.zip(13.91 MB)
  • pmd_releases/6.36.0(Jun 26, 2021)

    26-June-2021 - 6.36.0

    The PMD team is pleased to announce PMD 6.36.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Improved Incremental Analysis

    Incremental Analysis has long helped our users obtain faster analysis results, however, its implementation tended to be too cautious in detecting changes to the runtime and type resolution classpaths, producing more cache invalidations than necessary. We have now improved the heuristics to remove several bogus invalidations, and slightly sped up the cache usage along the way.

    PMD will now ignore:

    • Non class files in classpath and jar / zip files being referenced.
    • Changes to the order of file entries within a jar / zip
    • Changes to file metadata within jar / zip (ie: creation and modification time, significant in multi-module / composite build projects where lateral artifacts are frequently recreated)

    New rules

    • The new Apex rule AvoidDebugStatements finds usages of System.debug calls. Debug statements contribute to longer transactions and consume Apex CPU time even when debug logs are not being captured. You can try out this rule like so:
        <rule ref="category/apex/performance.xml/AvoidDebugStatements" />
    
    • The new Apex rule InaccessibleAuraEnabledGetter checks that an AuraEnabled getter is public or global. This is necessary if it is referenced in Lightning components. You can try out this rule like so:
        <rule ref="category/apex/errorprone.xml/InaccessibleAuraEnabledGetter" />
    

    Renamed rules

    • The Java rule BadComparison has been renamed to ComparisonWithNaN to better reflect what the rule actually detects. It now considers usages of Double.NaN or Float.NaN in more cases and fixes false negatives.

    Fixed Issues

    • apex
      • #3307: [apex] Avoid debug statements since it impact performance
      • #3321: [apex] New rule to detect inaccessible AuraEnabled getters (summer '21 security update)
      • #3332: [apex] CognitiveComplexity - incorrect increment for "else if"
    • core
      • #2637: [cpd] Error Loading stylesheet cpdhtml.xslt
      • #3323: [core] Adds fullDescription and tags in SARIF report
    • java-bestpractices
      • #957: [java] GuardLogStatement: False positive with compile-time constant arguments
      • #3076: [java] UnusedAssignment reports unused variable when used in increment expr
      • #3114: [java] UnusedAssignment false positive when reporting unused variables
      • #3315: [java] LiteralsFirstInComparisons false positive with two constants
      • #3341: [java] JUnitTestsShouldIncludeAssert should support Junit 5
      • #3340: [java] NullPointerException applying rule GuardLogStatement
    • java-codestyle
      • #3317: [java] Update UnnecessaryImport to recognize usage of imported types in javadoc's @exception tag
    • java-errorprone
      • #2895: [java] Improve BadComparison and rename to ComparisonWithNaN
      • #3284: [java] InvalidLogMessageFormat may examine the value of a different but identically named String variable
      • #3304: [java] NPE in MoreThanOneLoggerRule on a java 16 record
      • #3305: [java] ConstructorCallsOverridableMethodRule IndexOutOfBoundsException on a java16 record
      • #3343: [java] CloneMethodMustImplementCloneable: FN with local classes
    • java-performance
      • #3331: [java] UseArraysAsList false negative with for-each loop
      • #3344: [java] InefficientEmptyStringCheck FN with trim.length on method call

    API Changes

    No changes.

    External Contributions

    • #3276: [apex] Update ApexCRUDViolation and OperationWithLimitsInLoop docs - Jonathan Wiesel
    • #3306: [java] More than one logger rule test null pointer exception - Arnaud Jeansen
    • #3317: [java] Update UnnecessaryImport to recognize usage of imported types in javadoc's @exception tag - Piotrek Żygieło
    • #3319: [apex] New AvoidDebugStatements rule to mitigate performance impact - Jonathan Wiesel
    • #3320: [java] Fix incorrect increment for "else if" branch in Cognitive Complexity docs - Denis Borovikov
    • #3322: [apex] added rule to detect inaccessible AuraEnabled getters - Philippe Ozil
    • #3323: [core] Adds fullDescription and tags in SARIF report - Clint Chester
    • #3339: [java] JUnitTestsShouldIncludeAssert Tweak assertion definition to avoid false positive with modern JUnit5 - Arnaud Jeansen

    Stats

    • 81 commits
    • 36 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.36.0.zip(42.46 MB)
    pmd-doc-6.36.0.zip(4.44 MB)
    pmd-src-6.36.0.zip(13.88 MB)
  • pmd_releases/6.35.0(May 29, 2021)

    29-May-2021 - 6.35.0

    The PMD team is pleased to announce PMD 6.35.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Javascript module now requires at least Java 8

    The latest version of Rhino, the implementation of JavaScript we use for parsing JavaScript code, requires at least Java 8. Therefore we decided to upgrade the pmd-javascript module to Java 8 as well. This means that from now on, a Java 8 or later runtime is required in order to analyze JavaScript code. Note that PMD core still only requires Java 7.

    New rules

    This release ships with 3 new Java rules.

        <rule ref="category/java/bestpractices.xml/JUnit5TestShouldBePackagePrivate" />
    
    • CognitiveComplexity uses the cognitive complexity metric to find overly complex code. This metric improves on the similar cyclomatic complexity in several ways, for instance, it incentivizes using clearly readable shorthands and idioms. See the rule documentation for more details. You can try out this rule like so:
        <rule ref="category/java/design.xml/CognitiveComplexity" />
    
    • MutableStaticState finds non-private static fields that are not final. These fields break encapsulation since these fields can be modified from anywhere within the program. You can try out this rule like so:
        <rule ref="category/java/design.xml/MutableStaticState" />
    

    Modified rules

    • The Java rule CompareObjectsWithEquals has now a new property typesThatCompareByReference. With that property, you can configure types, that should be whitelisted for comparison by reference. By default, java.lang.Enum and java.lang.Class are allowed, but you could add custom types here. Additionally comparisons against constants are allowed now. This makes the rule less noisy when two constants are compared. Constants are identified by looking for an all-caps identifier.

    Deprecated rules

    • The java rule DefaultPackage has been deprecated in favor of CommentDefaultAccessModifier.

      The rule "DefaultPackage" assumes that any usage of package-access is accidental, and by doing so, prohibits using a really fundamental and useful feature of the language.

      To satisfy the rule, you have to make the member public even if it doesn't need to, or make it protected, which muddies your intent even more if you don't intend the class to be extended, and may be at odds with other rules like AvoidProtectedFieldInFinalClass.

      The rule CommentDefaultAccessModifier should be used instead. It flags the same thing, but has an escape hatch.

    • The Java rule CloneThrowsCloneNotSupportedException has been deprecated without replacement.

      The rule has no real value as CloneNotSupportedException is a checked exception and therefore you need to deal with it while implementing the clone() method. You either need to declare the exception or catch it. If you catch it, then subclasses can't throw it themselves explicitly. However, Object.clone() will still throw this exception if the Cloneable interface is not implemented.

      Note, this rule has also been removed from the Quickstart Ruleset (rulesets/java/quickstart.xml).

    Fixed Issues

    • apex
      • #3183: [apex] ApexUnitTestMethodShouldHaveIsTestAnnotation false positive with helper method
      • #3243: [apex] Correct findBoundary when traversing AST
    • core
      • #2639: [core] PMD CLI output file is not created if directory or directories in path don't exist
      • #3196: [core] Deprecate ThreadSafeReportListener
    • doc
      • #3230: [doc] Remove "Edit me" button for language index pages
    • dist
      • #2466: [dist] Distribution archive doesn't include all batch scripts
    • java
      • #3269: [java] Fix NPE in MethodTypeResolution
    • java-bestpractices
      • #1175: [java] UnusedPrivateMethod FP with Junit 5 @MethodSource
      • #2219: [java] Document Reasons to Avoid Reassigning Parameters
      • #2737: [java] Fix misleading rule message on rule SwitchStmtsShouldHaveDefault with non-exhaustive enum switch
      • #3236: [java] LiteralsFirstInComparisons should consider constant fields (cont'd)
      • #3239: [java] PMD could enforce non-public methods for Junit5 / Jupiter test methods
      • #3254: [java] AvoidReassigningParameters reports violations on wrong line numbers
    • java-codestyle
      • #2655: [java] UnnecessaryImport false positive for on-demand imports
      • #3206: [java] Deprecate rule DefaultPackage
      • #3262: [java] FieldDeclarationsShouldBeAtStartOfClass: false negative with anon classes
      • #3265: [java] MethodArgumentCouldBeFinal: false negatives with interfaces and inner classes
      • #3266: [java] LocalVariableCouldBeFinal: false negatives with interfaces, anon classes
      • #3274: [java] OnlyOneReturn: false negative with anonymous class
      • #3275: [java] UnnecessaryLocalBeforeReturn: false negatives with lambda and anon class
    • java-design
      • #2780: [java] DataClass example from documentation results in false-negative
      • #2987: [java] New Rule: Public and protected static fields must be final
      • #2329: [java] Cognitive complexity rule for Java
    • java-errorprone
      • #3110: [java] Enhance CompareObjectsWithEquals with list of exceptions
      • #3112: [java] Deprecate rule CloneThrowsCloneNotSupportedException
      • #3205: [java] Make CompareObjectWithEquals allow comparing against constants
      • #3248: [java] Documentation is wrong for SingletonClassReturningNewInstance rule
      • #3249: [java] AvoidFieldNameMatchingTypeName: False negative with interfaces
      • #3268: [java] ConstructorCallsOverridableMethod: IndexOutOfBoundsException with annotations
    • java-performance
      • #1438: [java] InsufficientStringBufferDeclaration false positive for initial calculated StringBuilder size
    • javascript
      • #699: [javascript] Update Rhino library to 1.7.13
      • #2081: [javascript] Failing with OutOfMemoryError parsing a Javascript file

    API Changes

    Deprecated API

    External Contributions

    Stats

    • 143 commits
    • 53 closed tickets & PRs
    • Days since last release: 34
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.35.0.zip(42.45 MB)
    pmd-doc-6.35.0.zip(4.43 MB)
    pmd-src-6.35.0.zip(13.85 MB)
  • pmd_releases/6.34.0(Apr 24, 2021)

    24-April-2021 - 6.34.0

    The PMD team is pleased to announce PMD 6.34.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    New rules

    Modified rules

    • The Apex rule ApexCRUDViolation does not ignore getters anymore and also flags SOQL/SOSL/DML operations without access permission checks in getters. This will produce false positives now for VF getter methods, but we can't reliably detect, whether a getter is a VF getter or not. In such cases, the violation should be suppressed.

    Deprecated rules

    Fixed Issues

    • apex-performance
      • #3198: [apex] OperationWithLimitsInLoopRule: Support more limit consuming static method invocations
    • apex-security
      • #3202: [apex] ApexCRUDViolationRule fails to report CRUD violation on COUNT() queries
      • #3210: [apex] ApexCRUDViolationRule false-negative on non-VF getter
    • java-bestpractices
      • #3190: [java] Use StandardCharsets instead of Charset.forName
      • #3224: [java] UnusedAssignment crashes with nested records
    • java-codestyle
      • #3128: [java] New rule UnnecessaryImport, deprecate DuplicateImports, ImportFromSamePackage, UnusedImports
    • java-errorprone
      • #2757: [java] CloseResource: support Lombok's @Cleanup annotation
      • #3169: [java] CheckSkipResult: NPE when using pattern bindings

    API Changes

    No changes.

    External Contributions

    • #3193: [java] New rule: UseStandardCharsets - Andrea Aime
    • #3198: [apex] OperationWithLimitsInLoopRule: Support more limit consuming static method invocations - Jonathan Wiesel
    • #3211: [apex] ApexCRUDViolationRule: Do not assume method is VF getter to avoid CRUD checks - Jonathan Wiesel
    • #3234: [apex] ApexCRUDViolation: COUNT is indeed CRUD checkable since it exposes data (false-negative) - Jonathan Wiesel

    Stats

    • 74 commits
    • 18 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.34.0.zip(42.36 MB)
    pmd-doc-6.34.0.zip(4.43 MB)
    pmd-src-6.34.0.zip(13.82 MB)
  • pmd_releases/6.33.0(Mar 27, 2021)

    27-March-2021 - 6.33.0

    The PMD team is pleased to announce PMD 6.33.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    PLSQL parsing exclusions

    The PMD PLSQL parser might not parse every valid PL/SQL code without problems. In order to still use PMD on such files, you can now mark certain lines for exclusion from the parser. More information can be found in the language specific documentation for PLSQL.

    Fixed Issues

    • apex-design
      • #3142: [apex] ExcessiveClassLength multiple warning on the same class
    • java
      • #3117: [java] Infinite loop when parsing invalid code nested in lambdas
      • #3145: [java] Parse exception when using "record" as variable name
    • java-bestpractices
      • #3118: [java] UnusedPrivateMethod false positive when passing in lombok.val as argument
      • #3144: [java] GuardLogStatement can have more detailed example
      • #3155: [java] GuardLogStatement: False negative with unguarded method call
      • #3160: [java] MethodReturnsInternalArray does not consider static final fields and fields initialized with empty array
    • java-errorprone
      • #2977: [java] CloseResource: false positive with reassignment detection
      • #3146: [java] InvalidLogMessageFormat detection failing when String.format used
      • #3148: [java] CloseResource false positive with Objects.nonNull
      • #3165: [java] InvalidLogMessageFormat detection failing when String.format used in a variable
    • java-performance
      • #2427: [java] ConsecutiveLiteralAppend false-positive with builder inside lambda
      • #3152: [java] ConsecutiveLiteralAppends and InsufficientStringBufferDeclaration: FP with switch expressions
    • plsql
      • #195: [plsql] Ampersand '&' causes PMD processing error in sql file - Lexical error in file

    External Contributions

    • #3161: [plsql] Add support for lexical parameters in SQL*Plus scripts, allow excluding lines which the parser does not understand - Henning von Bargen
    • #3167: [java] Minor typo in quickstart ruleset - Austin Tice

    Stats

    • 49 commits
    • 27 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.33.0.zip(42.36 MB)
    pmd-doc-6.33.0.zip(4.41 MB)
    pmd-src-6.33.0.zip(13.80 MB)
  • pmd_releases/6.32.0(Feb 27, 2021)

    27-February-2021 - 6.32.0

    The PMD team is pleased to announce PMD 6.32.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Java 16 Support

    This release of PMD brings support for Java 16. PMD supports JEP 394: Pattern Matching for instanceof and JEP 395: Records. Both have been promoted to be a standard language feature of Java 16.

    PMD also supports JEP 397: Sealed Classes (Second Preview) as a preview language feature. In order to analyze a project with PMD that uses these language features, you'll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 16-preview:

    export PMD_JAVA_OPTS=--enable-preview
    ./run.sh pmd -language java -version 16-preview ...
    

    Note: Support for Java 14 preview language features have been removed. The version "14-preview" is no longer available.

    Modified Rules

    • The Apex rule ApexDoc has two new properties: reportPrivate and reportProtected. Previously the rule only considered public and global classes, methods, and properties. With these properties, you can verify the existence of ApexDoc comments for private and protected methods as well. By default, these properties are disabled to preserve backwards compatible behavior.

    Fixed Issues

    • apex-documentation
      • #3075: [apex] ApexDoc should support private access modifier
    • java
      • #3101: [java] NullPointerException when running PMD under JRE 11
    • java-bestpractices
      • #3132: [java] UnusedImports with static imports on subclasses
    • java-errorprone
      • #2716: [java] CompareObjectsWithEqualsRule: False positive with Enums
      • #3089: [java] CloseResource rule throws exception on spaces in property types
      • #3133: [java] InvalidLogMessageFormat FP with StringFormattedMessage and ParameterizedMessage
    • plsql
      • #3106: [plsql] ParseException while parsing EXECUTE IMMEDIATE 'drop database link ' || linkname;

    API Changes

    Experimental APIs

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    • The protected or public member of the Java rule AvoidUsingHardCodedIPRule are deprecated and considered to be internal API. They will be removed with PMD 7.

    External Contributions

    Stats

    • 43 commits
    • 21 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.32.0.zip(42.35 MB)
    pmd-doc-6.32.0.zip(4.41 MB)
    pmd-src-6.32.0.zip(13.78 MB)
  • pmd_releases/6.31.0(Jan 30, 2021)

    30-January-2021 - 6.31.0

    The PMD team is pleased to announce PMD 6.31.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    SARIF Format

    PMD now supports the Static Analysis Results Interchange Format (SARIF) as an additional report format. Just use the command line parameter -format sarif to select it. SARIF is an OASIS standard format for static analysis tools. PMD creates SARIF JSON files in SARIF version 2.1.0. An example report can be found in the documentation in Report formats for PMD.

    CPD

    • The C++ module now supports the new option --ignore-literal-sequences, which can be used to avoid detection of some uninteresting clones. This options has been introduced with PMD 6.30.0 for C# and is now available for C++ as well. See #2963.

    New Rules

    • The new Apex rule OverrideBothEqualsAndHashcode brings the well known Java rule to Apex. In Apex the same principle applies: equals and hashCode should always be overridden together to ensure collection classes such as Maps and Sets work as expected.

    • The new Visualforce rule VfHtmlStyleTagXss checks for potential XSS problems when using <style> tags on Visualforce pages.

    Deprecated rules

    • java-performance
      • AvoidUsingShortType: arithmetic on shorts is not significantly slower than on ints, whereas using shorts may provide significant memory savings in arrays.
      • SimplifyStartsWith: the suggested code transformation has an insignificant performance impact, and decreases readability.

    Fixed Issues

    • core
      • #2953: [core] Support SARIF JSON Format
      • #2970: [core] PMD 6.30.0 release is not reproducible
      • #2994: [core] Fix code climate severity strings
    • java-bestpractices
      • #575: [java] LiteralsFirstInComparisons should consider constant fields
      • #2454: [java] UnusedPrivateMethod violation for disabled class in 6.23.0
      • #2833: [java] NPE in UseCollectionIsEmptyRule with enums
      • #2876: [java] UnusedPrivateField cannot override ignored annotations property
      • #2957: [java] Ignore unused declarations that have special name
    • java-codestyle
      • #2960: [java] Thread issue in MethodNamingConventionsRule
    • java-design
      • #3006: [java] NPE in SingularFieldRule with concise resource syntax
    • java-errorprone
      • #2976: [java] CompareObjectsWithEquals: FP with array.length
      • #2977: [java] 6.30.0 introduces new false positive in CloseResource rule?
      • #2979: [java] UseEqualsToCompareStrings: FP with "var" variables
      • #3004: [java] UseEqualsToCompareStrings false positive with PMD 6.30.0
      • #3062: [java] CloseResource FP with reassigned stream
    • java-performance
      • #2296: [java] Deprecate rule AvoidUsingShortType
      • #2740: [java] Deprecate rule SimplifyStartsWith
      • #3088: [java] AvoidInstantiatingObjectsInLoops - false positive with Collections
    • vf-security
      • #3081: [vf] VfUnescapeEl: Inherently un-XSS-able built-in functions trigger false positives

    API Changes

    Deprecated API

    Experimental APIs

    • The method GenericToken#getKind has been added as experimental. This unifies the token interface for both JavaCC and Antlr. The already existing method AntlrToken#getKind is therefore experimental as well. The returned constant depends on the actual language and might change whenever the grammar of the language is changed.

    External Contributions

    Stats

    • 116 commits
    • 40 closed tickets & PRs
    • Days since last release: 49
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.31.0.zip(42.34 MB)
    pmd-doc-6.31.0.zip(4.41 MB)
    pmd-src-6.31.0.zip(13.75 MB)
  • pmd_releases/6.30.0(Dec 12, 2020)

    12-December-2020 - 6.30.0

    The PMD team is pleased to announce PMD 6.30.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    CPD

    • The C# module now supports the new option --ignore-literal-sequences, which can be used to avoid detection of some uninteresting clones. Support for other languages may be added in the future. See #2945

    • The Scala module now supports suppression through CPD-ON/CPD-OFF comment pairs. See #2929

    Type information for VisualForce

    The Visualforce AST now can resolve the data type of Visualforce expressions that reference Apex Controller properties and Custom Object fields. This feature improves the precision of existing rules, like VfUnescapeEl.

    This can be configured using two environment variables:

    • PMD_VF_APEXDIRECTORIES: Comma separated list of directories for Apex classes. Absolute or relative to the Visualforce directory. Default is ../classes. Specifying an empty string will disable data type resolution for Apex Controller properties.
    • PMD_VF_OBJECTSDIRECTORIES: Comma separated list of directories for Custom Objects. Absolute or relative to the Visualforce directory. Default is ../objects. Specifying an empty string will disable data type resolution for Custom Object fields.

    This feature is experimental, in particular, expect changes to the way the configuration is specified. We'll probably extend the CLI instead of relying on environment variables in a future version.

    Thanks to Jeff Bartolotta and Roopa Mohan for contributing this!

    Fixed Issues

    • core
      • #1939: [core] XPath expressions return handling
      • #1961: [core] Text renderer should include name of violated rule
      • #2874: [core] Fix XMLRenderer with UTF-16
    • cs
      • #2938: [cs] CPD: ignoring using directives could not be disabled
    • java
      • #2911: [java] ClassTypeResolver#searchNodeNameForClass leaks memory
      • #2934: [java] CompareObjectsWithEquals / UseEqualsToCompareStrings - False negatives with fields
      • #2940: [java] Catch additional TypeNotPresentExceptions / LinkageErrors
    • scala
      • #2480: [scala] Support CPD suppressions

    API Changes

    Deprecated API

    Around RuleSet parsing
    Around the PMD class

    Many classes around PMD's entry point (PMD) have been deprecated as internal, including:

    Miscellaneous

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    External Contributions

    Stats

    • 190 commits
    • 25 closed tickets & PRs
    • Days since last release: 49
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.30.0.zip(42.28 MB)
    pmd-doc-6.30.0.zip(4.40 MB)
    pmd-src-6.30.0.zip(13.70 MB)
  • pmd_releases/6.29.0(Oct 24, 2020)

    24-October-2020 - 6.29.0

    The PMD team is pleased to announce PMD 6.29.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Updated Apex Support

    New Rules

    • The new Apex rule OperationWithLimitsInLoop (apex-performance) finds operations in loops that may hit governor limits such as DML operations, SOQL queries and more. The rule replaces the three rules "AvoidDmlStatementsInLoops", "AvoidSoqlInLoops", and "AvoidSoslInLoops".

    Renamed Rules

    • The Java rule DoNotCallSystemExit has been renamed to DoNotTerminateVM, since it checks for all the following calls: System.exit(int), Runtime.exit(int), Runtime.halt(int). All these calls terminate the Java VM, which is bad, if the VM runs an application server which many independent applications.

    Deprecated Rules

    Fixed Issues

    • apex
      • #2839: [apex] Apex classes with safe navigation operator from Winter 21 (50.0) are skipped
    • apex-performance
      • #1713: [apex] Mark Database DML statements in For Loop
    • core
      • #2831: [core] Fix XMLRenderer newlines when running under IBM Java
    • java-errorprone
      • #2157: [java] Improve DoNotCallSystemExit: permit call in main(), flag System.halt
      • #2764: [java] CloseResourceRule does not recognize multiple assignment done to resource
    • miscellaneous
      • #2823: [doc] Renamed/Moved rules are missing in documentation
    • vf (Salesforce VisualForce)
      • #2765: [vf] Attributes with dot cause a VfParseException

    External Contributions

    Stats

    • 50 commits
    • 23 closed tickets & PRs
    • Days since last release: 27
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.29.0.zip(42.10 MB)
    pmd-doc-6.29.0.zip(4.40 MB)
    pmd-src-6.29.0.zip(13.63 MB)
  • pmd_releases/6.28.0(Sep 26, 2020)

    26-September-2020 - 6.28.0

    The PMD team is pleased to announce PMD 6.28.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    CPD's AnyTokenizer has been improved

    The AnyTokenizer is used for languages, that don't have an own lexer/grammar based tokenizer. AnyTokenizer now handles string literals and end-of-line comments. Fortran, Perl and Ruby have been updated to use AnyTokenizer instead of their old custom tokenizer based on AbstractTokenizer. See #2758 for details.

    AbstractTokenizer and the custom tokenizers of Fortran, Perl and Ruby are deprecated now.

    Fixed Issues

    • cpd

      • #2758: [cpd] Improve AnyTokenizer
      • #2760: [cpd] AnyTokenizer doesn't count columns correctly
    • apex-security

      • #2774: [apex] ApexSharingViolations does not correlate sharing settings with class that contains data access
    • java

      • #2738: [java] Custom rule with @ExhaustiveEnumSwitch throws NPE
      • #2755: [java] [6.27.0] Exception applying rule CloseResource on file ... java.lang.NullPointerException
      • #2756: [java] TypeTestUtil fails with NPE for anonymous class
      • #2767: [java] IndexOutOfBoundsException when parsing an initializer BlockStatement
      • #2783: [java] Error while parsing with lambda of custom interface
    • java-bestpractices

      • #2759: [java] False positive in UnusedAssignment
    • java-design

      • #2708: [java] False positive FinalFieldCouldBeStatic when using lombok Builder.Default

    API Changes

    Deprecated API

    For removal

    External Contributions

    • #2735: [ci] Add github actions for a fast view of pr succeed/not - XenoAmess
    • #2747: [java] Don't trigger FinalFieldCouldBeStatic when field is annotated with lombok @Builder.Default - Ollie Abbey
    • #2773: [java] issue-2738: Adding null check to avoid npe when switch case is default - Nimit Patel
    • #2789: Add badge for reproducible build - Dan Rollo
    • #2791: [apex] Analyze inner classes for sharing violations - Jeff Bartolotta

    Stats

    • 58 commits
    • 24 closed tickets & PRs
    • Days since last release: 25
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.28.0.zip(42.08 MB)
    pmd-doc-6.28.0.zip(4.39 MB)
    pmd-src-6.28.0.zip(13.61 MB)
  • pmd_releases/6.27.0(Aug 31, 2020)

    31-August-2020 - 6.27.0

    The PMD team is pleased to announce PMD 6.27.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Java 15 Support

    This release of PMD brings support for Java 15. PMD can parse Text Blocks which have been promoted to be a standard language feature of Java.

    PMD also supports Pattern Matching for instanceof, Records, and Sealed Classes.

    Note: The Pattern Matching for instanceof, Records, and Sealed Classes are all preview language features of OpenJDK 15 and are not enabled by default. In order to analyze a project with PMD that uses these language features, you'll need to enable it via the environment variable PMD_JAVA_OPTS and select the new language version 15-preview:

    export PMD_JAVA_OPTS=--enable-preview
    ./run.sh pmd -language java -version 15-preview ...
    

    Note: Support for Java 13 preview language features have been removed. The version "13-preview" is no longer available.

    Changes in how tab characters are handled

    In the past, tab characters in source files has been handled differently in different languages by PMD. For instance in Java, tab characters had a width of 8 columns, while C# used only 1 column. Visualforce instead used 4 columns.

    This has been unified now so that tab characters are consistently now always 1 column wide.

    This however might be a incompatible change, if you're using the properties "BeginColumn" or "EndColumn" additionally to "BeginLine" and "EndLine" of a Token/AST node in order to highlight where a rule violation occurred in the source file. If you have logic there that deals with tab characters, you most likely can remove this logic now, since tab characters are now just "normal" characters in terms of string processing.

    See also [all] Ensure PMD/CPD uses tab width of 1 for tabs consistently #2656.

    Updated PMD Designer

    This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog.

    New Rules

    • The new Java rule AvoidReassigningCatchVariables (java-bestpractices) finds cases where the variable of the caught exception is reassigned. This practice is surprising and prevents further evolution of the code like multi-catch.

    Modified Rules

    • The Java rule CloseResource (java-errorprone) has a new property closeNotInFinally. With this property set to true the rule will also find calls to close a resource, which are not in a finally-block of a try-statement. If a resource is not closed within a finally block, it might not be closed at all in case of exceptions.

      As this new detection would yield many new violations, it is disabled by default. It might be enabled in a later version of PMD.

    Deprecated Rules

    Fixed Issues

    • core
      • #724: [core] Avoid parsing rulesets multiple times
      • #1962: [core] Simplify Report API
      • #2653: [lang-test] Upgrade kotlintest to Kotest
      • #2656: [all] Ensure PMD/CPD uses tab width of 1 for tabs consistently
      • #2690: [core] Fix java7 compatibility
    • java
      • #2646: [java] Support JDK 15
    • java-bestpractices
      • #2471: [java] New Rule: AvoidReassigningCatchVariables
      • #2663: [java] NoClassDefFoundError on upgrade from 6.25.0 to 6.26.0
      • #2668: [java] UnusedAssignment false positives
      • #2673: [java] UnusedPrivateField and SingularField false positive with lombok annotation EqualsAndHashCode
      • #2684: [java] UnusedAssignment FP in try/catch
      • #2686: [java] UnusedAssignment must not flag abstract method parameters in interfaces and abstract classes
    • java-design
      • #2108: [java] [doc] ImmutableField rule: Description should clarify shallow immutability
      • #2461: [java] ExcessiveParameterListRule must ignore a private constructor
    • java-errorprone
      • #2264: [java] SuspiciousEqualsMethodName: Improve description about error-prone overloading of equals()
      • #2410: [java] ProperCloneImplementation not valid for final class
      • #2431: [java] InvalidLogMessageFormatRule throws IndexOutOfBoundsException when only logging exception message
      • #2439: [java] AvoidCatchingThrowable can not detect the case: catch (java.lang.Throwable t)
      • #2470: [java] CloseResource false positive when resource included in return value
      • #2531: [java] UnnecessaryCaseChange can not detect the case like: foo.equals(bar.toLowerCase())
      • #2647: [java] Deprecate rule DataFlowAnomalyAnalysis
    • java-performance
      • #1868: [java] false-positive for SimplifyStartsWith if string is empty
      • #2441: [java] RedundantFieldInitializer can not detect a special case for char initialize: char foo = '\0';
      • #2530: [java] StringToString can not detect the case: getStringMethod().toString()
    • dart
      • #2750: [dart] [cpd] Cpd Dart escaped dollar

    API Changes

    • XML rule definition in rulesets: In PMD 7, the language attribute will be required on all rule elements that declare a new rule. Some base rule classes set the language implicitly in their constructor, and so this is not required in all cases for the rule to work. But this behavior will be discontinued in PMD 7, so missing language attributes are now reported as a forward compatibility warning.

    Deprecated API

    For removal

    External Contributions

    Stats

    • 189 commits
    • 68 closed tickets & PRs
    • Days since last release: 37
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.27.0.zip(41.96 MB)
    pmd-doc-6.27.0.zip(4.39 MB)
    pmd-src-6.27.0.zip(13.89 MB)
  • pmd_releases/6.26.0(Jul 25, 2020)

    25-July-2020 - 6.26.0

    The PMD team is pleased to announce PMD 6.26.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    New Rules

    • The new Java rule UnusedAssignment (java-bestpractices) finds assignments to variables, that are never used and are useless. The new rule is supposed to entirely replace DataflowAnomalyAnalysis.

    Modified rules

    • The Java rule ArrayIsStoredDirectly (java-bestpractices) now ignores by default private methods and constructors. You can restore the old behavior by setting the new property allowPrivate to "false".

    Fixed Issues

    • apex
      • #2610: [apex] Support top-level enums in rules
    • apex-bestpractices
      • #2626: [apex] UnusedLocalVariable - false positive on case insensitivity allowed in Apex
    • apex-performance
      • #2598: [apex] AvoidSoqlInLoops false positive for SOQL with in For-Loop
    • apex-security
      • #2620: [visualforce] False positive on VfUnescapeEl with new Message Channel feature
    • core
      • #710: [core] Review used dependencies
      • #2594: [core] Update exec-maven-plugin and align it in all project
      • #2615: [core] PMD/CPD produces invalid XML (insufficient escaping/wrong encoding)
    • java-bestpractices
      • #2543: [java] UseCollectionIsEmpty can not detect the case this.foo.size()
      • #2569: [java] LiteralsFirstInComparisons: False negative for methods returning Strings
      • #2622: [java] ArrayIsStoredDirectly false positive with private constructor/methods
    • java-codestyle
      • #2546: [java] DuplicateImports reported for the same import... and import static...
    • java-design
      • #2174: [java] LawOfDemeter: False positive with 'this' pointer
      • #2181: [java] LawOfDemeter: False positive with indexed array access
      • #2189: [java] LawOfDemeter: False positive when casting to derived class
      • #2580: [java] AvoidThrowingNullPointerException marks all NullPointerException objects as wrong, whether or not thrown
      • #2625: [java] NPathComplexity can't handle switch expressions
    • java-errorprone
      • #2578: [java] AvoidCallingFinalize detects some false positives
      • #2634: [java] NullPointerException in rule ProperCloneImplementation
    • java-performance
      • #1736: [java] UseStringBufferForStringAppends: False positive if only one concatenation
      • #2207: [java] AvoidInstantiatingObjectsInLoops: False positive - should not flag objects when assigned to lists/arrays

    API Changes

    Deprecated API

    For removal

    External Contributions

    Stats

    • 156 commits
    • 43 closed tickets & PRs
    • Days since last release: 28
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.26.0.zip(42.12 MB)
    pmd-doc-6.26.0.zip(4.38 MB)
    pmd-src-6.26.0.zip(13.51 MB)
  • pmd_releases/6.25.0(Jun 27, 2020)

    27-June-2020 - 6.25.0

    The PMD team is pleased to announce PMD 6.25.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    Scala cross compilation

    Up until now the PMD Scala module has been compiled against scala 2.13 only by default. However, this makes it impossible to use pmd as a library in scala projects, that use scala 2.12, e.g. in sbt plugins. Therefore PMD now provides cross compiled pmd-scala modules for both versions: scala 2.12 and scala 2.13.

    The new modules have new maven artifactIds. The old artifactId net.sourceforge.pmd:pmd-scala:6.25.0 is still available, but is deprecated from now on. It has been demoted to be just a delegation to the new pmd-scala_2.13 module and will be removed eventually.

    The coordinates for the new modules are:

    <dependency>
        <groupId>net.sourceforge.pmd</groupId>
        <artifactId>pmd-scala_2.12</artifactId>
        <version>6.25.0</version>
    </dependency>
    
    <dependency>
        <groupId>net.sourceforge.pmd</groupId>
        <artifactId>pmd-scala_2.13</artifactId>
        <version>6.25.0</version>
    </dependency>
    

    The command line version of PMD continues to use scala 2.13.

    New Rules

    • The new Java Rule UnnecessaryCast (java-codestyle) finds casts that are unnecessary while accessing collection elements.

    • The new Java Rule AvoidCalendarDateCreation (java-performance) finds usages of java.util.Calendar whose purpose is just to get the current date. This can be done in a more lightweight way.

    • The new Java Rule UseIOStreamsWithApacheCommonsFileItem (java-performance) finds usage of FileItem.get() and FileItem.getString(). These two methods are problematic since they load the whole uploaded file into memory.

    Modified rules

    • The Java rule UseDiamondOperator (java-codestyle) now by default finds unnecessary usages of type parameters, which are nested, involve wildcards and are used within a ternary operator. These usages are usually only unnecessary with Java8 and later, when the type inference in Java has been improved.

      In order to avoid false positives when checking Java7 only code, the rule has the new property java7Compatibility, which is disabled by default. Settings this to "true" retains the old rule behaviour.

    Fixed Issues

    • apex-bestpractices
      • #2554: [apex] Exception applying rule UnusedLocalVariable on trigger
    • core
      • #971: [apex][plsql][java] Deprecate overly specific base rule classes
      • #2451: [core] Deprecate support for List attributes with XPath 2.0
      • #2599: [core] Fix XPath 2.0 Rule Chain Analyzer with Unions
      • #2483: [lang-test] Support cpd tests based on text comparison. For details see Testing your implementation in the developer documentation.
    • c#
      • #2551: [c#] CPD suppression with comments doesn't work
    • cpp
      • #1757: [cpp] Support unicode characters
    • java
      • #2549: [java] Auxclasspath in PMD CLI does not support relative file path
    • java-codestyle
      • #2545: [java] UseDiamondOperator false negatives
      • #2573: [java] DefaultPackage: Allow package default JUnit 5 Test methods
    • java-design
      • #2563: [java] UselessOverridingMethod false negative with already public methods
      • #2570: [java] NPathComplexity should mention the expected NPath complexity
    • java-errorprone
      • #2544: [java] UseProperClassLoader can not detect the case with method call on intermediate variable
    • java-performance
      • #2591: [java] InefficientStringBuffering/AppendCharacterWithChar: Fix false negatives with concats in appends
      • #2600: [java] UseStringBufferForStringAppends: fix false negative with fields
    • scala
      • #2547: [scala] Add cross compilation for scala 2.12 and 2.13

    API Changes

    • The maven module net.sourceforge.pmd:pmd-scala is deprecated. Use net.sourceforge.pmd:pmd-scala_2.13 or net.sourceforge.pmd:pmd-scala_2.12 instead.

    • Rule implementation classes are internal API and should not be used by clients directly. The rules should only be referenced via their entry in the corresponding category ruleset (e.g. <rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" />).

      While we definitely won't move or rename the rule classes in PMD 6.x, we might consider changes in PMD 7.0.0 and onwards.

    Deprecated APIs

    Internal API

    Those APIs are not intended to be used by clients, and will be hidden or removed with PMD 7.0.0. You can identify them with the @InternalApi annotation. You'll also get a deprecation warning.

    For removal

    External Contributions

    Stats

    • 135 commits
    • 31 closed tickets & PRs
    • Days since last release: 33
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.25.0.zip(59.53 MB)
    pmd-doc-6.25.0.zip(4.38 MB)
    pmd-src-6.25.0.zip(14.42 MB)
  • pmd_releases/6.24.0(May 24, 2020)

    24-May-2020 - 6.24.0

    The PMD team is pleased to announce PMD 6.24.0.

    This is a minor release.

    Table Of Contents

    New and noteworthy

    CPD now supports XML as well

    Thanks to Fernando Cosso CPD can now find duplicates in XML files as well. This is useful to find duplicated sections in XML files.

    Updated PMD Designer

    This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog.

    New Rules

    • The new Java Rule LiteralsFirstInComparisons (java-bestpractices) find String literals, that are used in comparisons and are not positioned first. Using the String literal as the receiver of e.g. equals helps to avoid NullPointerExceptions.

      This rule is replacing the two old rules PositionLiteralsFirstInComparisons and PositionLiteralsFirstInCaseInsensitiveComparisons and extends the check for the methods compareTo, compareToIgnoreCase and contentEquals in addition to equals and equalsIgnoreCase.

      Note: This rule also replaces the two mentioned rules in Java's quickstart ruleset.

    Deprecated Rules

    Fixed Issues

    • apex-bestpractices
      • #2468: [apex] Unused Local Variable fails on blocks
    • core
      • #2444: [core] Support reproducible builds
      • #2484: [core] Update maven-enforcer-plugin to require Java 118
    • c#
      • #2495: [c#] Support for interpolated verbatim strings
    • java
      • #2472: [java] JavaCharStream throws an Error on invalid escape
    • java-bestpractices
      • #2145: [java] Deprecate rules PositionLiteralsFirstIn(CaseInsensitive)Comparisons in favor of LiteralsFirstInComparisons
      • #2288: [java] JUnitTestsShouldIncludeAssert: Add support for Hamcrest MatcherAssert.assertThat
      • #2437: [java] AvoidPrintStackTrace can't detect the case e.getCause().printStackTrace()
    • java-codestyle
      • #2476: [java] MethodNamingConventions - Add support for JUnit 5 method naming
    • java-errorprone
      • #2477: [java] JUnitSpelling false-positive for JUnit5/4 tests
    • swift
      • #2473: [swift] Swift 5 (up to 5.2) support for CPD

    API Changes

    Deprecated APIs

    Experimental APIs

    Note: Experimental APIs are identified with the annotation Experimental, see its javadoc for details

    External Contributions

    Stats

    • 114 commits
    • 29 closed tickets & PRs
    • Days since last release: 30
    Source code(tar.gz)
    Source code(zip)
    pmd-bin-6.24.0.zip(59.52 MB)
    pmd-doc-6.24.0.zip(4.37 MB)
    pmd-src-6.24.0.zip(14.25 MB)
A static analyzer for Java, C, C++, and Objective-C

Infer Infer is a static analysis tool for Java, C++, Objective-C, and C. Infer is written in OCaml. Installation Read our Getting Started page for det

Facebook 13.7k Dec 28, 2022
Java bytecode static analyzer

This project is abandoned and unlikely will be supported in future HuntBugs 0.0.11 New Java bytecode static analyzer tool based on Procyon Compiler To

Tagir Valeev 302 Aug 13, 2022
mobsfscan is a static analysis tool that can find insecure code patterns in your Android and iOS source code.

mobsfscan is a static analysis tool that can find insecure code patterns in your Android and iOS source code. Supports Java, Kotlin, Swift, and Objective C Code. mobsfscan uses MobSF static analysis rules and is powered by semgrep and libsast pattern matcher.

Mobile Security Framework 347 Dec 29, 2022
SpotBugs is FindBugs' successor. A tool for static analysis to look for bugs in Java code.

SpotBugs is the spiritual successor of FindBugs, carrying on from the point where it left off with support of its community. SpotBugs is licensed unde

null 2.9k Jan 4, 2023
Java library for parsing report files from static code analysis.

Violations Lib This is a Java library for parsing report files like static code analysis. Example of supported reports are available here. A number of

Tomas Bjerre 127 Nov 23, 2022
Tackle Data-intensive Validity Analyzer

Tackle-DiVA (Data-intensive Validity Analyzer) Tackle-DiVA is a command-line tool for data-centric application analysis. It imports a set of target ap

Konveyor 38 Oct 31, 2022
A tool to help eliminate NullPointerExceptions (NPEs) in your Java code with low build-time overhead

NullAway: Fast Annotation-Based Null Checking for Java NullAway is a tool to help eliminate NullPointerExceptions (NPEs) in your Java code. To use Nul

Uber Open Source 3.2k Dec 29, 2022
Inria 1.4k Dec 29, 2022
OpenGrok is a fast and usable source code search and cross reference engine, written in Java

Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved. OpenGrok - a wicked fast source browser OpenGrok - a wicked fast source br

Oracle 3.8k Jan 8, 2023
Astra: a Java tool for analysing and refactoring Java source code

What is Astra? Astra is a Java tool for analysing and refactoring Java source code. For example: "References to type A should instead reference type B

Alfa 51 Dec 26, 2022
Reformats Java source code to comply with Google Java Style.

google-java-format google-java-format is a program that reformats Java source code to comply with Google Java Style. Using the formatter from the comm

Google 4.8k Dec 31, 2022
:coffee: SonarSource Static Analyzer for Java Code Quality and Security

Code Quality and Security for Java This SonarSource project is a code analyzer for Java projects. Information about the analysis of Java features is a

SonarSource 976 Jan 5, 2023
A static analyzer for Java, C, C++, and Objective-C

Infer Infer is a static analysis tool for Java, C++, Objective-C, and C. Infer is written in OCaml. Installation Read our Getting Started page for det

Facebook 13.7k Dec 28, 2022
Java bytecode static analyzer

This project is abandoned and unlikely will be supported in future HuntBugs 0.0.11 New Java bytecode static analyzer tool based on Procyon Compiler To

Tagir Valeev 302 Aug 13, 2022
Code metrics for Java code by means of static analysis

CK CK calculates class-level and method-level code metrics in Java projects by means of static analysis (i.e. no need for compiled code). Currently, i

Maurício Aniche 286 Jan 4, 2023
mobsfscan is a static analysis tool that can find insecure code patterns in your Android and iOS source code.

mobsfscan is a static analysis tool that can find insecure code patterns in your Android and iOS source code. Supports Java, Kotlin, Swift, and Objective C Code. mobsfscan uses MobSF static analysis rules and is powered by semgrep and libsast pattern matcher.

Mobile Security Framework 347 Dec 29, 2022
SpotBugs is FindBugs' successor. A tool for static analysis to look for bugs in Java code.

SpotBugs is the spiritual successor of FindBugs, carrying on from the point where it left off with support of its community. SpotBugs is licensed unde

null 2.9k Jan 4, 2023
Java library for parsing report files from static code analysis.

Violations Lib This is a Java library for parsing report files like static code analysis. Example of supported reports are available here. A number of

Tomas Bjerre 127 Nov 23, 2022
Firehose is an extensible, no-code, and cloud-native service to load real-time streaming data from Kafka to data stores, data lakes, and analytical storage systems.

Firehose - Firehose is an extensible, no-code, and cloud-native service to load real-time streaming data from Kafka to data stores, data lakes, and analytical storage systems.

Open DataOps Foundation 279 Dec 22, 2022