The NSF Faculty Early Career Development (CAREER) Program is a grant program that aims to support early-career tenure-track faculty in building a research group and a career in academia as independent scholars. Unique from other grant awards, the CAREER supports a single PI, pre-tenure, and provides a 5-year period of support. Hence, the CAREER program provides an important opportunity for faculty to build and demonstrate research vision and independence.
I was recently wrangling with some nastiness involving several different tools, each of which was performing bytecode instrumentation. The problem was that one tool (Mockito, which I didn’t feel like digging into, and am using as a black-box) was modifying my transformed code, and it was very difficult to tell exactly what it was doing to my code. It is easy for me to dump out class files for the code that I generate, but seemingly hard to get Mockito to do.
Debugging (Failed) Instrumentation through sun.misc.Unsafe.defineAnonymousClass
defineAnonymousClass is a super handy method of the notorious sun.misc.Unsafe “escape hatch” in the JVM. defineAnonymousClass is used as a fast-path to define specialized anonymous classes which are not rigorously verified, are not loaded into a class loader (e.g. they exist only so long as you hold a reference to one, perhaps through an instance of an object of that type), and can have their constant pools lazily patched at load-time. For classes that do not need to be accessible from anywhere other than the class that defines them, defineAnonymousClass is a much faster way to load in a class. defineAnonymousClass is used under-the-hood to implement Lambdas, and we aggressively used it to implement CROCHET.
Debugging Java Bytecode Instrumentation
If you’ve ever tried, or are planning to try instrumenting the JRE, and plan to instrument the entire JRE, you might have run up against some “fun” debugging challenges. For instance, you might have found out that it is possible to generate some bytecode that causes the JVM to produce a segmentation fault while starting. This can be really, really really annoying to debug if you aren’t aware of all of the great tools available. Here are some key tricks (going from most straightforward to least), all written down in one place. I’m aware that this isn’t so much of a how-to to use each of these approaches, as much as it is some pointers down the right path, as when I was trying to figure this all out I had a really tough time finding where to start.