Tuesday May 20, 2008
Tuesday May 20, 2008
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.
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 compiler API helps application servers to minimize the time taken to deploy applications, for example, by avoiding the overhead of using an external compiler for compiling the servlet sources generated from the JSP pages.
Developer tools like IDEs and code analyzers can invoke the compiler from within the editor or build tools that significantly reduce the compile time.
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.
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 #