Lecture 5: ESC/Java2 – The Java Extended Static Checker

ESC/Java2: a verification tool combining several analysis techniques (types, dataflow, proof). An overview of the checks it performs: exception freedom for common exceptions (null pointers, array indices, class casts). The lack of soundness and completeness: false positives and defects missed. Some further and specialised annotations extending core JML (non_null, unreachable, modifies, pure). Specification inheritance.

Links: Slides; ESC/Java2 downloads.

Homework

  1. Try ESC/Java on some of the example files and some Java (1.4) programs of your own (see below how to run ESC/Java2 on DICE).
  2. Try to statically verify your previously written recipe card program with ESC/Java2.

Running ESC/Java2

I have provided a shared installation of jdk1.4.2 and ESC/Java2,
the latter downloaded
from the latest KindSoftware release.

The files are in the /group/teaching/apl/JMLESC directory, with wrapper scripts in the bin subdirectory. For example, to run the Bag example I showed in this morning’s lecture, try this command in a command shell:

cd /group/teaching/apl/JMLESC
./bin/escj ESC/examples/0.0/Bag.java

Ignore the spurious warnings at the start of the output. The messages relating to the input file begin like this:

Bag: Bag(int[]) ...
------------------------------------------------------------------------
ESC/examples/0.0/Bag.java:6: Warning: Possible null dereference (Null)
n = input.length;
^ ------------------------------------------------------------------------
[1.016 s 13927376 bytes] failed


Bag: extractMin() ...
------------------------------------------------------------------------
ESC/examples/0.0/Bag.java:15: Warning: Possible null dereference (Null)
if (a[i] < m) {
^
Execution trace information:
Reached top of loop after 0 iterations in "ESC/examples/0.0/Bag.java", line 14, col 4.

(the blog has messed up the indentation here, you should see a more useful result).

The shared directory is also available on AFS as
/afs/inf.ed.ac.uk/group/teaching/apl so you may
also be able to access it remotely if you have openafs installed on your
Linux machine.

3 Responses to Lecture 5: ESC/Java2 – The Java Extended Static Checker

  1. ianstark says:

    > The shared directory is also available on AFS as
    > /afs/inf.ed.ac.uk/group/teaching/apl so you may
    > also be able to access it remotely if you have openafs installed on your
    > Linux machine.

    I just tried this, but there were some permission and path problems. I believe that I’ve fixed them: if anyone tries this, please post good or bad news here.

    The Informatics computing staff have a handy guide to setting up the AFS connection to Informatics on a variety of machines, including AFS on Debian. It’s a convenient way to access Informatics home directories from afar.

  2. s0974627 says:

    I have this running on my own machine but am having trouble with some code.
    I have a method in a Recipe class:

    //@ requires ingredientName != null && !ingredientName.equals(“”);
    //@ ensures \result == (Amount)ingredientMap.get(ingredientName);
    public /*@ pure @*/ Amount getAmount(String ingredientName) {
    return (Amount) ingredientMap.get(ingredientName);
    }

    The casting is necessary as it’s Java 1.4 but ESC/Java2 is telling me:
    ————————————————————————
    Recipe.java:35: Warning: Possible type cast error (Cast)
    return (Amount)ingredientMap.get(ingredientName);
    ^
    ————————————————————————

    Is anyone else seeing anything like this?

    Also, while this works:

    private int quantity;
    //@ invariant quantity >= 0;

    The same syntax with a float variable type doesnt:

    private float quantity;
    //@ invariant quantity >= 0.0;

    It gives the error:

    ————————————————————————
    Amount.java:1: Warning: Possible violation of object invariant (Invariant)
    public class Amount {
    ^
    Associated declaration is “Amount.java”, line 5, col 5:
    //@ invariant quantity >= 0.0;
    ^
    Possibly relevant items from the counterexample context:
    brokenObj%0 == RES-1.20
    (brokenObj* refers to the object for which the invariant is broken.)
    ————————————————————————

    Even though Java will initialize instance variables to 0 by default, this wont work for the float unless quantity is initialized explicitly (there are no setters in this class for quantity or anything that changes its value).

  3. Hi, I talked to you after the lecture today about this. The ESC error is perhaps accurate in that to make sure the cast succeeds your code may need to test first, if (o instanceof Amount) then { … (Amount)o … }.

    If the only types of thing put into the map are Amount, you could argue that the error is a false positive because the cast can in fact never fail. But you might need a whole program analysis to see this, and ensure with visibility/final controls that no other code could insert into the map.

    You could try adding an invariant to specify that every object in the map is an Amount, then see if ESC stops complaining. Of course, generics are a better solution, because the invariant is then captured by the type system.