Tips for using core Java SE APIs
Core Java Technologies Tech Tips
Archives
« June 2009
SunMonTueWedThuFriSat
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today
Click me to subscribeSubscribe
Search

Links
 

Today's Page Hits: 1065

« Nimbus Look and Feel... | Main | Add Logging at Class... »
Tuesday May 20, 2008
Source Code Analysis Using Java 6 APIs

by Seema Richard, Deepa Sobhana

Have you ever thought of how tools like Checkstyle or FindBugs perform a static code analysis, or how Integrated Development Environments (IDEs) like NetBeans or Eclipse execute quick code fixes or find the exact references of a field declared in your code? In many cases, IDEs have their own APIs to parse the source code and generate a standard tree structure, called an Abstract Syntax Tree (AST) or "parse tree," which can be used for deeper analysis of the source elements. The good news is that it is now possible to accomplish the said tasks plus a lot more with the help of three new APIs introduced in Java as part of the Java Standard Edition 6 release. The APIs that might be of interest to developers of Java applications that need to perform source code analysis are the Java Compiler API (JSR 199), the Pluggable Annotation Processing API (JSR 269), and the Compiler Tree API.

In this article, we explore the features of each of these APIs and go on to develop a simple demo application that verifies certain Java coding rules on a set of source code files supplied as input. This utility also shows the coding violation messages as well as the location of violated source code as output. Consider a simple Java class that overrides the equals() method of the Object class. The coding rule to be verified is that every class that implements the equals() method should also override the hashcode() method with the proper signature. You can see that the TestClass class below does not define the hashcode() method, even though it has the equals() method.

 

public class TestClass implements Serializable {
int num;

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if ((obj == null) || (obj.getClass() != this.getClass()))
return false;
TestClass test = (TestClass) obj;
return num == test.num;
}
}

Let us go on and analyze this class as part of the build process with the help of these three APIs.

Invoking the Compiler from Code: The Java Compiler API

We all use the javac command-line tool for compiling Java source files to class files. Then why do we need an API to compile Java files? Well, the answer is quite simple: as the name describes, this new standard API lets us invoke the compiler from our own Java applications; i.e., you can programmatically interact with the compiler and thereby make compilation part of application-level services. Some typical uses of this API are listed below.

The Java compiler classes are packaged under the javax.tools package. The ToolProvider class of this package provides a method called getSystemJavaCompiler() that returns an instance of some class that implements the JavaCompiler interface. This compiler instance can be used to create a compilation task that will perform the actual compilation. The Java source files to be compiled will be then passed to the compilation task. For this, the compiler API provides a file manager abstraction called JavaFileManager, which allows Java files to be retrieved from various sources, such as the file system, databases, memory, and so on. In this sample, we use StandardFileManager, a file manager based on java.io.File. The standard file manager can be acquired by calling the getStandardFileManager() method of the JavaCompiler instance. The code snippet for the above-mentioned steps is shown below:

//Get an instance of java compiler
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

//Get a new instance of the standard file manager implementation
StandardJavaFileManager fileManager = compiler.
getStandardFileManager(null, null, null);

// Get the list of java file objects, in this case we have only
// one file, TestClass.java
Iterable compilationUnits1 =
fileManager.getJavaFileObjectsFromFiles("TestClass.java");



A diagnostic listener can be optionally passed to the getStandardFileManager() method to produce diagnostic reports of any non-fatal problems. In this code snippet, we pass null values, since we are not collecting the diagnostics from the tool. For details of the other parameters passed to these methods, please refer to the Java 6 API. The getJavaFileObjectsfromFiles() method of the StandardJavaFileManager returns all the JavaFileObject instances that correspond to the supplied Java source files.

Read the rest of this article

Posted at 12:06PM May 20, 2008 by dananourie in TechTip  |  Comments[4]

Comments:

I want stady from this site

Posted by aaaaa on May 27, 2008 at 01:45 PM PDT #

I want to learn java programming from the beginning.Actually I hold no idea on this subject.So it would be great to if I am able to get trained from your class.

Posted by Murad Islam on June 05, 2008 at 06:22 AM PDT #

If you want to learn Java programming from the beginning, I recommend you read Java Technology Fundamentals and use the New to Java Programming Center, where you can find many tutorials:

http://blogs.sun.com/JavaFundamentals/

http://java.sun.com/new2java/

Dana Nourie

Posted by Dana Nourie on June 05, 2008 at 09:24 AM PDT #

it was useful tip

Posted by 122.164.59.143 on June 13, 2008 at 03:16 AM PDT #

Post a Comment:
Comments are closed for this entry.