Mark Roberts
Mark Roberts

Reputation: 101

Instrumenting Java 9+ runtime modules

Our tool (http://plse.cs.washington.edu/daikon) calculates program invariants by inserting instrumentation into the Java byte codes for a program. The user code is instrumented during runtime via the normal ClassFileTransformer::transform method.

It is also necessary to track value flows through JDK methods. Thus, we need to instrument the Java runtime as well. We cannot use transform, because hundreds of runtime methods are loaded prior to the first time we get control at transform.

Prior to Java 9, we handled this in an offline step that reads rt.jar, instruments its methods, and writes out a modified version as dcomp-rt.jar. The user placed dcomp-rt.jar on the bootclasspath to ensure our modified Java runtime methods were loaded instead of the standard ones. The user program invocation would look something like:

java -cp .:.../daikon/daikon.jar \
  -Xbootclasspath/p:.../daikon/java/dcomp_rt.jar:.:.../daikon/daikon.jar \
  -javaagent:.../daikon/java/dcomp_premain.jar={various dcomp arguments} \
  {user program} {user program arguments}

Now to Java 9+. Our first approach was to read in and instrument the class files within the Java runtime jmod files (via the new jrt:/ file system) and create a dcomp_rt.jar as before. The problem we are experiencing is that we cannot get the system to use the contents of this jar instead of jrt:/java.base (for example). We tried various --module-path and -Xbootclasspath (only /a is available now, might be part of problem) options to no avail. Still hoping there might be a way to do this?

If not, I'm guessing we need to make modified versions of each of the interesting runtime jmods and then use a --patch-module argument for each of them. Would this ensure our modified code is loaded instead of the standard runtime?

Any thoughts/suggestions?

Upvotes: 2

Views: 428

Answers (1)

Mark Roberts
Mark Roberts

Reputation: 101

Well it looks like --patch-module does the trick. I made the same dcomp_rt.jar but with only classes from java.base.jmod. Then used:

 --patch-module java.base={full path}/dcomp_rt.jar

Running java with -verbose:class showed all base classes being loaded from my jar.

Is this the best way to accomplish my goal?

Upvotes: 1

Related Questions