David Evans http://www.cs.virginia.edu/~evans Lecture 2: Java Semantics, Validation CS201j: Engineering Software? University of Virginia Computer Science David Evans http://www.cs.virginia.edu/~evans
Menu Survey Results Objects in Java: Heap and Stack Validation: Testing and Analysis 29 August 2002 CS 201j Fall 2002
Survey Results 29 August 2002 CS 201j Fall 2002
Experience Almost everyone: C++ Only 2 with a little Java experience Scheme, PHP, Python, Basic, VHDL Largest Program: 16: CS101/CS200 (few hundred lines) 5 people had experience with 1000+ line programs Only 4 of you did any programming over the summer! 29 August 2002 CS 201j Fall 2002
Other Answers On the course web site My answers also… 29 August 2002 CS 201j Fall 2002
Java Semantics 29 August 2002 CS 201j Fall 2002
The Stack and Heap String s = new String (“hello”); s java.lang.String String is a type in the Java API for representing sequences of characters “hello” Objects live on the Heap new creates an Object on the Heap Local variables live on the Stack Point to objects on the Heap 29 August 2002 CS 201j Fall 2002
String s = new String (“hello”); String t = s; s java.lang.String t “hello” 29 August 2002 CS 201j Fall 2002
String s = new String (“hello”); String t = s; s java.lang.String java.lang.String t “hello” “goodbye” s = new String (“goodbye”); 29 August 2002 CS 201j Fall 2002
Primitive Types Not everything in Java is an Object Some types are primitive types boolean, byte, char, double, float, int, long, short Values of primitive types are stored directly on the stack 29 August 2002 CS 201j Fall 2002
String s = new String (“hello”); String t = s; int i = 201; s int j = i; java.lang.String t “hello” i 201 j 201 How can we see the difference between primitive types and objects? 29 August 2002 CS 201j Fall 2002
Equality x == y Object Types: same objects Primitive Types: same value x.equals (y) Object Types: method that compares values of objects Primitive Types: doesn’t exist 29 August 2002 CS 201j Fall 2002
Mutability If an object is mutated, all references to the object see the new value StringBuffer sb = new (“hi”); StringBuffer tb = sb; tb.append (“gh”); sb java.lang.StringBuffer tb “hi” “high” 29 August 2002 CS 201j Fall 2002
Immutable/Mutable Types Types can be mutable or immutable Objects of an immutable type never change value after they are created String is immutable, StringBuffer is mutable String.concat creates a new String object StringBuffer.append mutates the old object 29 August 2002 CS 201j Fall 2002
Java Semantics Question public class Strings { public static void test (String [] args) { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); // What are the values of s, t, sb and tb now? // Which of these are true: // a) s == t b) s1 == t1 c) s == s1 // d) s.equals (t) e) sb == tb f) t.equals (tb) } java.lang.String “hello” s java.lang.String t “hello” sb 201 tb 201 29 August 2002 CS 201j Fall 2002
Java Semantics Question public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” s1 String spec is not enough to determine if s, t, s1 and t1 are the same objects! This is what Sun’s JDK 1.4 does. Other implementations could correctly do different things. java.lang.String t1 “hello” 29 August 2002 CS 201j Fall 2002
Java Semantics Question public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” “hello” s1 java.lang.String t1 “hello” 29 August 2002 CS 201j Fall 2002
Java Semantics Question public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” “hello goodbye!” s1 java.lang.String t1 “hello” 29 August 2002 CS 201j Fall 2002
Java Semantics Question public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” “hello goodbye!” s1 java.lang.String java.lang.String t1 “hello” “hello goodbye!” 29 August 2002 CS 201j Fall 2002
s t sb tb s1 t1 java.lang.String “hello goodbye!” java.lang.String public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” “hello goodbye!” s1 java.lang.String java.lang.String t1 “hello” “hello goodbye!” 29 August 2002 CS 201j Fall 2002
s t sb tb s1 t1 After test returns? java.lang.String “hello goodbye!” public class Strings { public static void test () { String s = new String ("hello"); String t = new String ("hello"); StringBuffer sb = new StringBuffer ("he"); StringBuffer tb = sb; String s1 = "hello"; String t1 = "hello"; sb.append (“llo"); tb.append (" goodbye!"); s.concat (" goodbye!"); t = s.concat (" goodbye!"); } } java.lang.String “hello” s java.lang.String t “hello” sb java.lang.StringBuffer tb “he” “hello goodbye!” s1 java.lang.String java.lang.String t1 “hello” “hello goodbye!” 29 August 2002 CS 201j Fall 2002
Validation 29 August 2002 CS 201j Fall 2002
Dictionary Definition val·i·date To declare or make legally valid. To mark with an indication of official sanction. To establish the soundness of; corroborate. Can we do any of these with software? 29 August 2002 CS 201j Fall 2002
Java’s License READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE TERMS (COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE MEDIA PACKAGE. BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE TERMS OF THIS AGREEMENT. IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, INDICATE YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT THE END OF THIS AGREEMENT. IF YOU DO NOT AGREE TO ALL THESE TERMS, PROMPTLY RETURN THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND OR, IF THE SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON AT THE END OF THIS AGREEMENT. 29 August 2002 CS 201j Fall 2002
Java’s License 5. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. … 29 August 2002 CS 201j Fall 2002
Java’s License 2. RESTRICTIONS. … Unless enforcement is prohibited by applicable law, you may not modify, decompile, or reverse engineer Software. You acknowledge that Software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility. Sun disclaims any express or implied warranty of fitness for such uses. 29 August 2002 CS 201j Fall 2002
Software Validation Process designed to increase our confidence that a program works as intended For complex programs, cannot often make guarantees This is why typical software licenses don’t make any claims about their program working 29 August 2002 CS 201j Fall 2002
Increasing Confidence Testing Run the program on set of inputs and check the results Verification Argue formally or informally that the program always works as intended Analysis Poor programmer’s verification: examine the source code to increase confidence that it works as intended 29 August 2002 CS 201j Fall 2002
Testing If all the test cases produce the correct results, you know that a particular execution of the program on each of the test cases produced the correct result Concluding that this means the program is correct is like concluding there are no fish in the river because you didn’t catch one! 29 August 2002 CS 201j Fall 2002
Exhaustive Testing Test all possible inputs PS1: 50x50 grid, all cells can be either dead or alive before starting 22500 = 375828023454801203683362418972386504867736551759258677056523839782231681498337708535732725752658844333702457749526057760309227891351617765651907310968780236464694043316236562146724416478591131832593729111221580180531749232777515579969899075142213969117994877343802049421624954402214529390781647563339535024772584901607666862982567918622849636160208877365834950163790188523026247440507390382032188892386109905869706753143243921198482212075444022433366554786856559389689585638126582377224037721702239991441466026185752651502936472280911018500320375496336749951569521541850441747925844066295279671872605285792552660130702047998218334749356321677469529682551765858267502715894007887727250070780350262952377214028842297486263597879792176338220932619489509376 But that’s not all: all possible start stop step interactions, different platforms, how long to you need to run it, etc. 29 August 2002 CS 201j Fall 2002
Selective Testing We can’t test everything, pick test cases with high probability of finding flaws Black-Box Testing: design tests looking only at specification Glass-Box Testing: design tests looking at code Path-complete: at least one test to exercise each path through code 29 August 2002 CS 201j Fall 2002
Black-Box Testing Test all paths through the specification: public CellState getNextState () // MODIFIES: this // EFFECTS: Returns the next state for this cell. If a cell is currently // dead cell and has three live neighbors, then it becomes a live cell. // If a cell is currently alive and has two or three live neighbors it // remains alive. Otherwise, the cell dies. Test all paths through the specification: currently dead, three live neighbors currently alive, two live neighbors currently alive, three live neighbors currently dead, < 3 live neighbors currently dead, > 3 live neighbors currently alive, < 2 live neighbors currently alive, > 3 live neighbors 29 August 2002 CS 201j Fall 2002
Black-Box Testing Test all paths through the specification (7 tests) public CellState getNextState () // MODIFIES: this // EFFECTS: Returns the next state for this cell. If a cell is currently // dead cell and has three live neighbors, then it becomes a live cell. // If a cell is currently alive and has two or three live neighbors it // remains alive. Otherwise, the cell dies. Test all paths through the specification (7 tests) Test boundary conditions all neighbors are dead all neighbors are alive cell is at a corner of the grid cell is at an edge of the grid 29 August 2002 CS 201j Fall 2002
Glass-Box Testing Test all paths through the code (4) public CellState getNextState () // MODIFIES: this // EFFECTS: Returns the next state for this cell. If a cell is currently // dead cell and has three live neighbors, then it becomes a live cell. // If a cell is currently alive and has two or three live neighbors it // remains alive. Otherwise, the cell dies. { if (countAliveNeighbors () == 3) { return CellState.createAlive (); } else if (getState ().isAlive () && countAliveNeighbors () == 2) { } else { return CellState.createDead (); } Test all paths through the code (4) 29 August 2002 CS 201j Fall 2002
Glass-Box Testing Test all paths through the code (4) public CellState getNextState () // MODIFIES: this // EFFECTS: Returns the next state for this cell. If a cell is currently // dead cell and has three live neighbors, then it becomes a live cell. // If a cell is currently alive and has two or three live neighbors it // remains alive. Otherwise, the cell dies. { if (countAliveNeighbors () == 3) { return CellState.createAlive (); } else if (getState ().isAlive () && countAliveNeighbors () == 2) { } else { return CellState.createDead (); } Test all paths through the code (4) 29 August 2002 CS 201j Fall 2002
Path-Complete Testing Insufficient Often, bugs are missing paths Impossible Most programs have essentially infinite number of paths Loops and recursion Test with zero, one and several iterations 29 August 2002 CS 201j Fall 2002
Testing Recap Testing can find problems, not to prove your program works Since exhaustive testing is impossible, select test cases with maximum probability of finding bugs A successful test case is one that reveals a bug in your program! Typically at least 40% of cost of software project is testing, often ~80% of cost for safety-critical software 29 August 2002 CS 201j Fall 2002
If we can’t test all possible paths through a program, how can we increase our confidence that it works? 29 August 2002 CS 201j Fall 2002
Analysis Make claims about all possible paths by examining the program code directly, not executing it Use formal semantics of programming language to know what things mean Use formal specifications of procedures to know that they do 29 August 2002 CS 201j Fall 2002
Hopelessness of Analysis It is impossible to correctly determine if any interesting property is true for an arbitrary program! The Halting Problem: it is impossible to write a program that determines if an arbitrary program halts. More on this later in the class… 29 August 2002 CS 201j Fall 2002
Compromises Accept unsoundness and incompleteness False positives: sometimes an analysis tool will report warnings for a program, when the program is actually okay (unsoundness) False negatives: sometimes an analysis tool will report no warnings for a program, even when the program violates properties it checks (incompleteness) 29 August 2002 CS 201j Fall 2002
ESC/Java Extended Static Checking for Java Analysis tool developed at DEC/Compaq/HP Research Lab Is unsound and incomplete: Just because it finds no warnings, doesn’t mean your code is correct PS2: use without adding annotations Later: use annotations to document program assumptions 29 August 2002 CS 201j Fall 2002
CS201J Bug Bounty If you find a bug in the code we provide, you get 10 bonus points. If you find a bug in the Java compiler or API code, you get 50 bonus points. If you find a bug in ESC/Java or the ESC/Java Specs, you get 5 bonus points. 29 August 2002 CS 201j Fall 2002
Charge Increase confidence a program works by: Testing: sample possible executions, trying to find ones that don’t work Analysis: check properties about all possible executions by examining code PS2: a lot longer and harder than PS1 Remember to take pictures! 29 August 2002 CS 201j Fall 2002