Slashdot Mirror


Java Static Analysis And Custom Bug Detectors

An anonymous reader writes "Java static analysis and custom bug detectors can be a very cost-effective way to improve software quality. By creating a detector for a known bug pattern, we can search for that bug pattern not only in the current code base for a specific project, but in any project, current or future. This article looks at how static analysis tools can change the way you manage software quality."

4 of 157 comments (clear)

  1. PMD and JLINT by Hoolala · · Score: 4, Interesting

    We develop Java-based vertical products and we have found PMD and JLINT when integrated with an appropriate development process, can be highly effective in preventing serious bugs. That said, both PMD and JLINT incorporates "religious" issues, and it is important to determine what the religious issues are and steer clear of them lest the good rules get lost among the non-essential (from project perspective) rules.

  2. doesn't findbugs do this by josepha48 · · Score: 2, Interesting

    I think findbugs does this. I've started using it and it found lots of bugs in my code. As a result I have learned a few things about java, just by using it and fixing my bugs.

    --

    Only 'flamers' flame!
    Does slashdot hate my posts?

  3. Custom bug detector I wrote for FindBugs last week by wpugh · · Score: 2, Interesting

    As an example of turning bug instances into bug patterns, I always read through the list of bugs fixed in each version of the jdk1.6.0 builds. In build 89, a bug was fixed in the serialization of ArrayBlockingQueue.

    I wrote a FindBugs bug detector to look for similar cases: a class with transient fields, but no readObject or readResolve method to restore the field. I had to tune the detector a bit (for example, raise the priority if it is set to a non-default value in the constructor). I'm still doing some tuning, but at the moment the new detector reports warnings in 47 jdk 1.6 b89 classes, 18 of which are confirmed to be bugs. This took me a total of 5 hours of work.

    Bugs listed below (these have been reported to Sun); this detector isn't in the current 1.0 release of FindBugs, but is available is the latest CVS snapshot, and will be in the next release.

      Bill Pugh

    -----

    java.security.Timestamp and java.security.CodeSigner:
            they have a transient myhash field used to cache the hashCode that is
            initialized to -1. If you serialize/deserialize one of these
            and invoke hashCode on the result, you'll get an incorrect hashCode of 0.

    javax.management.AttributeList
            has a transient boolean field tainted. If you add something other than an Attribute
            to an AttributeList, serialize/deserialize it, and then invoke asList(), you get back
            a List that contains something that isn't an Attribute. If you call asList() on
              the original AttributeList, you get an exception.

    javax.management.relation.RoleList
    javax.management.relation.RoleUnresolvedList
            problems isomorphic to the above problem

    sun.util.BuddhistCalendar
            has a transient field yearOffset that is initialized in the constructor. If you
            serialize/deserialize a BuddhistCalendar, you get back a broken BuddhistCalendar
            that computes dates incorrectly (off by 543 years)

    javax.swing.DefaultDesktopManager
            has a transient field floatingItems that is initialized to an empty array of Rectangles, and
            it sure looks like the code is assuming that floatingItems is assumed to be nonnull, so
            if you serialize/deserialize it, it will be broken (of course, I can never be sure if
            anybody seriously intends for awt/swing objects to be serialized.

    com.sun.rowset.CachedRowSetImpl
    com.sun.rowset.FilteredRowSetImpl
    com.sun.rowset.JdbcRowSetImpl
    com.sun.rowset.JoinRowSetImpl
    com.sun.rowset.WebRowSetImpl
    com.sun.rowset.internal.CachedRowSetReader
    com.sun.rowset.internal.CachedRowSetWriter
    com.sun.rowset.internal.InsertRow
    com.sun.rowset.internal.SyncResolverImpl
    com.sun.rowset.internal.WebRowSetXmlReader
    com.sun.rowset.internal.WebRowSetXmlWriter
    com.sun.rowset.providers.RIOptimisticProvider
            all initialize in their constructors transient fields pointing to resource bundles
                    for providing localized error messages, and the resource bundle will be null if the
            an object is deserialized and serialized.

    javax.smartcardio.CommandAPDU
            has 3 transient fields (nc, ne and dataOffset) that are computed by the call to parse in the constructor
            from the apdu array. However, if the object is serialized/deserialized, the fields will have their
            default values.

  4. Re:What a strange thing from IBM by maraist · · Score: 2, Interesting

    That's not the correct way to be doing things, anyway. Try this instead

    You missed the part where I compared it to cooperative multi-tasking.. You are wrapping the collection at constructor time, BUT half (and I do mean half) of the time you don't have control over the constructor to an object.. Especially if you are writing middle-ware code, which is most of what Java does - at least good application designs write most of their code in the form of middle-ware.

    Take Sort for example... It can't depend on the fact that even though it asks for a generified collection that there is any sort of type-safety involved.. The only thing it can do is pre-validate the data-type of the existing items in the collection that is passed to it. But that's a performance hit, and the ONLY thing that this will do is produce a more meaningful runtime exception.. i.e. instead of an exception in the comparator you get one in the sorter with an explicit "element in collection of type X was really Y" RuntimeException.

    Caches, Marshellers / Serializers, IPC services, persistence sercies, etc. They all are middleware applications which throw really really confusing errors sometimes because they aren't passed the expected classes. And when I say confusing, I mean they don't often throw class-cast exceptions, but instead meta-data mismatch exceptions.. But that leads you to believe that you've missed an attribute in the XML configuration instead of the fact that you've adding an object of the wrong type to the middle-layer.

    Ideally, generics would be fully enforced by the VM. What we currently have (even with the spettering of Collections.unmodifiable,synchronized,checked etc are weak-enforcement which at best provides spot cleanness of code.. But any static anylizer tool could have detected innappropriate local bugs.. The more critical bugs are inter-moule bugs. And APIs of that sort tend to be littered with innappropriate parameter-checking. If you don't think this is a problem, then what is the number 1 security loop-hole in most older C libraries? gets(). This function (for performance purposes) didn't verify the size of the string so it allowed the over-flowing of the buffer and overwriting of user-space memory. Most other languages handle strings in a less performant, but more robust manner, so this type of bug has mostly dissapeared.

    In java, with the advent of dynamic proxies and aspect-oriented-programming, the situation is even worse, because inter-module libraries can proxy objects which don't even match the appropriate prototype/interface. So you actually wouldn't get a class-cast-exception, but instead an arbitrary exception (most likely an NPE) inside the InvocationHandler.

    This is mostly a rant, but it's based on my growing frustration with the lack of type-safety in java frameworks... Yes, you're certainly free to not use those frameworks.. But with the increasing movement into container-managed services (tomcat, jboss, or even spring/pico-container), this type-looseness is becoming a growing problem.

    --
    -Michael