Java™ Pathfinder, or “JPF” as we call it from here, is a highly customizable execution environment for verification of Java™ bytecode programs. JPF was developed at the NASA Ames Research Center, open sourced in 2005, and is freely available here under the NOSA 1.3 license. JPF started as a software model checker but it integrates model checking, program analysis and testing.
In this post we will go in a step by step process to setup the environment where Java Path Finder can be used within Eclipse IDE environment. We will show a simple example of using JPF.
Step 1. Install Eclipse
Step 2. Download JPF
Step 2.1 : Download Mercurial plug-in for Eclipse
Step 2.2 : Download the JPF source code
Step 2.3 : Build the JPF
In the package explorer, select the build.xml, right click on it, select “run as” » “Run as Ant build “.
Eclipse will build JPF and a new folder named “build” will appear in the package explorer (it may not appear even the build was successful, double check the windows explorer for it.)
If the build failed due to error missing JDK:
On Eclipse menu : Project » Properties. Select Builders from the lift hand side list
Select Ant Builder and click New.
Select Ant Builder and click New.
In the Edit Configuration dialog, select the “JRE” tab, then select “Separate JRE” from the “Runtime JRE section”. In the drop down list, select JDK:
If you couldn’t find the JDK in the drop down list, click “Installed JRE …”
In the “Preferences” dialog, click “Add”
Select “Standard VM” and click “Next”
Click “Directory” and navigate to your JDK installation directory. Then click “Finish” to return to the previous dialog.
Select the JDK and click Ok.
Select JDK in the drop down box and click OK
Step 3 : Install and configure JPF
Create site.properties under <user.home>/.jpf folder.
To create the folder on windows, use the following command on the command window after navigating to the user home: mkdir .jpf .
Paste the following content into the site.properties file.``` # JPF site configuration
jpf.home = ${user.home}/projects/jpf
jpf-core = ${user.home}/projects/jpf/jpf-core
jpf-aprop = ${jpf.home}/jpf-aprop extensions+=,${jpf-aprop}
jpf-numeric = ${jpf.home}/jpf-numeric extensions+=,${jpf-numeric}
#jpf-concurrent = ${jpf.home}/jpf-concurrent #extensions+=,${jpf-concurrent} jpf-shell = ${jpf.home}/jpf-shell extensions+=,${jpf-shell} jpf-awt = ${jpf.home}/jpf-awt extensions+=,${jpf-awt}
jpf-awt-shell = ${jpf.home}/jpf-awt-shell extensions+=,${jpf-awt-shell}
Step 4 : Start the demo project
Step 4.1 : Create and configure project
Step 4.2 : Create a class (program under test)
Right click on the “src” folder and choose: New » Class. Name it Calculator and click Finish.
This is the content of the very simple Calculator.java which prints the sum of two integers. The Verify statements are the only JPF statements, the rest is pure java. We will explain the JPF statements through its results in the next step.
import gov.nasa.jpf.jvm.Verify;
public class Calculator {
int add (int a, int b)
{
return a+b;
}
public static void main(String\[\] args)
{
int a = Verify.getInt(1,3);
int b = Verify.getInt(5,8);
Calculator cal = new Calculator();
System.out.println(a + "+" + b + "=" + cal.add(a, b));
}
}
Step 4.3 : Run JPF from Eclipse
Right click on the project name and select: New » File. Name the file “jpf_junit_demo.jpf”.
This is the content of the newly added file
+classpath=${config_path}/bin
target=TestGenerator
In the package explorer, right click on the “jpf_junit_demo.jpf” and select “Verify …”.
If you couldn’t see the “Verify…” option, this means that you didn’t installed the JPF plug-in properly. See step 3.3.
JPF will get started and you will see its output in the console pane. It will be like the following:
Executing command: java -jar C:\\Users\\Ebeid\\projects\\jpf\\jpf-core\\build\\RunJPF.jar +shell.port=4242 C:\\Users\\Ebeid\\projects\\jpf\_junit\_demo\\jpf\_junit.demo.jpf
JavaPathfinder v6.0 (rev 960+) - (C) RIACS/NASA Ames Research Center
====================================================== system under test
application: Calculator.java
====================================================== search started: 3/28/13 4:41 PM
1+5=6
1+6=7
1+7=8
1+8=9
2+5=7
2+6=8
2+7=9
2+8=10
3+5=8
3+6=9
3+7=10
3+8=11
====================================================== results
no errors detected
====================================================== statistics
elapsed time: 00:00:02
states: new=5, visited=11, backtracked=16, end=12
search: maxDepth=3, constraints hit=0
choice generators: thread=1 (signal=0, lock=1, shared ref=0), data=4
heap: new=545, released=197, max live=353, gc-cycles=13
instructions: 5098
max memory: 55MB
loaded code: classes=82, methods=1362
====================================================== search finished: 3/28/13 4:41 PM
According to our program code and the JPF results, you may already guessed what the verify statements are doing in the following lines of code:
int a = Verify.getInt(1,3);
int b = Verify.getInt(5,8);
So, the total versions of the program running by JPF is 3 * 4 = 12. Its like a tree where the leafs are the print statements :
you can use JPF for your JUnit tests to generate explore your code states as we did; just keep in mind that a small increase in the number of states of variables could result in huge number of total program states.
I hope you enjoyed it, and see you later in more posts about JPF.