Now that I’m adding the
InstrumentingClassLoader to the runtime to load and instrument classes on the fly, additional classes need to go into the rt.jar file, and it quickly becomes confusing which ones to include. The custom class loader references nearly the entire runtime portion of the project, but not the JPDA monitor.
I still didn’t want to draw the line by hand and risk a mistake. Well, I did and failed. Practically, all classes that get referenced in the class I am running need to be available in rt.jar, and all the classes that get referenced in them, and so on. Conceptually, this is the least class dependency fixpoint.
Now I wrote a tool,
edu.rice.cs.cunit.DependencyFixPoint, that lists all the classes in that fixpoint, starting with any number of classes. The files can be output as file names and piped into jar to create an archive of just the files necessary. Now everything is automated and exactly the right files get added to the runtime.
I’ve also fixed a bug related to the Instrumentation attribute. Until tonight, I never had the case where the string “Instrumentation” was already present in the class file, and it worked because a new item was added to the constant pool. Tonight, I instrumented InstrumentingClassLoader.class, which already contains the string “Instrumentation”, so it is supposed to reuse it. That’s where it failed. Fixed.
And I’ve noticed that I actually don’t need to include the monitor.jar file (which I now renamed cunitrt.jar) separately on the boot class path. I merge it into the rt.jar already.
I just found another problem. The way I changed the automation, now all the files added to the rt.jar got instrumented. Of course,
SyncPointRecorder still contains that little comment “do not instrument”, which now got ignored. Infinite recursion generally isn’t a good thing.
Now you can add the @DoNotInstrument annotation to a class to prevent it from getting instrumented. Both the offline
FileInstrumenter and the on the fly
InstrumentingClassLoader obey the annotation.