Performing bytecode manipulation using APIs like javaassist modify class files after compilation. But, if the java code is optimized can't the modifications be performed in the wrong place? Are there ways to avoid this problem? Is the story any different between regular Java and Android?
Bytecode manipulation consists in modifying the classes - represented by bytecode - compiled by the Java compiler, at runtime. It is used extensively for instance by frameworks such as Spring (IoC) and Hibernate (ORM) to inject dynamic behaviour to Java objects at runtime.
Disadvantages. The bytecode cannot run without an interpreter or JVM. If any device doesn't have JVM, bytecode won't run on that device. It is difficult to analyze the bytecode as it is in the form of binary and not understandable by humans.
Unlike human-readable source code, bytecodes are compact numeric codes, constants, and references (normally numeric addresses) that encode the result of compiler parsing and performing semantic analysis of things like type, scope, and nesting depths of program objects.
Advantages of Bytecode Bytecodes are non-runnable codes that rely on the availability of an interpreter, this is where JVM comes into play. It is a machine-level language code that runs on the JVM. It adds portability to Java which resonates with the saying, “write once, read anywhere”.
A typical Java program is compiled multiple times. In a first step, Java source code is translated into Java byte code. In a second step, Java byte code is translated into machine code.
The details of this process are of course dependent on the virtual machine that runs code. Early versions of Java did for example not include a so-called just-in-time compiler. In this case, the byte code was interpreted instruction by instruction where byte code manipulations could of course have a performance impact. But this is not longer true. Both the OpenJDK's HotSpot virtual machine as well as Android's ART and DEX runtimes perform optimizations of the byte code.
The javac compiler that translates source code into byte code performs very few optimizations. You should not normally worry about the performance impact of the to-byte-code translation step. However, in some cases, the byte code that is produced by runtime code generation can have a performance impact. This happens when the just-in-time compiler observes byte code that is difficult to optimize. Typically, this is caused by unnecessary object allocations which are difficult to optimize away.
If you want to look in the details of this matter, I have given this presentation where I talk a bit about the problem: https://www.youtube.com/watch?v=XMY6HA7_h5Y
As for safety: As long as the byte code manipulation does not corrupt the byte code, there is no problem. If it does corrupt the byte code, the Java virtual machine will refuse loading the class with the corrupt code. This is both true for HotSpot and Android which verify any byte code previous to loading a class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With