Sundararajan's Weblog

  • Java
    November 14, 2006

Javac Tree API - check for empty catch blocks

Guest Author

I wrote about javac's APIs in my last blog entry. But, I did not mention an example for Javac's Tree API. How about a simple example that uses javac's tree API? Here it is... In the following example, we implement a checker for empty catch blocks (because "eating exceptions silently" is considered bad) and warn the user.

We implement EmptyCatchChecker as a JSR-269 processor. In the process method, we
get each ClassTree node and run it through a verifier visitor - which is a TreeScanner. In the TreeScanner subclass, whenever CatchTree node is visited, we check whether it's block has any statements or not. If not, we issue a warning message. To give a better warning message, we print the class and the method in which empty catch block occurs [To print source file and line number, we need CompilationUnitTree and I don't know how to get that!].

Update: I had missed HTML escaping < characters in source code [for generics] and so the code below was not compiling. Thanks to Jaya Hangal for notifying this issue. I've fixed it now.

import java.util.\*;
// import all JSR 199, JSR 269 and Tree API stuff
import javax.annotation.processing.\*;
import javax.lang.model.\*;
import javax.lang.model.element.\*;
import javax.lang.model.type.\*;
import javax.tools.\*;
import com.sun.source.tree.\*;
import com.sun.source.util.\*;
// An annotation processor that processes all classes
public class EmptyCatchChecker extends AbstractProcessor {
private Trees treeUtils;
public void init(ProcessingEnvironment pe) {
treeUtils = Trees.instance(pe);
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
if (! roundEnv.processingOver()) {
Set<? extends Element> elements =
for (Element e: elements) {
Tree tree = treeUtils.getTree(e);
if (tree.getKind().equals(Tree.Kind.CLASS)) {
return true;
// verify each class tree
private void verify(ClassTree ct) {
ct.accept(new TreeScanner<Object, Void>() {
private String currentClass, currentMethod;
public Object visitClass(ClassTree node, Void v) {
currentClass = node.getSimpleName().toString();
return super.visitClass(node, v);
public Object visitMethod(MethodTree node, Void v) {
currentMethod = node.getName().toString();
return super.visitMethod(node, v);
public Object visitCatch(CatchTree node, Void v) {
BlockTree block = node.getBlock();
if (block.getStatements().isEmpty()) {
warn("empty catch block in " + currentMethod +
" method of " + currentClass);
return super.visitCatch(node, v);
}, null);
private void warn(String msg) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, msg);

To compile the above code, you can use the following command:

javac -classpath $JDK_HOME/lib/tools.jar EmptyCatchChecker.java

To use this empty catch checker, you can use the following command:

javac -processor EmptyCatchChecker YourClass.java

Note that the above checker can be fooled by adding a simple ';' in catch block - because ';' is a statement. How do we check for that? That is an exercise to the reader ;-) [Hint: EmptyStatementTree]

Join the discussion

Comments ( 3 )
  • anjan bacchu Tuesday, November 14, 2006
    hi sundararajan,
    nice post.
    thanks for the tip.
  • Mehmood Tuesday, November 14, 2006
    Hi Sundar,
    Nice post.can u please tell me about where to read about the java compiler architecture,classes and related stuffs?
    Thanks in advance...
  • A. Sundararajan Wednesday, November 15, 2006
    Hi Mehmood: you may want to start here. Reading compiler sources requires understanding compiler theory. In javac's case, understanding Java Language Specification is also needed (which is available online). Also, you may want to read Peter Ahe's (http://blogs.sun.com/ahe) blogs.
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.