-----------------------
Javalib & Sawja
-----------------------

Download: Javalib / Sawja

Introduction

Javalib is a library to parse Java .class files into OCaml data structures, thus enabling the OCaml programmer to extract information from class files, to manipulate and to generate valid .class files.

It is distributed under the GNU Lesser General Public License (see LICENSE file).

Sawja is a library written in OCaml, relying on Javalib to provide a high level representation of Java bytecode programs. Whereas Javalib is dedicated to isolated classes, Sawja handles bytecode programs with their class hierarchy and with control flow algorithms.

Moreover, Sawja provides some stackless intermediate representations of code, called JBir and A3Bir. The transformation algorithm, common to these representations, has been formalized and proved to be semantics-preserving1.

It is distributed under the GNU Lesser General Public License (see LICENSE file).


  1. D. Demange, T. Jensen and D. Pichardie. A Provably Correct Stackless Intermediate Representation For Java Bytecode . Research Report 7021, INRIA, 2009. See http://irisa.fr/celtique/ext/bir/rr7021v2.pdf

Quick start

We quickly present some OCaml code allowing to load a full program and to transform it into JBir intermediate representation. To get started, run the command make ocaml in the source repository of Sawja. Then you can run the generated toplevel named ocaml, which includes Javalib and Sawja modules. You need to enter some #directory directives to specify the location of the .cmi files needed by Javalib and Sawja.

Loading a program

Given an archive test.jar containing a class named Test.class defining a main method, we can load the corresponding program, assuming that the $CLASSPATH environment variable contains the test.jar file and the Java Runtime rt.jar. Enter the following directives in your toplevel:

    #cd "... path of your test.jar archive ...";;
    #directory "... path of Javalib sources ...";;
    #directory "... path of Sawja sources ...";;
  

    let (prta,instantiated_classes) =
      JRTA.parse_program (Sys.getenv "CLASSPATH")
         (JBasics.make_cn "Test", JProgram.main_signature);;
  

Now we generate the .html files corresponding to the parsed program prta. One file per class is generated and the package tree is reproduced in the destination directory. The destination directory must exist otherwise an exception will be raised.

    let outputdir = "./test"
    let () =
      JPrintHtml.pp_print_program_to_html_files prta outputdir;;
  

You can open the file ./test/Test.html with a web browser and navigate through the class hierarchy, or follow the control flow graph.

Transforming a program

We transform the previously loaded program.

    let pbir = JProgram.map_program2
      (fun _ -> JBir.transform ~compress:false) prta;;
  

To see how JBir representation looks like, we can pretty-print one class to the standard output, for instance java.lang.Object.

    let obj = JProgram.get_node pbir JBasics.java_lang_object
    let () = Javalib.JPrint.print_class (JProgram.to_ioc obj) JBir.print stdout;;
  


Last modification: 2009-11-02 22:50:44.000000000 +0100