Because I was stuck with the hanging slave, I took a look at the InstrumentingClassLoader again. It’s a custom class loader that rewrites class files as they are loaded during runtime.
I abandoned working on that a while ago when I ran into problems with mutually recursive references. Somehow, my class loader got confused when it was loading a class A that referenced a class B that, directly or indirectly, referenced A again… Instead, I resorted to offline instrumentation using FileInstrumentor. That makes more sense with the giant rt.jar anyway. There’s no reason to instrument those classes all over again.
I haven’t tested it a lot yet, but at least it seems to integrate well with the launcher and the JPDA monitor. Now I have a lot more files that should not be instrumented, though, that need to be included in the bootclasspath and loaded.
I felt like adding a string mask to exclude them wasn’t flexible enough, so I introduced a custom attribute called “Instrumentation”. If a file has been instrumented already, that attribute is added to the class file. The attribute data is a string of the instrumentor class names, separated by semicolon. Currently, the following string is generated:
"edu.rice.cs.cunit.instrumentors.MethodHashTableInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.ThreadInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.SleepYieldCallInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.SleepYieldInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.ObjectCallInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.ObjectInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.SynchronizedMethodToBlockInstrumentationStrategy; edu.rice.cs.cunit.instrumentors.SynchronizedBlockInstrumentationStrategy"
If a class just shouldn’t be instrumented, then that attribute is added with an empty string. A class is only instrumented if the “Instrumentation” attribute is not present yet. After that, it is added with the proper string.