SlideShare une entreprise Scribd logo
1  sur  63
Télécharger pour lire hors ligne
Having fun with
Javassist
JEEConf 2017
@antonarhipov
whoami
Anton Arhipov
@antonarhipov
Javassist inside!
@Entity

@Table(name = "owners")

public class Owner extends Person {

@Column(name = "address")

@NotEmpty

private String address;



@Column(name = "city")

@NotEmpty

private String city;



@Column(name = "telephone")

@NotEmpty

@Digits(fraction = 0, integer = 10)

private String telephone;



@OneToMany(cascade = CascadeType.ALL,
mappedBy = "owner")

private Set<Pet> pets;
public class JavassistLazyInitializer
extends BasicLazyInitializer
implements MethodHandler {
final JavassistLazyInitializer instance
= new JavassistLazyInitializer(…);


ProxyFactory factory = new ProxyFactory();

factory.setSuperclass(interfaces.length == 1?persistentClass:null);

factory.setInterfaces(interfaces);

factory.setFilter(FINALIZE_FILTER);


Class cl = factory.createClass();

final HibernateProxy proxy = (HibernateProxy) cl.newInstance();

((ProxyObject)proxy).setHandler(instance);

instance.constructed = true;

return proxy;
public class JavassistLazyInitializer
extends BasicLazyInitializer
implements MethodHandler {
final JavassistLazyInitializer instance
= new JavassistLazyInitializer(…);


ProxyFactory factory = new ProxyFactory();

factory.setSuperclass(interfaces.length == 1?persistentClass:null);

factory.setInterfaces(interfaces);

factory.setFilter(FINALIZE_FILTER);


Class cl = factory.createClass();

final HibernateProxy proxy = (HibernateProxy) cl.newInstance();

((ProxyObject)proxy).setHandler(instance);

instance.constructed = true;

return proxy;
The main use case for
bytecode generation
in Java frameworks
is to generate proxies
Why?
Programming model (AOP, ORM, итд)
Monitoring agent (NewRelic, XRebel)
Specialized debuggers
Developer tools (JRebel)
Obfuscation (Proguard)
Javassist 101
www.javassist.org
API
ClassPool
CtClass
CtClass
CtClass
CtClass
CtField
CtMethod
CtConst
CtMethod
insertBefore
insertAfter
instrument
https://speakerdeck.com/antonarhipov
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
ClassPool cp = new ClassPool(null);
cp.appendSystemPath();
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
public class A extends Clazz { 

public A() {

}

}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
mars:output anton$ javap -c com/zt/A.class
public class com.zt.A extends com.zt.Clazz {
public com.zt.A();
Code:
0: aload_0
1: invokespecial #10
4: return
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass("com.zt.A",
cp.get("com.zt.Clazz"));
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
Can generate classes from
metadata at build time
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
cp.appendClassPath(new ClassPath(){ … });
CtClass ct = cp.get("com.zt.A");
CtMethod[] methods = ct.getMethods();

for (CtMethod method : methods) {

//…
}
ct.writeFile("/output");
}
… or you can post process the
compiled classes
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"()V");
foo.insertBefore("System.out.println();");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"()V");
foo.insertBefore("System.out.println();");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"()V");
foo.insertBefore("System.out.println();");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
public void foo() { 

}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"(Ljava/lang/String;)V");
foo.insertBefore("System.out.println();");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
public void foo(String s) { 

}
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lja
foo.insertBefore("System.out.println();");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
Descriptors might get quite long ;)
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"(Ljava/lang/String;)V");
foo.insertBefore("System.out.println($1)");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
$1, $2, $3 — local variables
$0 — this for non-static methods
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"(Ljava/lang/String;)V");
foo.insertBefore("System.out.println($1)");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
Exception in thread "main" javassist.CannotCompileException: [source error] ; is missing
at javassist.CtBehavior.insertBefore(CtBehavior.java:774)
at javassist.CtBehavior.insertBefore(CtBehavior.java:734)
at com.zt.basics.Ex.main(Ex.java:35)
public static void main(String[] args) throws Exception {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("com.zt.A");
CtMethod foo = ctClass.getMethod("foo",
"(Ljava/lang/String;)V");
foo.insertBefore("System.out.println($1);");
Class c = ctClass.toClass();

A a = (A) c.newInstance();

a.foo("Hello");

}
CtMethod foo = …
foo.insertBefore(…);
foo.insertAfter(…);
Can implement tracing
… or add logging
CtMethod foo = …
foo.insertBefore(…);
foo.insertAfter(…);
… or implement AOP
CtMethod foo = …
foo.insertBefore(…);
foo.insertAfter(…);
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(NewExpr e)
throws CannotCompileException {

e.replace("{" +

"$_ = $proceed($$);" +

"System.out.println($_);" +

"}");

}
});
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(NewExpr e)
throws CannotCompileException {

e.replace("{" +

"$_ = $proceed($$);" +

"System.out.println($_);" +

"}");

}
});
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(NewExpr e)
throws CannotCompileException {

e.replace("{" +

"$_ = $proceed($$);" +

"System.out.println($_);" +

"}");

}
}); Intercept new instances
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(NewExpr e)
throws CannotCompileException {

e.replace("{" +

"$_ = $proceed($$);" +

"System.out.println($_);" +

"}");

}
}); Intercept new instances
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(MethodCall m)
throws CannotCompileException {

if(m.getMethodName().contains("println")) {

m.replace("{}");

}
}
}); Remove unwanted
invocations
CtMethod foo = …
foo.instrument(new ExprEditor() {
@Override

public void edit(FieldAccess f)
throws CannotCompileException {

if (f.isWriter()) {

CtField field = f.getField();

String setterName = findSetter(field);

f.replace("{" + "$0." + setterName + "($$);" + "}");

}
}
});
Replace direct field access
with setter calls
java.lang.ClassFormatError: LVTT entry
for 'callbackTypes' in class file
com/google/inject/internal/ProxyFactory
does not match any LVT entry
This slide is intentionally left blank
Java agents
Java Agent
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
public class Agent {
public static void premain(String args, Instrumentation inst)
throws Exception {
inst.addTransformer(new ClassFileTransformer {
// here be code
});
}
}
META-INF/MANIFEST.MF
Premain-Class: Agent
$> java –javaagent:agent.jar application.Main
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass(new
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}
}
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass(new
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}
}
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass(new
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}
}
ClassFileTransformer
new ClassFileTransformer() {
public byte[] transform(ClassLoader loader,
String className,
Class<?> classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer){
ClassPool cp = ClassPool.getDefault();
CtClass ct = cp.makeClass(new
ByteArrayInputStream(classfileBuffer));
// here we can do all the things to ‘ct’
return ct.toBytecode();
}
}
ClassFileTransformer
https://github.com/zeroturnaround/callspy
Javassist in
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
pluginjrebel.jar
Reloads
classes
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
Notifies
plugins
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
Refresh
configurations
Javassist lives here
Spring
plugin
Hibernate
plugin
EJB
plugin
JRebel
core
Spring
Hibernate
OpenEJB
JRebel
core
Spring
plugin
Hibernate
plugin
EJB
plugin
class Framework {
public void configure(){
//…

}
}
CtClass framework
= cp.get("com.zt.Framework");
framework.addInterface(
cp.get("com.zt.jrebel.Listener"));
class Framework
implements Listener {
public void configure(){

}
}
framework.addMethod(
CtNewMethod.make(
"public void onEvent(){" +
" configure();" +
"}",
framework
));
https://github.com/antonarhipov/jpoint
HowItWorks
This slide is intentionally left blank
Your task
Javassist
https://speakerdeck.com/antonarhipov
http://www.slideshare.net/arhan
@antonarhipov
anton@zeroturnaround.com

Contenu connexe

Tendances

Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidJordi Gerona
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner codeMite Mitreski
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languagesRafael Winterhalter
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리욱래 김
 
Clean code with google guava jee conf
Clean code with google guava jee confClean code with google guava jee conf
Clean code with google guava jee confIgor Anishchenko
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...julien.ponge
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overviewSteve Min
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]Baruch Sadogursky
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниStfalcon Meetups
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to missAndres Almiray
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 

Tendances (20)

Google guava
Google guavaGoogle guava
Google guava
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Java Concurrency by Example
Java Concurrency by ExampleJava Concurrency by Example
Java Concurrency by Example
 
Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리
 
Clean code with google guava jee conf
Clean code with google guava jee confClean code with google guava jee conf
Clean code with google guava jee conf
 
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
Java 7 Launch Event at LyonJUG, Lyon France. Fork / Join framework and Projec...
 
Java 7 LavaJUG
Java 7 LavaJUGJava 7 LavaJUG
Java 7 LavaJUG
 
Google guava overview
Google guava overviewGoogle guava overview
Google guava overview
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Java 8 Puzzlers [as presented at OSCON 2016]
Java 8 Puzzlers [as presented at  OSCON 2016]Java 8 Puzzlers [as presented at  OSCON 2016]
Java 8 Puzzlers [as presented at OSCON 2016]
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Sailing with Java 8 Streams
Sailing with Java 8 StreamsSailing with Java 8 Streams
Sailing with Java 8 Streams
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
Java libraries you can't afford to miss
Java libraries you can't afford to missJava libraries you can't afford to miss
Java libraries you can't afford to miss
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 

Similaire à JEEConf 2017 - Having fun with Javassist

Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Anton Arhipov
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet KotlinJieyi Wu
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agentsRafael Winterhalter
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Java Generics
Java GenericsJava Generics
Java Genericsjeslie
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
New features and enhancement
New features and enhancementNew features and enhancement
New features and enhancementRakesh Madugula
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVMRafael Winterhalter
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfarjuncorner565
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116Paulo Morgado
 
Java Questions
Java QuestionsJava Questions
Java Questionsbindur87
 

Similaire à JEEConf 2017 - Having fun with Javassist (20)

Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012Binary patching for fun and profit @ JUG.ru, 25.02.2012
Binary patching for fun and profit @ JUG.ru, 25.02.2012
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet Kotlin
 
The definitive guide to java agents
The definitive guide to java agentsThe definitive guide to java agents
The definitive guide to java agents
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Java Generics
Java GenericsJava Generics
Java Generics
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
New features and enhancement
New features and enhancementNew features and enhancement
New features and enhancement
 
A topology of memory leaks on the JVM
A topology of memory leaks on the JVMA topology of memory leaks on the JVM
A topology of memory leaks on the JVM
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
H base programming
H base programmingH base programming
H base programming
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
What is new in Java 8
What is new in Java 8What is new in Java 8
What is new in Java 8
 
JDK 8
JDK 8JDK 8
JDK 8
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Java Questions
Java QuestionsJava Questions
Java Questions
 

Plus de Anton Arhipov

JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfAnton Arhipov
 
TechTrain 2019 - (Не)адекватное техническое интервью
TechTrain 2019 - (Не)адекватное техническое интервьюTechTrain 2019 - (Не)адекватное техническое интервью
TechTrain 2019 - (Не)адекватное техническое интервьюAnton Arhipov
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCityAnton Arhipov
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCityAnton Arhipov
 
Devoxx Ukraine 2018 - Kotlin DSL in under an hour
Devoxx Ukraine 2018 - Kotlin DSL in under an hourDevoxx Ukraine 2018 - Kotlin DSL in under an hour
Devoxx Ukraine 2018 - Kotlin DSL in under an hourAnton Arhipov
 
GeeCON Prague 2018 - Kotlin DSL in under an hour
GeeCON Prague 2018 - Kotlin DSL in under an hourGeeCON Prague 2018 - Kotlin DSL in under an hour
GeeCON Prague 2018 - Kotlin DSL in under an hourAnton Arhipov
 
Build pipelines with TeamCity and Kotlin DSL
Build pipelines with TeamCity and Kotlin DSLBuild pipelines with TeamCity and Kotlin DSL
Build pipelines with TeamCity and Kotlin DSLAnton Arhipov
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCityAnton Arhipov
 
JavaDay Kiev 2017 - Integration testing with TestContainers
JavaDay Kiev 2017 - Integration testing with TestContainersJavaDay Kiev 2017 - Integration testing with TestContainers
JavaDay Kiev 2017 - Integration testing with TestContainersAnton Arhipov
 
GeeCON Prague 2017 - TestContainers
GeeCON Prague 2017 - TestContainersGeeCON Prague 2017 - TestContainers
GeeCON Prague 2017 - TestContainersAnton Arhipov
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
JavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassleJavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassleAnton Arhipov
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingAnton Arhipov
 
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingJavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingAnton Arhipov
 
JUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationJUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationAnton Arhipov
 
Devclub 01/2017 - (Не)адекватное Java-интервью
Devclub 01/2017 - (Не)адекватное Java-интервьюDevclub 01/2017 - (Не)адекватное Java-интервью
Devclub 01/2017 - (Не)адекватное Java-интервьюAnton Arhipov
 
Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Anton Arhipov
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
JPoint 2016 - Bytecode
JPoint 2016 - BytecodeJPoint 2016 - Bytecode
JPoint 2016 - BytecodeAnton Arhipov
 

Plus de Anton Arhipov (20)

JavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdfJavaZone 2022 - Building Kotlin DSL.pdf
JavaZone 2022 - Building Kotlin DSL.pdf
 
Idiomatic kotlin
Idiomatic kotlinIdiomatic kotlin
Idiomatic kotlin
 
TechTrain 2019 - (Не)адекватное техническое интервью
TechTrain 2019 - (Не)адекватное техническое интервьюTechTrain 2019 - (Не)адекватное техническое интервью
TechTrain 2019 - (Не)адекватное техническое интервью
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCity
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCity
 
Devoxx Ukraine 2018 - Kotlin DSL in under an hour
Devoxx Ukraine 2018 - Kotlin DSL in under an hourDevoxx Ukraine 2018 - Kotlin DSL in under an hour
Devoxx Ukraine 2018 - Kotlin DSL in under an hour
 
GeeCON Prague 2018 - Kotlin DSL in under an hour
GeeCON Prague 2018 - Kotlin DSL in under an hourGeeCON Prague 2018 - Kotlin DSL in under an hour
GeeCON Prague 2018 - Kotlin DSL in under an hour
 
Build pipelines with TeamCity and Kotlin DSL
Build pipelines with TeamCity and Kotlin DSLBuild pipelines with TeamCity and Kotlin DSL
Build pipelines with TeamCity and Kotlin DSL
 
Build pipelines with TeamCity
Build pipelines with TeamCityBuild pipelines with TeamCity
Build pipelines with TeamCity
 
JavaDay Kiev 2017 - Integration testing with TestContainers
JavaDay Kiev 2017 - Integration testing with TestContainersJavaDay Kiev 2017 - Integration testing with TestContainers
JavaDay Kiev 2017 - Integration testing with TestContainers
 
GeeCON Prague 2017 - TestContainers
GeeCON Prague 2017 - TestContainersGeeCON Prague 2017 - TestContainers
GeeCON Prague 2017 - TestContainers
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
 
JavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassleJavaOne 2017 - TestContainers: integration testing without the hassle
JavaOne 2017 - TestContainers: integration testing without the hassle
 
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloadingJavaOne 2017 - The hitchhiker’s guide to Java class reloading
JavaOne 2017 - The hitchhiker’s guide to Java class reloading
 
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloadingJavaZone 2017 - The Hitchhiker’s guide to Java class reloading
JavaZone 2017 - The Hitchhiker’s guide to Java class reloading
 
JUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentationJUG.ua 20170225 - Java bytecode instrumentation
JUG.ua 20170225 - Java bytecode instrumentation
 
Devclub 01/2017 - (Не)адекватное Java-интервью
Devclub 01/2017 - (Не)адекватное Java-интервьюDevclub 01/2017 - (Не)адекватное Java-интервью
Devclub 01/2017 - (Не)адекватное Java-интервью
 
Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
JPoint 2016 - Bytecode
JPoint 2016 - BytecodeJPoint 2016 - Bytecode
JPoint 2016 - Bytecode
 

Dernier

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 

Dernier (20)

Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 

JEEConf 2017 - Having fun with Javassist

  • 3.
  • 4. @Entity
 @Table(name = "owners")
 public class Owner extends Person {
 @Column(name = "address")
 @NotEmpty
 private String address;
 
 @Column(name = "city")
 @NotEmpty
 private String city;
 
 @Column(name = "telephone")
 @NotEmpty
 @Digits(fraction = 0, integer = 10)
 private String telephone;
 
 @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
 private Set<Pet> pets;
  • 5. public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler { final JavassistLazyInitializer instance = new JavassistLazyInitializer(…); 
 ProxyFactory factory = new ProxyFactory();
 factory.setSuperclass(interfaces.length == 1?persistentClass:null);
 factory.setInterfaces(interfaces);
 factory.setFilter(FINALIZE_FILTER); 
 Class cl = factory.createClass();
 final HibernateProxy proxy = (HibernateProxy) cl.newInstance();
 ((ProxyObject)proxy).setHandler(instance);
 instance.constructed = true;
 return proxy;
  • 6. public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler { final JavassistLazyInitializer instance = new JavassistLazyInitializer(…); 
 ProxyFactory factory = new ProxyFactory();
 factory.setSuperclass(interfaces.length == 1?persistentClass:null);
 factory.setInterfaces(interfaces);
 factory.setFilter(FINALIZE_FILTER); 
 Class cl = factory.createClass();
 final HibernateProxy proxy = (HibernateProxy) cl.newInstance();
 ((ProxyObject)proxy).setHandler(instance);
 instance.constructed = true;
 return proxy;
  • 7. The main use case for bytecode generation in Java frameworks is to generate proxies
  • 8.
  • 9. Why? Programming model (AOP, ORM, итд) Monitoring agent (NewRelic, XRebel) Specialized debuggers Developer tools (JRebel) Obfuscation (Proguard)
  • 13. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); }
  • 14. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); } ClassPool cp = new ClassPool(null); cp.appendSystemPath();
  • 15. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); } public class A extends Clazz { 
 public A() {
 }
 }
  • 16. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); }
  • 17. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); } mars:output anton$ javap -c com/zt/A.class public class com.zt.A extends com.zt.Clazz { public com.zt.A(); Code: 0: aload_0 1: invokespecial #10 4: return
  • 18. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass("com.zt.A", cp.get("com.zt.Clazz")); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); } Can generate classes from metadata at build time
  • 19. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); cp.appendClassPath(new ClassPath(){ … }); CtClass ct = cp.get("com.zt.A"); CtMethod[] methods = ct.getMethods();
 for (CtMethod method : methods) {
 //… } ct.writeFile("/output"); } … or you can post process the compiled classes
  • 20. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "()V"); foo.insertBefore("System.out.println();"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 }
  • 21. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "()V"); foo.insertBefore("System.out.println();"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 }
  • 22. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "()V"); foo.insertBefore("System.out.println();"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 } public void foo() { 
 }
  • 23. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "(Ljava/lang/String;)V"); foo.insertBefore("System.out.println();"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 } public void foo(String s) { 
 }
  • 24. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lja foo.insertBefore("System.out.println();"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 } Descriptors might get quite long ;)
  • 25. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "(Ljava/lang/String;)V"); foo.insertBefore("System.out.println($1)"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 } $1, $2, $3 — local variables $0 — this for non-static methods
  • 26. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "(Ljava/lang/String;)V"); foo.insertBefore("System.out.println($1)"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 } Exception in thread "main" javassist.CannotCompileException: [source error] ; is missing at javassist.CtBehavior.insertBefore(CtBehavior.java:774) at javassist.CtBehavior.insertBefore(CtBehavior.java:734) at com.zt.basics.Ex.main(Ex.java:35)
  • 27. public static void main(String[] args) throws Exception { ClassPool cp = ClassPool.getDefault(); CtClass ctClass = cp.get("com.zt.A"); CtMethod foo = ctClass.getMethod("foo", "(Ljava/lang/String;)V"); foo.insertBefore("System.out.println($1);"); Class c = ctClass.toClass();
 A a = (A) c.newInstance();
 a.foo("Hello");
 }
  • 28. CtMethod foo = … foo.insertBefore(…); foo.insertAfter(…); Can implement tracing
  • 29. … or add logging CtMethod foo = … foo.insertBefore(…); foo.insertAfter(…);
  • 30. … or implement AOP CtMethod foo = … foo.insertBefore(…); foo.insertAfter(…);
  • 31. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(NewExpr e) throws CannotCompileException {
 e.replace("{" +
 "$_ = $proceed($$);" +
 "System.out.println($_);" +
 "}");
 } });
  • 32. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(NewExpr e) throws CannotCompileException {
 e.replace("{" +
 "$_ = $proceed($$);" +
 "System.out.println($_);" +
 "}");
 } });
  • 33. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(NewExpr e) throws CannotCompileException {
 e.replace("{" +
 "$_ = $proceed($$);" +
 "System.out.println($_);" +
 "}");
 } }); Intercept new instances
  • 34. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(NewExpr e) throws CannotCompileException {
 e.replace("{" +
 "$_ = $proceed($$);" +
 "System.out.println($_);" +
 "}");
 } }); Intercept new instances
  • 35. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(MethodCall m) throws CannotCompileException {
 if(m.getMethodName().contains("println")) {
 m.replace("{}");
 } } }); Remove unwanted invocations
  • 36. CtMethod foo = … foo.instrument(new ExprEditor() { @Override
 public void edit(FieldAccess f) throws CannotCompileException {
 if (f.isWriter()) {
 CtField field = f.getField();
 String setterName = findSetter(field);
 f.replace("{" + "$0." + setterName + "($$);" + "}");
 } } }); Replace direct field access with setter calls
  • 37. java.lang.ClassFormatError: LVTT entry for 'callbackTypes' in class file com/google/inject/internal/ProxyFactory does not match any LVT entry
  • 38. This slide is intentionally left blank
  • 40. Java Agent import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.Instrumentation; public class Agent { public static void premain(String args, Instrumentation inst) throws Exception { inst.addTransformer(new ClassFileTransformer { // here be code }); } } META-INF/MANIFEST.MF Premain-Class: Agent $> java –javaagent:agent.jar application.Main
  • 41. ClassFileTransformer new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); } }
  • 42. new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); } } ClassFileTransformer
  • 43. new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); } } ClassFileTransformer
  • 44. new ClassFileTransformer() { public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer){ ClassPool cp = ClassPool.getDefault(); CtClass ct = cp.makeClass(new ByteArrayInputStream(classfileBuffer)); // here we can do all the things to ‘ct’ return ct.toBytecode(); } } ClassFileTransformer
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 59. class Framework { public void configure(){ //…
 } } CtClass framework = cp.get("com.zt.Framework"); framework.addInterface( cp.get("com.zt.jrebel.Listener")); class Framework implements Listener { public void configure(){
 } } framework.addMethod( CtNewMethod.make( "public void onEvent(){" + " configure();" + "}", framework ));
  • 61. This slide is intentionally left blank