2

I am trying to find a way to manipulate the bytecode of a class (at runtime) just before it is loaded. I need to do this because the manipulation depends on something that is not present before main (and potentially before the subject class is loaded).

I already looked at java agents. The premain method is obviously not applicable here, because it is executed before main, which means it can't depend on something that is set up in main. The other option seems to be agentmain and manually loading the agent at runtime. Now the problem with this is that in the newer versions (9+), the dependencies needed to do that (tools.jar) don't seem to be present anymore.

Now, I'd like to know what would be the best way to manipulate bytecode at a specific point in runtime or just before a class is loaded and if that is still possible somehow with Java 9+.

Johnny
  • 67
  • 5
  • I think the tools are "present" but not present by default. They changed the way Java JDK is distributed after Java 8 due to the new release schedule. Not sure where they went, ask around and I'm sure you can find them. – markspace Jun 29 '19 at 16:00
  • In `premain` you just adding transformer, it won't be used right away. It will be used later on just before class will be loaded - check https://jrebel.com/rebellabs/how-to-inspect-classes-in-your-jvm/ and https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/ClassFileTransformer.html – Grzesuav Jul 17 '19 at 16:19

1 Answers1

1

The premain method is obviously not applicable here, because it is executed before main, which means it can't depend on something that is set up in main

This is not true. The agent does not need to modify the class bytecode right at the agent load time. It may just register ClassFileTransformer and postpone bytecode manipulation until the target class is loaded later. Alternatively an agent can simply save Instrumentation instance to be used later at any convenient moment of time.

in the newer versions (9+), the dependencies needed to do that (tools.jar) don't seem to be present anymore

This is also not quite correct. Attach API exists in all new versions of JDK. Since JDK 9 it no longer requires tools.jar, instead it belongs to jdk.attach module.

To facilitate attach in runtime you may use byte-buddy-agent or a standalone jattach utility. Both work with JDK 8- as well as with JDK 9+.

apangin
  • 92,924
  • 10
  • 193
  • 247