The purpose of this lab is to work on your Java Exception skills. You'll start with a program that works OK, but only if the input is entered perfectly. The program processes commands. The commands are:
Your job in Part 1 will be to add specialized exceptions so that when the program crashes on bad input, the stack trace is a little more informative. Your job in Part 2 will be to add real error handling, and some nice features like the ability to read input from files, which will require still more use of exceptions!
Download the files Lab08.java, Queue.java and ModQueue.class:
curl -O http://faculty.cs.usna.edu/IC211/docs/lab08/Lab08.java curl -O http://faculty.cs.usna.edu/IC211/docs/lab08/Queue.java curl -O http://faculty.cs.usna.edu/IC211/docs/lab08/ModQueue.classThe ModQueue class extends Queue in three ways:
void dequeue(String s)
has been added, which dequeues everything up to and including entry String s in the queue. You should never call this method unless you're sure s is in the queue already.
String dump()
has been added, that returns a String that is a comma-separated list of the values in the Queue at that point.
Compile the program and run the program for yourself. Here are some example runs:
~/$ java Lab08 > add foo > add bar > add goo > dump foo,bar,goo > clearto bar > dump goo > quit
~/$ java Lab08 > add foo > add bar > dump foo,bar > clearto bat Exception in thread "main" java.lang.NullPointerException at Queue.dequeue(Queue.java:25) at ModQueue.dequeue(ModQueue.java:19) at ModQueue.dequeue(ModQueue.java:23) at Lab08.main(Lab08.java:16)
~/$ java Lab08 > dump Exception in thread "main" java.lang.NullPointerException at Queue.toArray(Queue.java:41) at ModQueue.dump(ModQueue.java:28) at Lab08.main(Lab08.java:20)
~/$ java Lab08 > add foo > add bar > dump foo,bar > clearto bat Exception in thread "main" QueueException: dequeue empty queue at Queue.dequeue(Queue.java:24) at ModQueue.dequeue(ModQueue.java:19) at ModQueue.dequeue(ModQueue.java:23) at Lab08.main(Lab08.java:16)
~/$ java Lab08 > dump Exception in thread "main" QueueException: toArray past end of queue at Queue.toArray(Queue.java:41) at ModQueue.dump(ModQueue.java:28) at Lab08.main(Lab08.java:20)
You must do this in a file named QueueException.java
. You cannot define QueueException as an inner class of Queue and expect to pass the tests on the submit system.
Note: These MUST be "unchecked" exceptions (i.e. the ones that Java doesn't require the caller to catch or re-throw.). Why? Because we can't modify ModQueue.java, and it isn't written to catch these!
Important: You should notice that we are able to make these changes and have everything work, even though ModQueue cannot be changed. In fact, we are doing it without access to the source code, or any way to even just recompile it. That should make crystal clear that we have distance (on the call stack) between where the errors occur (in Queue methods) and where they will ultimately be handled in Part 2 (Lab08's main). The fact that we are able to deal with this shows the strength of this approach to error handling.
Modify Lab08.java to add the below functionality:
File 'foo.txt' could not be opened; switching input to standard in.
Note 1: when the input comes from a file, no "> " prompt should be printed.
Note 2: now that you know about exceptions, you should be able to understand the code we gave you before for opening files:
Scanner sc = null;
try {
sc = new Scanner(new FileReader(fname));
} catch(IOException e) {
e.printStackTrace();
System.exit(1);
}
... and adapt it to this problem.
dump
command when the queue is empty, or the clearto
with a string that isn't in the queue, the program shouldn't crash. Instead, it should silently continue, except that, in verbose mode, issuing a clearto
command with a string that's not in the qeueue should result in printing to STDOUT (normal output) the error message "String 'foo' not found!" where, of course, foo should be replaced with the actual clearto string. After printing the error, however the program should continue running as if nothing bad happened.
Note: in the clearto
case, the queue should be emptied by a clearto
command with a string that's not in the queue.
add
, but no string was provided, and the end-of-file occurred when trying to read the string to be added, the program should print the message "Unexpected end of input.
".
Unknown command 'foo'.
", where "foo" should be replaced by the given command. In both cases the program should simply continue to process new commands.
.empty()
method on Queue or ModQueue objects! You must use exceptions!
~/$ java Lab08 > add cat > add dog > clearto rat > dump > ctrl-d
~/$ java Lab08 -v > add cat > add dog > clearto rat String 'rat' not found! > dump > ctrl-d
~/$ java Lab08 -v asdf File 'asdf' could not be opened; switching input to standard in. > add cat > add dog > damp Unknown command 'damp'. > dump cat,dog > quit
~/$ java Lab08 ex1.txt foo,bar,bat,cat bat,cat
~/$ java Lab08 -v ex2.txt foo,bar String 'cat' not found! Unexpected end of input.
Now that you've successfully error-proofed your code, let's get some more implementation practice. We gave you a compiled ModQueue.class file. You used its interface:
void dequeue(String s);
void enqueue(String s);
String dump();
Your task is to write your own ModQueue implementation that extends Queue, and replace our ModQueue.class library with your own version. Not one line of code from your Part 1 and Part 2 solutions should be changed. Your code should still pass all the part 1/2 tests without change. Proper OOP design must be followed. This is an exercise in creating an implementation given an interface...something software engineers regularly must do.
Note that your ModQueue.java should NOT do any exception handling, i.e. no try/catch/throw statements at all.
If you have them (or think that you need to have them), then you probably have the wrong parent class for QueueException.
~/bin/submit -c=IC211 -p=Lab08 *.java ModQueue.class
~/bin/submit -c=IC211 -p=Lab08 *.java