The joeq bootstrapping technique is detailed in the following paper:
John Whaley. System Checkpointing Using Reflection and Program Analysis. Proceedings of the Third International Conference on Metalevel Architectures and Separation of Crosscutting Concerns, REFLECTION 2001, Kyoto, Japan, September 25-28, 2001, pp 44-51.
Here is an overview. joeq uses the Java 2 Reflection API to bootstrap itself. The basic bootstrapping technique is as follows:
The relevant source code is contained in Main/Bootstrapper.java and Bootstrap/BootImage.java.
The technique described above will generate a precise copy of the relevant state of the host Jvm. However, we don't always want an exact copy. For example, file handles in the host Jvm cannot be used in the target Jvm. The target Jvm may use extra object fields that are not present in the host Jvm. Or we may want to use a different class library implementation than the host Jvm.
We handle the mapping of state from the host Jvm to the target Jvm by hijacking the reflection mechanism, using a class called ObjectTraverser, in Bootstrap/ObjectTraverser.java. All accesses of host Jvm objects go through this class. When, for example, we attempt to use reflection on a field that doesn't exist in the host Jvm, we hijack the reflective call and return our own value. We can also replace references to objects: for example, all references to the host Jvm's system class loader are replaced by references to the target Jvm's class loader. Different class libraries use different implementations of ObjectTraverser, for example, in ClassLib/Common/Interface.java.
Furthermore, some objects require some state to be reinitialized upon re-execution; for example, files must be reopened. This is handled in the mapValue method of the ObjectTraverser class. When we use reflection on an object that requires some code to be executed, we add that code to a list in jq.on_vm_startup. Code in that list is executed at program startup.