The original java.net API lacked one of the most used techniques when building
short-lived servers: demultiplexing I/O. This technique avoids spawning a new thread
for each new service, using instead a single execution thread to serve clients simultane-
ously. This functionality was added in version 1.4, which included the new java.nio
API including the Selector framework (implementing the native OS mechanism for de-
multiplexing I/O). Unfortunately, this framework achieved backward compatibility at
the expense of complicating the class structure existing in java.net. The new API
is partially shown in fig. 2, where some new elements are depicted: Channels (an evo-
lution of Stream objects) and Buffers (representing platform-level buffers which allow
zero-copy data operations).
3 Model Checking Internet Protocols with JPF
Java PathFinder can verify any Java program which does not depend on unsupported
native methods. The JPF virtual machine cannot execute platform specific or native
code, which imposes a restriction on what standard libraries can be used from within
the application under test. For instance, the current version of JPF does not support
java.awt, java.net, java.nio, and only has limited support for java.io and
runtime reflection. The huge state storage requirements for a software system also limit
the size of checkable applications. The JPF developers have estimated a maximum of
10.000 lines of code if no application and property specific abstractions are used [7].
Fortunately, JPF was designed as an open tool with extension capabilities. These
extensions allow users to adapt the model checking process to their specific applications
and properties. The main mechanisms available in JPF for extensions are:
– Listeners. The SearchListener and VMListener interfaces may be implemented to
modify the basic behavior of the model checking algorithm. A variant of the Ob-
server design pattern [8] allows listeners to subscribe to different events (bytecode
execution, forward or backward steps,...).
– Configurable choice generators. The ChoiceGenerator class is the extension point
responsible for implementing non-determinism policies to explore the state space
in terms of thread states or data values. After executing a system transition, JPF
prepares a ChoiceGenerator object which will be called to select the next transition
to run. A ThreadChoiceGenerator will schedule threads to run, whereas other user-
defined generators are focused on defining a finite data interval to explore.
– The Model Java Interface (MJI). Even if it is only a Java application (i.e. solely
consists of Java classes), JPF can be viewed as a Java Virtual Machine in itself.
The consequence is that (*.class) bytecodes are processed in two different ways in
a JVM running JPF: i) as ordinary Java classes managed and executed by the host
JVM (standard Java library classes, JPF implementation classes) or ii) as modelled
classes managed and processed (verified) by JPF.
Fig. 3 depicts JPF interfaces and their relationship with the host Java virtual ma-
chine. In the bottom layer we find the Java Native Interface (JNI) used by the virtual
machine to execute native libraries on top of the platform operating system. The Java
layer contains the JPF application that runs on top of the virtual machine and uses the
94