|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 4
java -cp %CLASSPATH%;src;_contract_db;instr com.reliablesystems.iContract.Tool -Z -a -v -minv,pre,post > -b"javac -classpath %CLASSPATH%;src" -c"javac -classpath %CLASSPATH%;instr" > -n"javac -classpath %CLASSPATH%;_contract_db;instr" -oinstr/@p/@f.@e -k_contract_db/@p src/*.java
The statement above warrants a little bit of an explanation.
com.reliablesystems.iContract.Tool.
-minv,pre,post specifies that we want to instrument our code with invariants and preconditions as well as postconditions.
-b"javac -classpath %CLASSPATH%;src" option specifies the command to use to compile Java classes before iContract instruments them. iContract needs to do that
because it uses Java reflection to extract some of the properties of your Java classes. So in order to do its job, it first
needs a compiled version of the uninstrumented Java class.
-c"javac -classpath %CLASSPATH%;instr" option specifies the Java compiler command to compile the instrumented Java files.
-n"javac -classpath %CLASSPATH%;_contract_db;instr" option specifies the Java compiler to compile the repository classes. iContract uses a set of Java classes as a repository
to resolve inheritance and interface implementation relationships.
-oinstr/@p/@f.@e specifies the location of the instrumented Java files.
As you can see, iContract commands can be quite involved, so it's best to create a small build script for every project.
After you execute that command, we will have two versions of the compiled class files of our sample project. The src directory will contain the uninstrumented class, while the instr directory will contain the instrumented version.
We can now run our example, then see the assertions in action. Let's run the uninstrumented version first:
$ java -cp ./src StackTest
Exception in thread "main" java.util.NoSuchElementException
at java.util.LinkedList.getLast(LinkedList.java:107)
at StackImpl.top(StackImpl.java:24)
at StackImpl.pop(StackImpl.java:17)
at StackTest.main(StackTest.java:14)
As you can see, something went terribly wrong! Let's see if the instrumented code can shed some light.
$ java -cp ./instr StackTest
Exception in thread "main" java.lang.RuntimeException:
java.lang.RuntimeException: src/StackImpl.java:22: error:
precondition violated (StackImpl::top()): (/*declared in Stack::top()*/ (!isEmpty()))
at StackImpl.top(StackImpl.java:210)
at StackImpl.pop(StackImpl.java:124)
at StackTest.main(StackTest.java:15)
Well, that's better, isn't it? We now know exactly what went wrong. The precondition !isEmpty() of the StackImpl.top() method was violated. We were calling top() on an empty Stack.
I hope that you feel our little journey into DBC in Java was worthwhile. You should have a good idea of how useful iContract as a tool is to your development efforts.
Please be aware that iContract is still in beta (and has been for some time). Some bugs in the tool are laid out on the iContract Webpage.
You'll want to check out a number of iContract supporting tools: