next up previous
Next: Tight event coupling Up: JiST- Java in Simulation Previous: Proxy entities

Reflection

An important consideration in the design of many popular simulators is configurability and the desire is to reuse the same simulation code for many different experiments. A few design approaches are possible. The first is source-level reuse. This approach involves the recompilation of the simulation program before each run with hard-coded simulation parameters and possibly also with a small driver program for simulation initialization. While the source-based approach is flexible and also runs efficiently, it is cumbersome to require recompilation on each run. A second approach is to use a configuration file that is parsed by a more sophisticated driver program as it initializes the simulation. This eliminates the need for recompilation in many circumstances, but it it is a brittle and inflexible option, since it is limited to pre-defined configuration options. A third approach is to integrate a scripting language into the simulation for purposes of configuration, an approach championed by ns2. The scripting language interpreter - Tcl, in the case of ns2, - is backed by the compiled simulation runtime, so that script variables are linked to simulation values. The script is used to instantiate and initialize the various pre-defined simulation components. This is an attractive, flexible approach, since it allows the simulation to be configured with a script.

Unfortunately, the linkage between the compiled simulation components and the interpreted simulation configuration scripts is difficult to establish. It is achieved manually via a programming pattern called split objects, which requires interface functions that channel information in objects within the compiled space to and from objects in the interpreted space. This not only clutters the core simulation code, but it is also inefficient in that it duplicates information within the process memory. Furthermore, the script performance depends heavily on these interfaces. The choice of binding ns2 with Tcl, for example, requires excessive string manipulation and leads to long configuration times.

In contrast, the scripting functionality comes ``for free'' in JiST. It does not require any additional code in the simulation components. It does not incur any additional memory overhead. And, the script can configure a simulation just as quickly as a custom driver program. This is all possible because Java is a dynamic language that supports reflection. A script engine can query and update simulation values by reflection and can also dynamically pre-compile the driver script directly to bytecode for efficient execution. As illustrated in Figure 8, the access that the script engine has to the simulation state is just as efficient and expressive as the compiled driver program.

Figure 8: JiST can easily provide multiple scripting interfaces to configure its simulations without source modification, memory overhead, or loss of performance. (1) As before, the simulation classes are loaded and rewritten on demand. (2) The script engine configures the simulation, using reflection and may even dynamically compile the script to bytecode for performance. (3) The simulation then runs, as before, interacting with the kernel as necessary.
\begin{figure}\resizebox{\columnwidth}{!}{\begin{picture}(0,0)%
\includegraphics{figs/script}%
\par
\end{picture}\input{figs/script.texi}}
\end{figure}

Figure 9: Basic example of BeanShell and Jython script-based simulation drivers. One can use Java-based scripting languages to configure and initialize simulations from existing components.
\begin{figure}\small
\medskip
\hrulefill\hspace{1ex}{\tt hello.bsh}\hspace{1ex...
...input{include/hello.jpy.html}
\vspace{2ex}
\hrule
{\small }
\par\end{figure}

A number of robust Java scripting engines already exist. JiST supports the BeanShell engine, with its Java syntax, and also the Jython engine, which interprets Python scripts. If desired, other engines, such as Bistro (Smalltalk), Jacl (Tcl), JRuby (Ruby), Kawa (Scheme), Rhino (JavaScript) or a custom simulation definition language interpreter can easily be integrated as well and they can even co-exist.

As is the case with compiled driver programs, the driver script is invoked within its host script engine by the JiST kernel. The script is the first, bootstrap event of any simulation. In addition, this functionality is exposed via the JistAPI, so that even simulation programs can embed configuration scripts that are specific to those simulations. For example, a wireless network simulator written atop JiST, called SWANS, uses scripts to configure network topology and node protocol stacks.


next up previous
Next: Tight event coupling Up: JiST- Java in Simulation Previous: Proxy entities
2006-01-18