SlideShare a Scribd company logo
Java byte code
in practice
0xCAFEBABE
source code
byte code
JVM
javac scalac groovyc jrubyc
JIT compilerinterpreter
class loader
creates
reads
runs
source code byte code
void foo() {
}
RETURNreturn; 0xB1
source code byte code
int foo() {
return 1 + 2;
}
ICONST_1
ICONST_2
IADD
operand stack 1
2
13
IRETURN
0x04
0x05
0x60
0xAC
source code byte code
ICONST_2
IADD
IRETURN
BIPUSH
int foo() {
return 11 + 2;
}
operand stack 11
2
1113
0x05
0x60
0xAC
0x10 110x0B
source code byte code
int foo(int i) {
return i + 1;
}
ILOAD_1
ICONST_1
IADD
IRETURN
operand stack
local variable array
1 : i
0 : this
i
1
ii + 1
0x1B
0x04
0x60
0xAC
source code byte code
long foo(long i) {
return i + 1L;
}
LLOAD_1
LCONST_1
LADD
LRETURN
operand stack
local variable array
2 : i (cn.)
1 : i
0 : this
i (cn.)
i
0x1F
0x0A
0x61
0xAD
i (cn.)
i
1L
1L (cn.)
i + 1L
i + 1L (cn.)
source code byte code
short foo(short i) {
return (short) (i + 1);
}
ILOAD_1
ICONST_1
IADD
I2S
IRETURN
operand stack
local variable array
1 : i
0 : this
1
iii + 1
0x1B
0x04
0x60
0x93
0xAC
source code byte code
pkg/Bar.class
void foo() {
return;
}
RETURN
package pkg;
class Bar {
}
constant pool (i.a. UTF-8)
0x0000
0x0000: foo
0x0001: ()V
0x0002: pkg/Bar
0xB1
0x0000 0x0000foo ()V()V0x0001
0x00000 1 10x0001
operand stack /////////////////
local variable array 0 : this
Java type JVM type (non-array) JVM descriptor stack slots
boolean
I
Z 1
byte B 1
short S 1
char C 1
int I 1
long L J 2
float F F 1
double D D 2
void - V 0
java.lang.Object A Ljava/lang/Object; 1
source code byte code
package pkg;
class Bar {
int foo(int i) {
return foo(i + 1);
}
}
ILOAD_1
ICONST_1
IADD
INVOKEVIRTUAL pkg/Bar foo (I)I
ALOAD_0
IRETURN
operand stack
local variable array
1 : i
0 : this
this
i
1
this
ii + 1
foo(i + 1)
0x2A
0x1B
0x04
0x60
0xAC
0xB6
constant pool
0x0002 0x0000 0x0001
INVOKESPECIAL
INVOKEVIRTUAL
INVOKESTATIC
INVOKEINTERFACE
INVOKEDYNAMIC
Invokes a static method.
pkg/Bar foo ()V
pkg/Bar foo ()V
Invokes the most-specific version of an inherited method on a non-interface class.
pkg/Bar foo ()V
Invokes a super class‘s version of an inherited method.
Invokes a “constructor method”.
Invokes a private method.
Invokes an interface default method (Java 8).
pkg/Bar foo ()V
Invokes an interface method.
(Similar to INVOKEVIRTUAL but without virtual method table index optimization.)
foo ()V bootstrap
Queries the given bootstrap method for locating a method implementation at runtime.
(MethodHandle: Combines a specific method and an INVOKE* instruction.)
void foo() {
???(); // invokedynamic
}
foo() ? qux()
bootstrap()
bar()
void foo() {
bar();
}
In theory, this could be achieved by using reflection. However, using invokedynamic
offers a more native approach. This is especially important when dealing with
primitive types (double boxing).
Used to implement lambda expressions, more important for dynamic languages.
interface Framework {
<T> Class<? extends T> secure(Class<T> type);
}
class Service {
@Secured(user = "ADMIN")
void deleteEverything() {
// delete everything...
}
}
@interface Secured {
String user();
}
class SecurityHolder {
static String user = "ANONYMOUS";
}
does not know aboutdepends on
discoversatruntime
class Service {
@Secured(user = "ADMIN")
void deleteEverything() {
if(!"ADMIN".equals(UserHolder.user)) {
throw new IllegalStateException("Wrong user");
}
// delete everything...
}
}
redefine class
(build time, agent)
create subclass
(Liskov substitution)
class SecuredService extends Service {
@Override
void deleteEverything() {
if(!"ADMIN".equals(UserHolder.user)) {
throw new IllegalStateException("Wrong user");
}
super.deleteEverything();
}
}
class Service {
@Secured(user = "ADMIN")
void deleteEverything() {
// delete everything...
}
}
The “black magic” prejudice.
var service = {
/* @Secured(user = "ADMIN") */
deleteEverything: function () {
// delete everything ...
}
}
function run(service) {
service.deleteEverything();
}
In dynamic languages (also those running on the JVM) this concept is applied a lot!
For framework implementors, type-safety is conceptually impossible.
But with type information available, we are at least able to fail fast when generating
code at runtime in case that types do not match.
No type, no problem.
(“duck typing”)
class Method {
Object invoke(Object obj,
Object... args)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException;
}
class Class {
Method getDeclaredMethod(String name,
Class<?>... parameterTypes)
throws NoSuchMethodException,
SecurityException;
}
Isn’t reflection meant for this?
Reflection implies neither type-safety nor a notion of fail-fast.
Note: there are no performance gains when using code generation over reflection!
Thus, runtime code generation only makes sense for user type enhancement: While
the framework code is less type safe, this type-unsafety does not spoil the user‘s code.
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(named("toString"))
.intercept(value("Hello World!"))
.make()
.load(getClass().getClassLoader(),
ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertThat(dynamicType.newInstance().toString(),
is("Hello World!"));
Byte Buddy: subclass creation
class MyInterceptor {
static String intercept() {
return "Hello World";
}
}
identifiesbestmatch
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(named("toString"))
.intercept(to(MyInterceptor.class))
.make()
.load(getClass().getClassLoader(),
ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
Byte Buddy: invocation delegation
Annotations that are not on the class path are ignored at runtime.
Thus, Byte Buddy’s classes can be used without Byte Buddy on the class path.
class MyInterceptor {
static String intercept(@Origin Method m) {
return "Hello World from " + m.getName();
}
}
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(named("toString"))
.intercept(to(MyInterceptor.class))
.make()
.load(getClass().getClassLoader(),
ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
providesarguments
Byte Buddy: invocation delegation (2)
@Origin Method|Class<?>|String Provides caller information
@SuperCall Runnable|Callable<?> Allows super method call
@DefaultCall Runnable|Callable<?> Allows default method call
@AllArguments T[] Provides boxed method arguments
@Argument(index) T Provides argument at the given index
@This T Provides caller instance
@Super T Provides super method proxy
Byte Buddy: dependency injection
class Foo {
String bar() { return "bar"; }
}
Foo foo = new Foo();
new ByteBuddy()
.redefine(Foo.class)
.method(named("bar"))
.intercept(value("Hello World!"))
.make()
.load(Foo.class.getClassLoader(),
ClassReloadingStrategy.installedAgent());
assertThat(foo.bar(), is("Hello World!"));
The instrumentation API does not allow introduction of new methods.
This might change with JEP-159: Enhanced Class Redefiniton.
Byte Buddy: runtime Hot Swap
class Foo {
String bar() { return "bar"; }
}
assertThat(new Foo().bar(), is("Hello World!"));
public static void premain(String arguments,
Instrumentation instrumentation) {
new AgentBuilder.Default()
.rebase(named("Foo"))
.transform( (builder, type) -> builder
.method(named("bar"))
.intercept(value("Hello World!"));
)
.installOn(instrumentation);
}
Byte Buddy: Java agents
Java virtual
machine
[stack, JIT]
Dalvik virtual
machine
[register, JIT]
Android
runtime
[register, AOT]
Android makes things more complicated.
Solution: Embed the Android SDK’s dex compiler (Apache 2.0 license).
Unfortunately, no recent version central repository deployments of Android SDK.
Byte Buddy cglib Javassist Java proxy
(1) 60.995 234.488 145.412 68.706
(2a) 153.800 804.000 706.878 973.650
(2b) 0.001 0.002 0.009 0.005
(3a) 172.126
1’850.567
1’480.525 625.778 n/a
(3b) 0.002
0.003
0.019 0.027 n/a
All benchmarks run with JMH, source code: https://github.com/raphw/byte-buddy
(1) Extending the Object class without any methods but with a default constructor
(2a) Implementing an interface with 18 methods, method stubs
(2b) Executing a method of this interface
(3a) Extending a class with 18 methods, super method invocation
(3b) Executing a method of this class
http://rafael.codes
@rafaelcodes
http://documents4j.com
https://github.com/documents4j/documents4j
http://bytebuddy.net
https://github.com/raphw/byte-buddy

More Related Content

What's hot (20)

PPTX
Byte code field report
Rafael Winterhalter
 
PPTX
The Java memory model made easy
Rafael Winterhalter
 
PDF
Bytecode manipulation with Javassist and ASM
ashleypuls
 
PPTX
Mastering Java Bytecode With ASM - 33rd degree, 2012
Anton Arhipov
 
PDF
Java Concurrency by Example
Ganesh Samarthyam
 
PPTX
Java and OpenJDK: disecting the ecosystem
Rafael Winterhalter
 
PPT
Java Basics
Sunil OS
 
PDF
Java Fundamentals
Shalabh Chaudhary
 
PPTX
An Overview of Project Jigsaw
Rafael Winterhalter
 
PDF
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
PDF
Sailing with Java 8 Streams
Ganesh Samarthyam
 
ODP
Java Concurrency
Carol McDonald
 
PPT
Learning Java 1 – Introduction
caswenson
 
PPTX
Code generation for alternative languages
Rafael Winterhalter
 
PPT
Java tut1 Coderdojo Cahersiveen
Graham Royce
 
PPT
Project Coin
Balamurugan Soundararajan
 
PDF
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
PPT
Java Tut1
guest5c8bd1
 
PDF
Java Programming - 03 java control flow
Danairat Thanabodithammachari
 
PPTX
Java 14 features
Aditi Anand
 
Byte code field report
Rafael Winterhalter
 
The Java memory model made easy
Rafael Winterhalter
 
Bytecode manipulation with Javassist and ASM
ashleypuls
 
Mastering Java Bytecode With ASM - 33rd degree, 2012
Anton Arhipov
 
Java Concurrency by Example
Ganesh Samarthyam
 
Java and OpenJDK: disecting the ecosystem
Rafael Winterhalter
 
Java Basics
Sunil OS
 
Java Fundamentals
Shalabh Chaudhary
 
An Overview of Project Jigsaw
Rafael Winterhalter
 
Advanced Debugging Using Java Bytecodes
Ganesh Samarthyam
 
Sailing with Java 8 Streams
Ganesh Samarthyam
 
Java Concurrency
Carol McDonald
 
Learning Java 1 – Introduction
caswenson
 
Code generation for alternative languages
Rafael Winterhalter
 
Java tut1 Coderdojo Cahersiveen
Graham Royce
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 
Java Tut1
guest5c8bd1
 
Java Programming - 03 java control flow
Danairat Thanabodithammachari
 
Java 14 features
Aditi Anand
 

Similar to Java byte code in practice (20)

PPT
Mastering Java ByteCode
Ecommerce Solution Provider SysIQ
 
ODP
Supercharging reflective libraries with InvokeDynamic
Ian Robertson
 
PDF
Jvm internals
Luiz Fernando Teston
 
PDF
Optimizing JavaScript and Dynamic Languages on the JVM
Marcus Lagergren
 
PDF
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
PPT
Groovy Basics
Wes Williams
 
PPTX
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Anton Arhipov
 
PDF
Invoke dynamite in Java EE with invoke dynamic
Antoine Sabot-Durand
 
PDF
Fun with bytecode weaving
Matthew
 
PPTX
Bytecode manipulation with Javassist for fun and profit
Jérôme Kehrli
 
PDF
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
lennartkats
 
PPT
Invoke dynamics
Balamurugan Soundararajan
 
PDF
Invoke dynamic your api to hotspot
Boundary
 
PPTX
Mastering Java Bytecode - JAX.de 2012
Anton Arhipov
 
PPT
Slides
Videoguy
 
PDF
Invokedynamic / JSR-292
ytoshima
 
PPTX
Metaprogramming Techniques In Groovy And Grails
zenMonkey
 
PPT
Understanding Annotations in Java
Ecommerce Solution Provider SysIQ
 
PPTX
Playing with Java Classes and Bytecode
Yoav Avrahami
 
PDF
Dynamic Proxy by Java
Kan-Han (John) Lu
 
Mastering Java ByteCode
Ecommerce Solution Provider SysIQ
 
Supercharging reflective libraries with InvokeDynamic
Ian Robertson
 
Jvm internals
Luiz Fernando Teston
 
Optimizing JavaScript and Dynamic Languages on the JVM
Marcus Lagergren
 
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
Groovy Basics
Wes Williams
 
Binary patching for fun and profit @ JUG.ru, 25.02.2012
Anton Arhipov
 
Invoke dynamite in Java EE with invoke dynamic
Antoine Sabot-Durand
 
Fun with bytecode weaving
Matthew
 
Bytecode manipulation with Javassist for fun and profit
Jérôme Kehrli
 
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
lennartkats
 
Invoke dynamics
Balamurugan Soundararajan
 
Invoke dynamic your api to hotspot
Boundary
 
Mastering Java Bytecode - JAX.de 2012
Anton Arhipov
 
Slides
Videoguy
 
Invokedynamic / JSR-292
ytoshima
 
Metaprogramming Techniques In Groovy And Grails
zenMonkey
 
Understanding Annotations in Java
Ecommerce Solution Provider SysIQ
 
Playing with Java Classes and Bytecode
Yoav Avrahami
 
Dynamic Proxy by Java
Kan-Han (John) Lu
 
Ad

Recently uploaded (20)

PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
DOCX
Import Data Form Excel to Tally Services
Tally xperts
 
PPTX
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PDF
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
PPTX
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
PPTX
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
PDF
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
PDF
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PPTX
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
 
Import Data Form Excel to Tally Services
Tally xperts
 
Tally_Basic_Operations_Presentation.pptx
AditiBansal54083
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
Migrating Millions of Users with Debezium, Apache Kafka, and an Acyclic Synch...
MD Sayem Ahmed
 
Transforming Mining & Engineering Operations with Odoo ERP | Streamline Proje...
SatishKumar2651
 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Efficient, Automated Claims Processing Software for Insurers
Insurance Tech Services
 
Online Queue Management System for Public Service Offices in Nepal [Focused i...
Rishab Acharya
 
Thread In Android-Mastering Concurrency for Responsive Apps.pdf
Nabin Dhakal
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
Equipment Management Software BIS Safety UK.pptx
BIS Safety Software
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
Ad

Java byte code in practice

  • 1. Java byte code in practice
  • 2. 0xCAFEBABE source code byte code JVM javac scalac groovyc jrubyc JIT compilerinterpreter class loader creates reads runs
  • 3. source code byte code void foo() { } RETURNreturn; 0xB1
  • 4. source code byte code int foo() { return 1 + 2; } ICONST_1 ICONST_2 IADD operand stack 1 2 13 IRETURN 0x04 0x05 0x60 0xAC
  • 5. source code byte code ICONST_2 IADD IRETURN BIPUSH int foo() { return 11 + 2; } operand stack 11 2 1113 0x05 0x60 0xAC 0x10 110x0B
  • 6. source code byte code int foo(int i) { return i + 1; } ILOAD_1 ICONST_1 IADD IRETURN operand stack local variable array 1 : i 0 : this i 1 ii + 1 0x1B 0x04 0x60 0xAC
  • 7. source code byte code long foo(long i) { return i + 1L; } LLOAD_1 LCONST_1 LADD LRETURN operand stack local variable array 2 : i (cn.) 1 : i 0 : this i (cn.) i 0x1F 0x0A 0x61 0xAD i (cn.) i 1L 1L (cn.) i + 1L i + 1L (cn.)
  • 8. source code byte code short foo(short i) { return (short) (i + 1); } ILOAD_1 ICONST_1 IADD I2S IRETURN operand stack local variable array 1 : i 0 : this 1 iii + 1 0x1B 0x04 0x60 0x93 0xAC
  • 9. source code byte code pkg/Bar.class void foo() { return; } RETURN package pkg; class Bar { } constant pool (i.a. UTF-8) 0x0000 0x0000: foo 0x0001: ()V 0x0002: pkg/Bar 0xB1 0x0000 0x0000foo ()V()V0x0001 0x00000 1 10x0001 operand stack ///////////////// local variable array 0 : this
  • 10. Java type JVM type (non-array) JVM descriptor stack slots boolean I Z 1 byte B 1 short S 1 char C 1 int I 1 long L J 2 float F F 1 double D D 2 void - V 0 java.lang.Object A Ljava/lang/Object; 1
  • 11. source code byte code package pkg; class Bar { int foo(int i) { return foo(i + 1); } } ILOAD_1 ICONST_1 IADD INVOKEVIRTUAL pkg/Bar foo (I)I ALOAD_0 IRETURN operand stack local variable array 1 : i 0 : this this i 1 this ii + 1 foo(i + 1) 0x2A 0x1B 0x04 0x60 0xAC 0xB6 constant pool 0x0002 0x0000 0x0001
  • 12. INVOKESPECIAL INVOKEVIRTUAL INVOKESTATIC INVOKEINTERFACE INVOKEDYNAMIC Invokes a static method. pkg/Bar foo ()V pkg/Bar foo ()V Invokes the most-specific version of an inherited method on a non-interface class. pkg/Bar foo ()V Invokes a super class‘s version of an inherited method. Invokes a “constructor method”. Invokes a private method. Invokes an interface default method (Java 8). pkg/Bar foo ()V Invokes an interface method. (Similar to INVOKEVIRTUAL but without virtual method table index optimization.) foo ()V bootstrap Queries the given bootstrap method for locating a method implementation at runtime. (MethodHandle: Combines a specific method and an INVOKE* instruction.)
  • 13. void foo() { ???(); // invokedynamic } foo() ? qux() bootstrap() bar() void foo() { bar(); } In theory, this could be achieved by using reflection. However, using invokedynamic offers a more native approach. This is especially important when dealing with primitive types (double boxing). Used to implement lambda expressions, more important for dynamic languages.
  • 14. interface Framework { <T> Class<? extends T> secure(Class<T> type); } class Service { @Secured(user = "ADMIN") void deleteEverything() { // delete everything... } } @interface Secured { String user(); } class SecurityHolder { static String user = "ANONYMOUS"; } does not know aboutdepends on discoversatruntime
  • 15. class Service { @Secured(user = "ADMIN") void deleteEverything() { if(!"ADMIN".equals(UserHolder.user)) { throw new IllegalStateException("Wrong user"); } // delete everything... } } redefine class (build time, agent) create subclass (Liskov substitution) class SecuredService extends Service { @Override void deleteEverything() { if(!"ADMIN".equals(UserHolder.user)) { throw new IllegalStateException("Wrong user"); } super.deleteEverything(); } } class Service { @Secured(user = "ADMIN") void deleteEverything() { // delete everything... } }
  • 16. The “black magic” prejudice. var service = { /* @Secured(user = "ADMIN") */ deleteEverything: function () { // delete everything ... } } function run(service) { service.deleteEverything(); } In dynamic languages (also those running on the JVM) this concept is applied a lot! For framework implementors, type-safety is conceptually impossible. But with type information available, we are at least able to fail fast when generating code at runtime in case that types do not match. No type, no problem. (“duck typing”)
  • 17. class Method { Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException; } class Class { Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException; } Isn’t reflection meant for this? Reflection implies neither type-safety nor a notion of fail-fast. Note: there are no performance gains when using code generation over reflection! Thus, runtime code generation only makes sense for user type enhancement: While the framework code is less type safe, this type-unsafety does not spoil the user‘s code.
  • 18. Class<?> dynamicType = new ByteBuddy() .subclass(Object.class) .method(named("toString")) .intercept(value("Hello World!")) .make() .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); assertThat(dynamicType.newInstance().toString(), is("Hello World!")); Byte Buddy: subclass creation
  • 19. class MyInterceptor { static String intercept() { return "Hello World"; } } identifiesbestmatch Class<?> dynamicType = new ByteBuddy() .subclass(Object.class) .method(named("toString")) .intercept(to(MyInterceptor.class)) .make() .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); Byte Buddy: invocation delegation
  • 20. Annotations that are not on the class path are ignored at runtime. Thus, Byte Buddy’s classes can be used without Byte Buddy on the class path. class MyInterceptor { static String intercept(@Origin Method m) { return "Hello World from " + m.getName(); } } Class<?> dynamicType = new ByteBuddy() .subclass(Object.class) .method(named("toString")) .intercept(to(MyInterceptor.class)) .make() .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER) .getLoaded(); providesarguments Byte Buddy: invocation delegation (2)
  • 21. @Origin Method|Class<?>|String Provides caller information @SuperCall Runnable|Callable<?> Allows super method call @DefaultCall Runnable|Callable<?> Allows default method call @AllArguments T[] Provides boxed method arguments @Argument(index) T Provides argument at the given index @This T Provides caller instance @Super T Provides super method proxy Byte Buddy: dependency injection
  • 22. class Foo { String bar() { return "bar"; } } Foo foo = new Foo(); new ByteBuddy() .redefine(Foo.class) .method(named("bar")) .intercept(value("Hello World!")) .make() .load(Foo.class.getClassLoader(), ClassReloadingStrategy.installedAgent()); assertThat(foo.bar(), is("Hello World!")); The instrumentation API does not allow introduction of new methods. This might change with JEP-159: Enhanced Class Redefiniton. Byte Buddy: runtime Hot Swap
  • 23. class Foo { String bar() { return "bar"; } } assertThat(new Foo().bar(), is("Hello World!")); public static void premain(String arguments, Instrumentation instrumentation) { new AgentBuilder.Default() .rebase(named("Foo")) .transform( (builder, type) -> builder .method(named("bar")) .intercept(value("Hello World!")); ) .installOn(instrumentation); } Byte Buddy: Java agents
  • 24. Java virtual machine [stack, JIT] Dalvik virtual machine [register, JIT] Android runtime [register, AOT] Android makes things more complicated. Solution: Embed the Android SDK’s dex compiler (Apache 2.0 license). Unfortunately, no recent version central repository deployments of Android SDK.
  • 25. Byte Buddy cglib Javassist Java proxy (1) 60.995 234.488 145.412 68.706 (2a) 153.800 804.000 706.878 973.650 (2b) 0.001 0.002 0.009 0.005 (3a) 172.126 1’850.567 1’480.525 625.778 n/a (3b) 0.002 0.003 0.019 0.027 n/a All benchmarks run with JMH, source code: https://github.com/raphw/byte-buddy (1) Extending the Object class without any methods but with a default constructor (2a) Implementing an interface with 18 methods, method stubs (2b) Executing a method of this interface (3a) Extending a class with 18 methods, super method invocation (3b) Executing a method of this class