Automatically execute Java code static analysis with PMD

Source: Internet
Author: User

 

I. Basic Knowledge
PMD is a tool for analyzing Java code errors. Unlike other analysis tools, PMD identifies code errors through static analysis. That is to say, report errors without running Java programs. PMD comes with many rules that can be used directly. Using these rules, you can find many problems in the Java source program, such as unused variables, redundant variable creation operations, empty catch blocks, and so on. In addition, you can define rules to check whether Java code complies with certain encoding specifications. For example, you can write a rule that requires PMD to find all the operations for creating Thread and Socket objects.
It was initially developed to support the Cougaar project. Cougaar is a project of Defense Advanced Research Projects Agency, DARPA. DARPA opened the source code of PMD, so it was released to the SourceForge website. Not long ago, the number of download operations of PMD exceeded 14000, and the number of page views exceeded 130000. More importantly, with the efforts of open source code authors, more and more information about the PMD rules and IDE plug-ins has been developed and then added to the core projects of PMD.
You can download the binary version or the version with source code from the PMD website. All downloaded files are ZIP files. Assume that you have downloaded the binary version and first decompress it to any directory. Next, we need to know how to use it-the simplest one. If you want to run PMD in a Java source code directory, simply run the following command on the command line:

C: datapmdpmd> java-jar libpmd-1.02.jar c: j2sdk1.4.1 _ 01 srcjavautil
Text rulesets/unusedcode. xml

The output result class is as follows:

C: j2sdk1.4.1 _ 01srcjavautilAbstractMap. java 650
Avoid unused local variables such as v
C: j2sdk1.4.1 _ 01srcjavautilDate. java 438
Avoid unused local variables such as millis

In addition to running PMD directly on the command line, you can also use Ant, Maven, or a variety of integrated development environments (IDE) to run PMD, for example, jEdit, Netbeans, Eclipse, Emacs, IDEAJ, and JBuilder.

2. built-in rules
It comes with many rules. The following are examples.

The unused code should obviously be cleared.
Public class Foo {
// The following instance variable is not used
Private List bar = new ArrayList (500 );
}
If an interface can achieve the same goal, why should a specific class be returned? For example, you can use the List interface in the following example.
Public ArrayList getList (){
Return new ArrayList ();
}
When the if condition is true, the if code block does not actually do anything. The following code can be written more concisely.
Public void doSomething (int y ){
If (y> = 2 ){
} Else {
System. out. println ("Less than two ");
}
}
Why create a new String object? You only need to use String x = "x.
String x = new String ("x ");



It also contains many other built-in rules, but we can see from the above examples that the basic working method of the message is dependent on. As long as appropriate static rules are defined, PMD can help you point out problems in the code just like an experienced programmer.

Iii. Working Principle

The core of PMD is the JavaCC Parser Generator. In combination with JavaCC and EBNF (Extended bacos-Noor paradigm, Extended Backus-Naur Formal) syntax, and JJTree, PMD parses Java source code into an abstract syntax tree (AST, abstract Syntax Tree ). Obviously, this sentence is not so easy to understand and can be explained in detail below.

Basically, Java source code is just some common text. However, in order for the parser to acknowledge that these common texts are legitimate Java code, they must comply with certain structural requirements. This structure can be expressed in a syntactic metalanguage called EBNF, usually known as Grammar ). JavaCC generates a parser according to syntax requirements. This parser can be used to parse programs written in Java programming language.

However, in actual operation, the PMD still needs to undergo a JJTree conversion. JJTree is a JavaCC plug-in. It uses AST to expand the parser generated by JavaCC. AST is a semantic layer over a Java symbolic stream. With JJTree, the syntax analysis result is no longer a symbolic sequence like "System,..., out,... println", but a tree hierarchy composed of objects. For example, below is a simple Java code and the corresponding AST.

Java source code:
Public class Foo {
Public void bar (){
System. out. println ("hello world ");
}
}
Corresponding abstract syntax tree
CompilationUnit
TypeDeclaration
ClassDeclaration
UnmodifiedClassDeclaration
ClassBody
ClassBodyDeclaration
MethodDeclaration
ResultType
MethodDeclarator
FormalParameters
Block
BlockStatement
Statement
StatementExpression
PrimaryExpression
PrimaryPrefix
Name
PrimarySuffix
Arguments
ArgumentList
Expression
PrimaryExpression
PrimaryPrefix
Literal



4. Write rules

We have seen the Java source code and the corresponding object hierarchy. Next, we will use these objects to write the PMD rule to check the existing problems in the code.

Generally, a PMD rule can be regarded as a Visitor, which traverses the AST and looks for a specific mode between multiple objects. This mode indicates a problem with the code. The problematic mode may be simple or complex, such as checking whether the Code contains the new Thread keyword, and determining whether a class correctly overwrites equals and hashcode.

The following is a simple PMD rule for finding null if statements.

// Extended into actrule to enable the Visitor Mode
Public class emptyifpolictrule extends actrule implements Rule {
// When a Block appears in the source code, the following method is called.
Public Object visit (ASTBlock node, Object data ){
// If the parent node is an if statement and there is no content in the code block
If (node. jjtGetParent (). jjtGetParent () instanceof ASTIfStatement)
& Node. jjtGetNumChildren () = 0 ){
// Make sure the code is faulty. Add a RuleViolation to the Report.
RuleContext ctx = (RuleContext) data;
Ctx. getReport (). addRuleViolation (createRuleViolation (ctx,
Node. getBeginLine ()));
}
// Continue to check the next node of the tree
Return super. visit (node, data );
}
}

Maybe you cannot grasp this code at once. In fact, its idea is relatively simple:
# Extends the AbstractRule base class.
# Declare a "hook". Once the node we are interested in appears, it will be called (called "callback "). In the above example, we need to be notified when every ASTBlock appears, So we declare visit (ASTBlock node, Object data ).
# In the callback function, determine whether the problem we are checking has occurred. In this example, we check whether there is an empty if block. Therefore, we first determine whether the current block is within ASTIfStatement and then determine whether it has subnodes.
Of course, we can also follow another method: declare a callback function that requires the ASTIfStatement to be checked, and then check whether there are subnodes In the callback function.
5. Configure rules
After writing a custom rule, you need to add it to a certain PMD rule set. The so-called PMD rule set is a set composed of a group of PMD rules. Each PMD rule set is defined by an XML file. The following is an example of the configuration information of an PMD rule:
<Rule name = "EmptyIfStmt"
Message = "Avoid using empty if statements"
Class = "net. sourceforge. pmd. rules. emptyif1_trule">
<Description>
Find an empty if statement: if checks the condition, but there is no content in the if block.
</Description>
<Priority> 3 </priority>
<Example>
<! [CDATA [
If (absValue <1 ){
// Not good
}
</XMLCDATA>
</Example>
</Rule>
It can be seen that the rule configuration file contains a lot of useful information. To run the newly added rule, you only need to put the XML file of the Rule Set and the Java source code file into CLASSPATH and then run the command.
Conclusion: This article describes how to analyze and find out the problems in the code without compiling the code. It provides several simple examples to understand the EBNF syntax, JavaCC, and AST, and how to check the problems in the Code with PMD, and how to compile and use the customized PMD rules. May it help you!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.