Java Specialists' Java Training Europehome of the java specialists' newsletter

The Java Specialists' Newsletter
Issue 0352001-11-17 Category: Software Engineering Java version:

GitHub Subscribe Free RSS Feed

Doclets Find Bad Code

by Dr. Heinz M. Kabutz

Welcome to the 35th issue of The Java(tm) Specialists' Newsletter. Two newsletters ago I mentioned checked exceptions and that perhaps they were a mistake. I also mentioned that I got that idea from someone else, that someone actually having been Bruce Eckel. Bruce and I had some very lively and interesting discussions regarding checked exceptions prior to my newsletter, and some of the ideas were gleaned from those discussions. Bruce has put up a website on http://www.mindview.net/Etc/Discussions/CheckedExceptions, where you can now voice your opinion on that matter. Please join us and tell us what you think. On that forum I've posted a way in which you can switch off exception checking in the compiler *evil grin*.

I'm always grateful for good publicity for my newsletter, so thanks also to Chris Preimesberger of DevX for publishing the exceptions newsletter on their website (http://www.java-zone.com/free/articles/Kabutz03/Kabutz03-1.asp). Please remember to forward this newsletter to your friends and collegues.

1618 members are currently subscribed from 55 countries

NEW: We have revised our "Advanced Topics" course, covering Reflection, Java NIO, Data Structures, Memory Management and several other useful topics for Java experts to master. 2 days of extreme fun and learning. Extreme Java - Advanced Topics.

Doclets Find Bad Code

What makes code bad? Is it the result of mistakes in logic? That makes the code incorrect, but not bad. Bad is one of those fuzzy attributes that are hard to define. It makes your stomach turn, fills you with dread, confiscates your mind ...

What makes coders bad? Lack of experience? Sloppiness? Bad training at universities by lecturers who themselves are bad coders? I once made the mistake of suggesting that the company, at which I was working at the time, give a Dutch student an opportunity to get some real-life experience. The code was indescribably bad! All the data members used package access, every class was in the same package, the whole program was one long nested if-else statement.

One of the things that makes this hobby of newsletter writing satisfying is the feedback I get from readers. Some time in June this year I was busy working for a German company (Infor AG) developing a subcomponent based on Doclets (I will write more about that in another newsletter).

At the same time, one of my readers at CitiCorp in India sent me an email, asking me for help. She was working in the quality control department of the coding group and was looking for some easy way of enforcing company policies with regard to coding. Since I was working with Doclets anyway, we had some interesting discussions on how you could use Doclets to solve her problems.

On another continent, Bruce Eckel was busy writing solutions for the exercises in his book. Naturally, he also wanted to make sure that his exercises did not contain "bad code" by mistake, so this newsletter is the result of a cooperation between Java users across three continents :-)

Let's get back to what makes code "bad". I believe that code is "bad" when it is difficult to maintain. In the refactoring literature, they say the code "smells". You might have code which is 100% correct, and yet still is "bad". How is that possible? If you don't believe me, wait until you have to change that code ...

There are certain "things" that we do which make code bad. Inappropriate variable names, making data members non-private, not having comments describing what each parameter is supposed to do, etc. But if you have a Java project with 2'000'000 lines of code, how do you find the code that is "bad"? Fortunately there is a solution that is not going to cost you the license fees of a Together/J, provided by Sun Microsystems in the form of Doclets.

The documentation for Doclets is in an obscure place. Go to your JDK documention, then to Tool Docs, click on Basic Tools, and under javadoc you'll see Javadoc 1.3 Home Page. All you have to do is write a method public static boolean start(RootDoc root) that is the starting point for the doclet engine. Let's have a look at some code that will find any non-private data members in your classes:

import com.sun.javadoc.*;

/** This class is used as a Doclet and will find any non-private
  data members in your classes. */
public class CodeChecker {
  /** This is the entry point for the doclet engine into your
  class. */
  public static boolean start(RootDoc root) {
    System.out.println("Non-private data members:");
    checkClasses(root.classes());
    return true;
  }
  /** We will call the checkClasses() method recursively so that
  we can also check the inner classes (for what it's worth). */
  private static void checkClasses(ClassDoc[] cds) {
    for (int i=0; i<cds.length; i++) {
      checkDataMembersArePrivate(cds[i]);
    }
  }
  /** This method prints out any data members that are not private
    together with their access.  If the field is package access
    we print out no modifiers. */
  private static void checkDataMembersArePrivate(ClassDoc cd) {
    System.out.println(cd.modifiers() + " " + cd.qualifiedName() + ":");
    FieldDoc[] fields = cd.fields();
    for (int i=0; i<fields.length; i++) {
      if (!fields[i].isPrivate()) {
        System.out.print("\t");
        if (!fields[i].isPackagePrivate())
          System.out.print(fields[i].modifiers() + " ");
        System.out.println(fields[i].type() + " " + fields[i].name());
      }
    }
    checkClasses(cd.innerClasses());
  }
}

The code above is dead-easy, but how do you use it? First you have to compile it, and you will need to include tools.jar in your classpath, e.g. javac -classpath .;c:\jdk1.3\lib\tools.jar *.java Note that the tools.jar file is not part of the runtime distributable, so if you want to use these features on your client machines, they will have to install the JDK, instead of just the JRE. Before we look at how we run Doclets, let's look at an example that we can use to test on:

public class Test {
  String packageAccess;
  private String privateAccess;
  public String publicAccess;
  protected String protectedAccess;
  public static final String NAME = "Hello";
}

We compile Test.java as well and now we can see how the Doclet is run:

javadoc -private -doclet CodeChecker Test.java

The resultant output is:

Loading source file Test.java...
Constructing Javadoc information...
Non-private data members:
public Test:
        java.lang.String packageAccess
        public java.lang.String publicAccess
        protected java.lang.String protectedAccess
        public static final java.lang.String NAME

You would have to of course match up your program with your company policy in order for this to be successful. For example, in your company you would probably say that it's OK for a data member to be public as long as it also was static and final.

More importantly than writing such a program is running it regularly, and suitably punishing those programmers found guilty of violating "the code" (in those countries that allow it, perhaps a public beheading would be appropriate? - oh no, rather a private one; otherwise they'd be violating their own rules.)

Would you use Doclets to do things to classes "in real time"? I would suggest you wait for the newsletter on how I tamed Doclets before you try that ;-)

My apologies again for not getting this newsletter out as regularly as I would like to. My excuse is rather lame - I'm busy writing a program for a company, and I love programming so much that everything else takes second place. The coding was also quite a rushed job, which is why I'm busy on a Saturday afternoon writing a newsletter when all my colleagues are on the beach ;-)

On the 30th of November we are celebrating our 1st anniversary as The Java(tm) Specialists' Newsletter. I would really appreciate it is you could make an extra effort to spread the word before that, so we can see some good growth.

Kind regards, and until next time...

Heinz

Software Engineering Articles Related Java Course

Extreme Java - Concurrency and Performance for Java 8
Extreme Java - Advanced Topics for Java 8
Design Patterns
In-House Courses

© 2010-2016 Heinz Kabutz - All Rights Reserved Sitemap
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners. JavaSpecialists.eu is not connected to Oracle, Inc. and is not sponsored by Oracle, Inc.