Skip to Content

This blog post will guide you through the static code checks performed by SAP S/4HANA Cloud SDK Pipeline as part of the Continuous integration and delivery (CI-CD) process.

Note: This post is part of a series. For a complete overview please visit the SAP S/4HANA Cloud SDK Overview.

 

Goal of this blog post

By the end of this article you will have an overview of the static code checks stage and configuration involved. You should also be able to analyze the log and identify the cause of the failure of a pipeline execution.

This tutorial will cover the following areas

  1. Introduction to static code check
  2. Static code check stage in CI-CD
  3. Why use both FindBugs and PMD
  4. Static code checks by FindBugs
  5. Static code checks by PMD

For a better understanding of this article, we suggest you to read the following tutorials first:

Step 14 with SAP S/4HANA Cloud SDK: Continuous integration and delivery

Introduction to static code check

Analyzing the source code for detecting bugs and vulnerabilities is an important stage in a software development life cycle (SDLC). Bugs that are detected in an early stage of SDLC can be fixed easily than that are identified in later stages such as bugs identified in a productive environment. Static code analysis and Dynamic code analysis are the two widely used code analysis techniques in an enterprise software development.

Static code check is a systematic way of examining the application code base for identifying potential bugs that may arise during run-time. It is performed either on source code or on the binaries which are generated after compilation. Static code check with its whitebox visibility can analysis entire application and detect bugs before executing the application.

Dynamic code analysis tools on the other hand are used to analyze system which is already in operation state and it can identify bugs that are too complicated for static code analysis. However, the scope of the dynamic code analysis is limited to the block of code that is in execution state.

Static code check stage in CI-CD

SAP S/4HANA Cloud SDK Pipeline performs the static code checks of the application code in order to achieve highest quality in the deliverable artifact. This is executed in parallel with the unit and integration test stages as you can see in the following figure. This stage currently examines code base with the help of two widely used static code analysis software namely FindBugs and PMD. Following sections will elaborate the configuration of these software in detail in a SAP S/4HANA Cloud SDK Pipeline context.

Why use both FindBugs and PMD?

PMD performs static code analysis on source code level where as FindBugs uses bytecode for analysis. PMD can identify issues like usage of == instead of equals where as FindBugs can help identifying improper implementation of equals method.  Even though, both FindBugs and PMD overlaps on reporting few issues they largely complement each other. Hence, SAP S/4HANA Cloud SDK Pipeline makes use of the capabilities of both of these tools.

Static code checks by FindBugs

FindBugs is an open source software which performs static code analysis on Java programs to identify bugs. You can run FindBugs against your source code by using Command Line Interface (CLI) or with the help of maven plugin. FindBugs can also be integrated with most of the commonly used IDEs and with Jenkins as an additional plugin.

While using Jenkins server which is setup by cx-server script, the FindBugs plugin is already installed for you. However, if you are using different Jenkins server then FindBugs plugin needs to be installed prior executing SAP S/4HANA Cloud SDK Pipeline.

Execution as a maven goal

FindBugs can be locally executed as a maven goal with the below command in your project root directory. This will generate a bug report under the target directory with name findbugsXml.xml.

$ mvn clean install findbugs:findbugs

FIndBugs can also be customized to include or whitelist some of the bugs during analysis. This can be achieved through the Filter Files which can be provided as an argument.

$ mvn clean install findbugs:findbugs -Dfindbugs.includeFilterFile=includeFilter.xml -Dfindbugs.excludeFilterFile=excludeFilter.xml

FindBugs as a Pipeline stage

SAP S/4HANA Cloud SDK Pipeline executes FindBugs plugin during static code checks. The include filter file used by the pipeline can be found here and the bug descriptions of individual filters can be found here. SAP S/4HANA Cloud SDK Pipeline has a zero tolerance to major bugs hence execution of the pipeline will be marked as FAILURE if there is any major bug in the code or as many as 10 minor bugs. You will see a FindBugs trend graph on job dashboard of your Cx server. Intuitively red line in the graph indicates major bugs where as yellow line indicates minor bugs.

Pipeline execution log upon any major bug discovery may look similar to the following.

[Pipeline] findbugs
12:38:58 [FINDBUGS] Collecting findbugs analysis files...
12:38:58 [FINDBUGS] Searching for all files in /var/jenkins_home/workspace/Controller-CF_test_findbugs that match the pattern **/findbugsXml.xml
12:38:58 [FINDBUGS] Parsing 1 file in /var/jenkins_home/workspace/Controller-CF_test_findbugs
12:38:58 [FINDBUGS] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_findbugs/application/target/findbugsXml.xml with 3 unique warnings and 0 duplicates.
12:38:58 Skipping warnings blame since pipelines do not have an SCM link.%n
12:38:58 [FINDBUGS] Computing warning deltas based on reference build #24
12:38:58 [FINDBUGS] Plug-in Result: Failed - <a href="findbugsResult">2 warnings</a> of <a href="findbugsResult/HIGH">priority High</a> exceed the threshold of 0 by 2
[Pipeline] fileExists
[Pipeline] dir
12:38:58 Running in /var/jenkins_home/workspace/Controller-CF_test_findbugs/s4hana_pipeline/reports
[Pipeline] {
[Pipeline] sh
12:38:58 [reports] Running shell script
12:38:59 + cp -p /var/jenkins_home/workspace/Controller-CF_test_findbugs/application/target/findbugsXml.xml .
[Pipeline] }
[Pipeline] // dir
[Pipeline] echo
12:38:59 --- END LIBRARY STEP: checkFindbugs.groovy ---
[Pipeline] echo
12:38:59 Current build result: FAILURE
[Pipeline] error
[Pipeline] echo
12:38:59 ----------------------------------------------------------
12:38:59 --- ERROR OCCURED IN LIBRARY STEP: executeStaticCodeChecks
12:38:59 ----------------------------------------------------------
12:38:59 
12:38:59 FOLLOWING PARAMETERS WERE AVAILABLE TO THIS STEP:
12:38:59 ***
12:38:59 [script:WorkflowScript@73c0cbf3]
12:38:59 ***
12:38:59 
12:38:59 ERROR WAS:
12:38:59 ***
12:38:59 hudson.AbortException: Build was ABORTED and marked as FAILURE, please examine static code check results.
12:38:59 ***
12:38:59 
12:38:59 
[Pipeline] echo
12:38:59 --- END LIBRARY STEP: executeStaticCodeChecks.groovy ---
GitHub has been notified of this commit’s build result

ERROR: Build was ABORTED and marked as FAILURE, please examine static code check results.
Finished: FAILURE

Troubleshooting

Once the FindBugs reports any bug, you can get additional details about the file and about the block of code which resulted in the failure of the check by clicking on the FindBugs trend graph. Upon clicking on the graph you will be navigated to detailed view as shown in the below image.

Click on the source file name to see the reason for the warning and the source code which needs a fix.

 

Upon fixing the bugs, a successful FindBugs analysis log will look like below.

[Pipeline] findbugs
12:36:24 [FINDBUGS] Collecting findbugs analysis files...
12:36:24 [FINDBUGS] Searching for all files in /var/jenkins_home/workspace/Controller-CF_test_findbugs that match the pattern **/findbugsXml.xml
12:36:24 [FINDBUGS] Parsing 1 file in /var/jenkins_home/workspace/Controller-CF_test_findbugs
12:36:24 [FINDBUGS] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_findbugs/application/target/findbugsXml.xml with 0 unique warnings and 0 duplicates.
12:36:24 Skipping warnings blame since pipelines do not have an SCM link.%n
12:36:24 [FINDBUGS] Computing warning deltas based on reference build #23
12:36:24 [FINDBUGS] Ignore new warnings since this is the first valid build
12:36:24 [FINDBUGS] Plug-in Result: Success - no threshold has been exceeded

Configuration

SAP S/4HANA Cloud SDK Pipeline requires no configuration in the project level to execute FindBugs. However, if a bug which is identified by FindBugs has to be reclassified with different priority in your project then you can configure the same as part of Exclude filter. An example FindBugs exclude filter file excludeFilter.xmlis shown below.

<FindBugsFilter>
<Match>
       <Class name="com.foobar.MyClass" />
       <Method name="someMethod" />
       <Bug pattern="IJU_NO_TESTS" />
       <Priority value="2" />
</Match>
</FindBugsFilter>

Once you create such an Exclude filter file, configure your pipeline_config.yml file by adding below configuration in steps block.

steps:
checkFindbugs:
   excludeFilterFile : excludeFilter.xml

Static code checks by PMD

Like FindBugs, PMD is also an open source static code analysis tool. PMD performs static code analysis on source code instead of bytecode. Every violation of standard coding practice is classified as one of the five priorities where priority 1 signifies the critical violation and 5 can be considered as a minor violation. You will see a PMD trend graph on your Cx server job dashboard after execution of the pipeline that would look similar to the following image.

Execution as a maven goal

You can also execute PMD against the source code by invoking maven plugin. However, this will not check SAP specific rules.

$ mvn clean install pmd:pmd 

PMD as part of Pipeline

Execution of PMD as part of SAP S/4HANA Cloud SDK Pipeline will performs SAP specific static code analysis on the source code in addition to standard PMD rules. In order to achive this, PMD has been extended as a custom plugin which is distributed along with SAP S/4HANA Cloud SDK. Below are the list of quality rules used by SAP S/4HANA Cloud SDK Pipeline during PMD static code checks.

OnlyUseCloudLoggerFactoryRule

The CloudLogger helps to log all important result in a way that it can be easily consumed by the SAP Cloud Platform. When instantiating a logger only use the CloudLoggerFactory which is provided by the SDK. Logging on SAP S/4HANA Cloud SDK provides an overview about logging mechanism in SDK. This rule has a priority of 2.

Example:

//Use 
private static final Logger logger = CloudLoggerFactory.getLogger(Foo.class);

//Instead of 
private static final Logger logger = LoggerFactory.getLogger(Foo.class);

HandleExceptionsRule

In order to allow postmortem analyzability of the application it is important to log the exception in the catch block or in a called handling method or referencing the exception it in a new thrown exception. This rule has a priority of 1.

// Use
protected List<Foo> convertResult (Result result){
    try {
      return result.asList(Foo.class);
    } catch (final Exception e) {
      throw new CustomExceptionHandler(e); // Use own exception handler to deal with exception object 'e'
    }
}

//Instead of
protected List<Foo> convertResult (Result result){
    try {
      return result.asList(Foo.class);
    } catch (final Exception e) {
      handleException();
    }
}

ReferenceExceptionRule

If you log an error or warning in an exception you should reference the exception object in your logger entry. This rule has a priority of 2.

// Use
protected List<Foo> convertResult (Result result){
    try {
      return result.asList(Foo.class);
    } catch (final Exception e) {
      logger.warn("Some exception happened", e);
    }
}

//Instead of
protected List<Foo> convertResult (Result result){
    try {
      return result.asList(Foo.class);
    } catch (final Exception e) {
      logger.warn("Some exception happened");
    }
}

 

UseSdkPlatformAbstractionsRule

SAP S/4HANA cloud SDK provides abstraction to access some platform level information such as

  • Cloud platform environment
  • Destination and connectivity services
  • Tenant context
  • User context
  • Audit logging

For a complete list of platform abstraction and examples please visit blog post on Cloud Platform Abstractions. In order to allow a smooth transition from Neo to Cloud Foundry you should use the platform abstractions provided by the SAP S/4HANA Cloud SDK. This rule has a priority of 2.

Generic PMD rules

In addition to SAP specific rules, generic quality rules from PMD is also being used by the pipeline. They are listed below. These rules are subset of rules of PMD which can be found here.

  • rulesets/java/basic.xml/BrokenNullCheck
  • rulesets/java/basic.xml/MisplacedNullCheck
  • rulesets/java/basic.xml/ReturnFromFinallyBlock
  • rulesets/java/basic.xml/UnconditionalIfStatement
  • rulesets/java/clone.xml/CloneThrowsCloneNotSupportedException
  • rulesets/java/design.xml/AvoidInstanceofChecksInCatchClause
  • rulesets/java/design.xml/NonCaseLabelInSwitchStatement
  • rulesets/java/design.xml/PreserveStackTrace
  • rulesets/java/empty.xml/EmptyCatchBlock
  • rulesets/java/imports.xml/UnusedImports
  • rulesets/java/logging-java.xml/LoggerIsNotStaticFinal
  • rulesets/java/logging-java.xml/MoreThanOneLogger
  • rulesets/java/logging-java.xml/SystemPrintln
  • rulesets/java/strictexception.xml/AvoidThrowingNewInstanceOfSameException
  • rulesets/java/strictexception.xml/AvoidThrowingNullPointerException
  • rulesets/java/strictexception.xml/AvoidThrowingRawExceptionTypes
  • rulesets/java/strictexception.xml/DoNotThrowExceptionInFinally
  • rulesets/java/strictexception.xml/SignatureDeclareThrowsException
  • rulesets/java/sunsecure.xml/MethodReturnsInternalArray

 

A log entry of your pipeline will look similar to the extract of the log below.

[Pipeline] pmd
11:56:49 [PMD] Collecting PMD analysis files...
11:56:50 [PMD] Searching for all files in /var/jenkins_home/workspace/Controller-CF_test_PMD that match the pattern **/target/pmd.xml
11:56:50 [PMD] Parsing 3 files in /var/jenkins_home/workspace/Controller-CF_test_PMD
11:56:50 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/application/target/pmd.xml with 4 unique warnings and 0 duplicates.
11:56:50 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/integration-tests/target/pmd.xml with 4 unique warnings and 0 duplicates.
11:56:50 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/unit-tests/target/pmd.xml with 4 unique warnings and 0 duplicates.
11:56:50 Skipping warnings blame since pipelines do not have an SCM link.%n
11:56:50 [PMD] Computing warning deltas based on reference build #33
11:56:50 [PMD] Plug-in Result: Failed - <a href="pmdResult">1 warning</a> of <a href="pmdResult/HIGH">priority High</a> exceeds the threshold of 0 by 1
[Pipeline] echo
11:56:50 --- END LIBRARY STEP: checkPmd.groovy ---

 

Troubleshooting

Once you encounter a failure in the pipeline due to PMD analysis, you can visit the build dashboard of your Cx server which will contain the summary of the PMD scan along with the PMD graph.

 

SAP S/4HANA Cloud SDK Pipeline has zero tolerance for any major violation. When PMD scan fails, kindly look in to the analysis details either by clicking on the PMD warning icon  or on the PMD Trend graph to get additional details on the reported issues. Upon clicking on the icon you will be navigated to a detailed view of analysis report.

Click on the source file of your interest and navigate to Details tab to check the root cause of the error.

 

 

 

 

 

 

Upon fixing the bugs, a successful PMD analysis log will look like below.

[Pipeline] pmd
12:13:22 [PMD] Collecting PMD analysis files...
12:13:22 [PMD] Searching for all files in /var/jenkins_home/workspace/Controller-CF_test_PMD that match the pattern **/target/pmd.xml
12:13:22 [PMD] Parsing 3 files in /var/jenkins_home/workspace/Controller-CF_test_PMD
12:13:22 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/application/target/pmd.xml with 3 unique warnings and 0 duplicates.
12:13:22 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/integration-tests/target/pmd.xml with 3 unique warnings and 0 duplicates.
12:13:22 [PMD] Successfully parsed file /var/jenkins_home/workspace/Controller-CF_test_PMD/unit-tests/target/pmd.xml with 3 unique warnings and 0 duplicates.
12:13:22 Skipping warnings blame since pipelines do not have an SCM link.%n
12:13:22 [PMD] Computing warning deltas based on reference build #35
12:13:22 [PMD] Plug-in Result: Success - no threshold has been exceeded

Configuration

SAP S/4HANA Cloud SDK Pipeline requires no configuration in the project level to execute PMD. However, like FindBugs you can whitelist files from PMD scan by configuring them in Stage configuration of the pipeline_config.yml file.

stages:
  staticCodeChecks:
    findbugsExcludesFile: '' #Path to findbugs exclude file
    pmdExcludes: '**/*Manifest.java' # List or ANT style patterns

Conclusion

Static code analysis help you to improve the quality of the code and avoid propagation of bugs to later stages of the SDLC. Integration of Static code check in a SAP S/4HANA Cloud SDK Pipeline is a step towards ensuring better quality production system. Requirement of no pre-configuration makes it an easy to use feature.

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply