3

Libraries such as ASM, BCEL, Javaassist and AspectJ are all capable of runtime bytecode manipulation but how do they achieve this?

I have done some basic bytecode manipulation using ASM before but i don't understand how it works. Is the Java Agent executed in the JVM before the remainder of the program, allowing for ASM to load the compiled classes and edit them before they are executed by the JVM?

If so, is it possible to perform java bytecode manipulation without using an external library like ASM and loading the compiled class files with an BufferedReader and writing a custom parser etc. for example?

Will D
  • 43
  • 5
  • The term "External Library" may be a bit vague. Whatever "external libraries" are doing, you theoretically can always copy&paste their code, and then they are not "external" any more. It seems like the question is rather about **how** these libraries actually achieve what they are doing. (I could again refer to their source code now, but ... maybe someone can write a proper answer....) – Marco13 Oct 07 '18 at 12:35
  • I suppose Third Party Library would be a better way to put it, regardless I will be looking into the source code for some of the aforementioned libraries, however any comments are still appreciated – Will D Oct 07 '18 at 12:39

3 Answers3

3

These libraries settle on standard Java APIs which, of course, you can also use yourself without these libraries.

First of all, Java class files are just sequences of bytes in a well defined format, as specified in JVMS §4, The class File Format. The primary task of the mentioned libraries is to provide tools for processing byte sequences in this format. The second is about getting the definitions of existing or exporting modified or newly created classes.

There are two different way of dealing with the second task. One is to read compiled classes from persistent storage like file systems or jar files, etc. and writing them back to these storage while the particular code is not running, like build and deployment tools do. This should be trivial, as it just boils down to reading and writing bytes.

The other is to manipulate classes at runtime, which can be done by Java Agents via the Instrumentation API. It offers mechanisms for intercepting classes at loading/definition time before their first use, but also redefinition of classes. The latter can’t change them freely, currently, it has to retain all field and method declarations, so it can be mainly used to change the executable code of the methods.

If you want examples for class file processing without additional 3rd party libraries, there are some answers on Stackoverflow

Of course, these examples are only single-purpose code or sketches. If you expand them to something more general or useful, you will soon end up at basically re-implementing these libraries.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thank you for your in depth response, I had come to a fairly similar understanding but I appreciate the clarification and the examples – Will D Oct 09 '18 at 15:15
3

Recently java development group at Oracle announced a new JEP( Java enhancement proposal) for class file manipulation. Now we will not need any additional libraries.

https://openjdk.org/jeps/8280389

Vipin
  • 4,851
  • 3
  • 35
  • 65
1

Class files are just a sequence of bytes, the format of which is specified in The Java Virtual Machine Specification. BufferedReader is for text files so you'd want BufferedInputStream, but the format is quite complicated.

You can load manipulated class files as if they were generated by javac. You can also load them dynamically with java.net.URLClassLoader.newInstance or similar. Java Agent allows modification of class files as they are loaded, either through a Java or a native interface (the latter being necessary if you want to modify classes the are loaded before classes that load classes).

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305