living in the matrix with bytecode manipulation (new relic)
DESCRIPTION
Speaker: Ashley Puls Applied Spring Track With Spring and Hibernate on your stack, your application's bytecode is likely enhanced or manipulated at runtime. This session examines three common byte code manipulation frameworks: ASM, CGLib, and Javassist (Java Programming Assistant). We will discuss how these tools work and why frameworks like Spring use them. You will learn enough to begin integrating these frameworks directly into your own code.TRANSCRIPT
![Page 1: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/1.jpg)
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.
Living in the Matrix with Bytecode Manipulation
Ashley Puls
Wednesday, September 10, 14
![Page 2: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/2.jpg)
2
Ashley PulsSenior Software Engineer
New Relic, Inc.
Wednesday, September 10, 14
![Page 3: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/3.jpg)
Outline
• What is bytecode• Why manipulate bytecode• In depth examination of 2 bytecode
manipulation frameworks• Applications• Lessons Learned
3
Wednesday, September 10, 14
![Page 4: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/4.jpg)
4Source: http://www.techlila.com/write-programs-linux/
What is Java bytecode?
Wednesday, September 10, 14
![Page 5: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/5.jpg)
5Source: http://www.techlila.com/write-programs-linux/
What is Java bytecode?
Wednesday, September 10, 14
![Page 6: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/6.jpg)
6
What is Java bytecode?
Wednesday, September 10, 14
![Page 7: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/7.jpg)
7Source: http://www.techlila.com/write-programs-linux/
What is Java bytecode?
Wednesday, September 10, 14
![Page 8: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/8.jpg)
8Source: http://www.techlila.com/write-programs-linux/
What is Java bytecode?
Wednesday, September 10, 14
![Page 9: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/9.jpg)
9
javac -verbose src/com/example/spring2gx/BankTransactions.java
What is Java bytecode?
Wednesday, September 10, 14
![Page 10: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/10.jpg)
10
javac -verbose src/com/example/spring2gx/BankTransactions.java
What is Java bytecode?
Wednesday, September 10, 14
![Page 11: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/11.jpg)
11
javac -verbose src/com/example/spring2gx/BankTransactions.java
What is Java bytecode?
Wednesday, September 10, 14
![Page 12: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/12.jpg)
12
What is Java bytecode?
javac -verbose src/com/example/spring2gx/BankTransactions.java
Wednesday, September 10, 14
![Page 13: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/13.jpg)
13
What is Java bytecode?
Wednesday, September 10, 14
![Page 14: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/14.jpg)
14
What is Java bytecode?
Wednesday, September 10, 14
![Page 15: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/15.jpg)
15
What is Java bytecode?
Source: http://www.techlila.com/write-programs-linux/Wednesday, September 10, 14
![Page 16: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/16.jpg)
16
What is Java bytecode?
Source: http://www.techlila.com/write-programs-linux/Wednesday, September 10, 14
![Page 17: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/17.jpg)
17
What is Java bytecode?
Source: http://www.techlila.com/write-programs-linux/
Instruction set of the Java Virtual Machine
Wednesday, September 10, 14
![Page 18: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/18.jpg)
18
What is Java bytecode?
Source: http://www.techlila.com/write-programs-linux/
Instruction set of the Java Virtual Machine
Wednesday, September 10, 14
![Page 19: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/19.jpg)
19
What is Java bytecode?
Source: http://www.techlila.com/write-programs-linux/
Instruction set of the Java Virtual Machine
Wednesday, September 10, 14
![Page 20: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/20.jpg)
Why learn about bytecode manipulation?
20
Wednesday, September 10, 14
![Page 21: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/21.jpg)
Why learn about bytecode manipulation?
21
• A bytecode manipulation framework is likely on your stack
• Spring• Hibernate
• Groovy• Clojure
• Eclipse• JRuby
Wednesday, September 10, 14
![Page 22: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/22.jpg)
• Spring• Hibernate
• A bytecode manipulation framework is likely on your stack
• It is really fun!
Why learn about bytecode manipulation?
22
• Groovy• Clojure
• Eclipse• JRuby
Wednesday, September 10, 14
![Page 23: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/23.jpg)
• Spring• Hibernate
• A bytecode manipulation framework is likely on your stack
• It is really fun!
• Many applications. Can become a valuable tool.
Why learn about bytecode manipulation?
23
• Groovy• Clojure
• Eclipse• JRuby
Wednesday, September 10, 14
![Page 24: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/24.jpg)
Why manipulate bytecode?
24
Wednesday, September 10, 14
![Page 25: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/25.jpg)
Why manipulate bytecode?
25
• Program analysis • find bugs in code• examine code complexity
Wednesday, September 10, 14
![Page 26: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/26.jpg)
Why manipulate bytecode?
26
• Program analysis • find bugs in code• examine code complexity
• Class generation• proxies• remove access to certain APIs• compiler for another language like Scala
Wednesday, September 10, 14
![Page 27: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/27.jpg)
Why manipulate bytecode?
27
• Program analysis • find bugs in code• examine code complexity
• Class generation• proxies• remove access to certain APIs• compiler for another language like Scala
• Transform classes without Java source code• profilers• optimization and obfuscation• additional logging
Wednesday, September 10, 14
![Page 28: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/28.jpg)
Why manipulate bytecode?
28
• Program analysis • find bugs in code• examine code complexity
• Class generation• proxies• remove access to certain APIs• compiler for another language like Scala
• Transform classes without Java source code• profilers• optimization and obfuscation• additional logging
Wednesday, September 10, 14
![Page 29: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/29.jpg)
Logging
29Source: http://www.vforteachers.com/About_NetSupport.htm
Wednesday, September 10, 14
![Page 30: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/30.jpg)
Logging
30Source: http://www.vforteachers.com/About_NetSupport.htm, http://inzolo.com/blog/tutorials/bank-accounts
Wednesday, September 10, 14
![Page 31: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/31.jpg)
Logging
31Source: http://www.vforteachers.com/About_NetSupport.htm, http://upload.wikimedia.org/wikipedia/commons/d/d3/49024-SOS-ATM.JPG
Wednesday, September 10, 14
![Page 32: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/32.jpg)
Logging
32Source: http://www.vforteachers.com/About_NetSupport.htm
A message should be logged every time an important action occurs
Wednesday, September 10, 14
![Page 33: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/33.jpg)
Logging
33Source: http://www.vforteachers.com/About_NetSupport.htm
A message should be logged every time an important action occurs
Log important values to identify the action
Wednesday, September 10, 14
![Page 34: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/34.jpg)
34
public class BankTransactions {
public static void main(String[] args) { BankTransactions bank = new BankTransactions(); // login and withdraw i dollars from account for (int i = 0; i < 100; i++) { String accountId = "account" + i; bank.login("password", accountId, "Ashley");
bank.unimportantProcessing(accountId); bank.withdraw(accountId, Double.valueOf(i)); } System.out.println(“Transactions completed”); }
}
Wednesday, September 10, 14
![Page 35: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/35.jpg)
35
public class BankTransactions {
public static void main(String[] args) { BankTransactions bank = new BankTransactions(); // login and withdraw i dollars from account for (int i = 0; i < 100; i++) { String accountId = "account" + i; bank.login("password", accountId, "Ashley");
bank.unimportantProcessing(accountId); bank.withdraw(accountId, Double.valueOf(i)); } System.out.println(“Transactions completed”); }
}
Wednesday, September 10, 14
![Page 36: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/36.jpg)
36
/** * A method annotation which should be used to indicate important methods whose * invocations should be logged. * */public @interface ImportantLog {
/** * The method parameter indexes whose values should be logged. For example, * if we have the method hello(int paramA, int paramB, int paramC), and we * wanted to log the values of paramA and paramC, then fields would be ["0", * "2"]. If we only want to log the value of paramB, then fields would be * ["1"]. */ String[] fields();}
Wednesday, September 10, 14
![Page 37: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/37.jpg)
37
public void login(String password, String accountId, String userName) { // login logic }
public void withdraw(String accountId, Double moneyToRemove) { // transaction logic }
Wednesday, September 10, 14
![Page 38: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/38.jpg)
38
@ImportantLog(fields = { "1", "2" }) public void login(String password, String accountId, String userName) { // login logic }
@ImportantLog(fields = { "0", "1" }) public void withdraw(String accountId, Double moneyToRemove) { // transaction logic }
Wednesday, September 10, 14
![Page 39: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/39.jpg)
39
@ImportantLog(fields = { "1", "2" }) public void login(String password, String accountId, String userName) { // login logic }
@ImportantLog(fields = { "0", "1" }) public void withdraw(String accountId, Double moneyToRemove) { // transaction logic }
A call was made to "login" on "com/example/spring2gx/BankTransactions" Important params: Index 1 value: ${accountId} Index 2 value: ${userName}
Wednesday, September 10, 14
![Page 40: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/40.jpg)
40
@ImportantLog(fields = { "1", "2" }) public void login(String password, String accountId, String userName) { // login logic }
@ImportantLog(fields = { "0", "1" }) public void withdraw(String accountId, Double moneyToRemove) { // transaction logic }
A call was made to "login" on "com/example/spring2gx/BankTransactions" Important params: Index 1 value: ${accountId} Index 2 value: ${userName}
A call was made to "withdraw" on "com/example/spring2gx/BankTransactions" Important params: Index 0 value: ${accountId} Index 1 value: ${moneyToAdd} Wednesday, September 10, 14
![Page 41: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/41.jpg)
Java Agent
41
• Ability to modify bytecode without modifying or accessing the application’s source code
• Feature added in Java 1.5• Docs: http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html
Wednesday, September 10, 14
![Page 42: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/42.jpg)
Typical Java process
42
JVM
Wednesday, September 10, 14
![Page 43: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/43.jpg)
Typical Java process
43
java com/example/spring2gx/BankTransactions
JVM
Wednesday, September 10, 14
![Page 44: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/44.jpg)
Typical Java process
44
java com/example/spring2gx/BankTransactions
ClassloaderJVM
Wednesday, September 10, 14
![Page 45: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/45.jpg)
Typical Java process
45
java com/example/spring2gx/BankTransactions
BankTransactions.class
public static void main(String[] args)
ClassloaderJVM
Wednesday, September 10, 14
![Page 46: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/46.jpg)
Typical Java process
46
java com/example/spring2gx/BankTransactions
Transactions completed
BankTransactions.class
public static void main(String[] args)
ClassloaderJVM
Wednesday, September 10, 14
![Page 47: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/47.jpg)
Process with Java agent
47
JVM
Wednesday, September 10, 14
![Page 48: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/48.jpg)
Process with Java agent
48
JVM
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
JVM
Wednesday, September 10, 14
![Page 49: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/49.jpg)
Process with Java agent
49
JVM
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
JVM
Wednesday, September 10, 14
![Page 50: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/50.jpg)
Process with Java agent
50
JVM
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
JVM Agent
void premain(String args, Instrumentation inst)
Agent.class1. call Agent premain in manifest
Wednesday, September 10, 14
![Page 51: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/51.jpg)
Process with Java agent
51
JVM
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
JVM Agent
void premain(String args, Instrumentation inst)
Agent.class
MyTransformer.class
byte[] transform( . .. , byte[] bankTransBytes)
1. call Agent premain in manifest
2. JVM registers my transformer
Wednesday, September 10, 14
![Page 52: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/52.jpg)
Process with Java agent
52
JVM JVM Agent
void premain(String args, Instrumentation inst)
Agent.class
MyTransformer.class
byte[] transform( . .. , byte[] bankTransBytes)
1. call Agent premain in manifest
2. JVM registers my transformer
3. Give BankTransactions bytes to MyTransformer
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
Wednesday, September 10, 14
![Page 53: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/53.jpg)
Process with Java agent
53
JVM JVM Agent
void premain(String args, Instrumentation inst)
Agent.class
MyTransformer.class
byte[] transform( . .. , byte[] bankTransBytes)
1. call Agent premain in manifest
2. JVM registers my transformer
3. Give BankTransactions bytes to MyTransformer
4. MyTransformer provides bytes to load
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
Wednesday, September 10, 14
![Page 54: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/54.jpg)
Process with Java agent
54
JVM JVM Agent
void premain(String args, Instrumentation inst)
Agent.class
MyTransformer.class
byte[] transform( . .. , byte[] bankTransBytes)
Transactions completed
BankTransactions.classpublic static void main(String[] args)
1. call Agent premain in manifest
2. JVM registers my transformer
3. Give BankTransactions bytes to MyTransformer
4. MyTransformer provides bytes to load
5. BankTransactions loaded and main runs
java -javaagent:/to/agent.jar com/example/spring2gx/BankTransactions
Wednesday, September 10, 14
![Page 55: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/55.jpg)
Code for Java agent
55
JVM
Wednesday, September 10, 14
![Page 56: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/56.jpg)
Code for Java agent
56
JVM
Manifest: Premain-Class: com.example.spring2gx.agent.Agent
Wednesday, September 10, 14
![Page 57: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/57.jpg)
Code for Java agent
57
JVM
package com.example.spring2gx.agent;
public class Agent {
public static void premain(String args, Instrumentation inst) { System.out.println("Starting the agent"); inst.addTransformer(new ImportantLogClassTransformer()); }}
Manifest: Premain-Class: com.example.spring2gx.agent.Agent
Wednesday, September 10, 14
![Page 58: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/58.jpg)
Code for Java agent
58
JVM
package com.example.spring2gx.agent;
public class Agent {
public static void premain(String args, Instrumentation inst) { System.out.println("Starting the agent"); inst.addTransformer(new ImportantLogClassTransformer()); }}
Manifest: Premain-Class: com.example.spring2gx.agent.Agent
Wednesday, September 10, 14
![Page 59: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/59.jpg)
Code for Java agent
59
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { //TODO return null; }}
Wednesday, September 10, 14
![Page 60: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/60.jpg)
Code for Java agent
60
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { //TODO return null; }}
Wednesday, September 10, 14
![Page 61: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/61.jpg)
Code for Java agent
61
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { //TODO return null; }}
Wednesday, September 10, 14
![Page 62: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/62.jpg)
Code for Java agent
62
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println(" Loading class: " + className); return null; }}
Wednesday, September 10, 14
![Page 63: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/63.jpg)
Code for Java agent
63
JVM
Starting the agent Loading class: java/lang/invoke/MethodHandleImpl Loading class: java/lang/invoke/MemberName$Factory Loading class: java/lang/invoke/LambdaForm$NamedFunction Loading class: java/lang/invoke/MethodType$ConcurrentWeakInternSet Loading class: java/lang/invoke/MethodHandleStatics Loading class: java/lang/invoke/MethodHandleStatics$1 Loading class: java/lang/invoke/MethodTypeForm Loading class: java/lang/invoke/Invokers Loading class: java/lang/invoke/MethodType$ConcurrentWeakInternSet$WeakEntry Loading class: java/lang/Void Loading class: java/lang/IllegalAccessException Loading class: sun/misc/PostVMInitHook Loading class: sun/launcher/LauncherHelper Loading class: java/util/concurrent/ConcurrentHashMap$ForwardingNode Loading class: sun/misc/URLClassPath$FileLoader$1 Loading class: com/example/spring2gx/mains/BankTransactions
Wednesday, September 10, 14
![Page 64: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/64.jpg)
Code for Java agent
64
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println(" Loading class: " + className); return null; }}
Wednesday, September 10, 14
![Page 65: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/65.jpg)
Code for Java agent
65
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { System.out.println(" Loading class: " + className); return null; }}
Wednesday, September 10, 14
![Page 66: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/66.jpg)
Code for Java agent
66
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // manipulate the bytes here return null; }}
Wednesday, September 10, 14
![Page 67: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/67.jpg)
Code for Java agent
67
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // manipulate the bytes here return modified bytes; }}
Wednesday, September 10, 14
![Page 68: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/68.jpg)
Bytecode Manipulation Frameworks
68
• ASM: http://asm.ow2.org/
• BCEL: http://commons.apache.org/proper/commons-bcel/
• CGLib: https://github.com/cglib/cglib
• Javassist: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
• Serp: http://serp.sourceforge.net/
• Cojen: https://github.com/cojen/Cojen/wiki
• AspectJ: http://www.eclipse.org/aspectj/
Wednesday, September 10, 14
![Page 69: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/69.jpg)
Bytecode Manipulation Frameworks• ASM: http://asm.ow2.org/
• BCEL: http://commons.apache.org/proper/commons-bcel/
• CGLib: https://github.com/cglib/cglib
• Javassist: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
• Serp: http://serp.sourceforge.net/
• Cojen: https://github.com/cojen/Cojen/wiki
• AspectJ: http://www.eclipse.org/aspectj/69
Wednesday, September 10, 14
![Page 70: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/70.jpg)
• Java Programming Assistant
• Subproject of JBoss
• Object based API
• Actively updated
• Version 3.18.2 released May 2014
• Source code: https://github.com/jboss-javassist/javassist
• Docs: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial.html
Javassist
70
Wednesday, September 10, 14
![Page 71: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/71.jpg)
Javassist
71
CtClass:compile time classCtClass Name
BankTransactions
Wednesday, September 10, 14
![Page 72: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/72.jpg)
Javassist
72
CtClass:compile time classCtClass Name
Bank TransactionsBankTransactions
Wednesday, September 10, 14
![Page 73: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/73.jpg)
Javassist
73
CtClass:compile time class
ClassPool: container of CtClass objects
Bank Transactions
Wednesday, September 10, 14
![Page 74: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/74.jpg)
Javassist
74
CtClass:compile time classClass Name
Bank Transactions
ClassPool: container of CtClass objects
Wednesday, September 10, 14
![Page 75: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/75.jpg)
Javassist
75
CtClass:compile time classClass Name
Bank TransactionsBankTransactions
ClassPool: container of CtClass objects
Wednesday, September 10, 14
![Page 76: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/76.jpg)
Javassist
76
Java Class: Bank Transactions
Wednesday, September 10, 14
![Page 77: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/77.jpg)
Java Class: Bank Transactions
Javassist
77
CtClass
Fields
Constructors
Methods
Wednesday, September 10, 14
![Page 78: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/78.jpg)
Java Class: Bank Transactions
Javassist
78
CtClass
Fields
Constructors
Methods
CtClass
Wednesday, September 10, 14
![Page 79: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/79.jpg)
Java Class: Bank Transactions
Javassist
79
CtClass
Fields
Constructors
Methods
CtClass
CtFields
CtConstructors
CtMethods
Wednesday, September 10, 14
![Page 80: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/80.jpg)
Javassist
80
CtClass
CtField
ClassPool
CtClass
CtClass
CtClass
CtConst
CtMethod
CtMethod
Wednesday, September 10, 14
![Page 81: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/81.jpg)
81
Javassist
CtMethod
Wednesday, September 10, 14
![Page 82: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/82.jpg)
82
Javassist
line 1 of code
line 2 of code
line 3 of code
line 4 of code
line 5of code
CtMethod
Wednesday, September 10, 14
![Page 83: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/83.jpg)
83
Javassist
line 1 of code
line 2 of code
line 3 of code
line 4 of code
line 5 of code
putMethod.insertBefore(“System.out.println(\“before method\”);”);
System.out.println(“before method”);
CtMethod
Wednesday, September 10, 14
![Page 84: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/84.jpg)
84
Javassist
line 2 of code
line 3 of code
line 4 of code
line 5 of code
System.out.println(“after method”);
line 1 of code
putMethod.insertAfter(“System.out.println(\”after method\”);”);
CtMethod
Wednesday, September 10, 14
![Page 85: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/85.jpg)
85
Javassist
line 2 of code
line 3 of code
line 4 of code
catch (IOException e) { Sys.out.prln( . . .
line 5 of code
line 1 of code
CtClass exceptionType = classpool.get(“java.io.IOException”);putMethod.addCatch(“{System.out.println($e); throw $e}”, exceptionType);
CtMethod
Wednesday, September 10, 14
![Page 86: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/86.jpg)
86
Javassist
line 2 of code
System.out.println(“middle method”);
line 3 of code
line 4 of code
line 5 of code
line 1 of code
putMethod.insertAt(3, true, “System.out.println(\“middle method\”);”);
CtMethod
Wednesday, September 10, 14
![Page 87: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/87.jpg)
Javassist
87
CtClass
CtField
ClassPool
CtClass
CtClass
CtClass
CtConst
CtMethod
CtMethod
insertBefore
insertAfter
catchEx
insertAt
Wednesday, September 10, 14
![Page 88: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/88.jpg)
88
JVM
package com.example.spring2gx.agent;
public class Agent {
public static void premain(String args, Instrumentation inst) { System.out.println("Starting the agent"); inst.addTransformer(new ImportantLogClassTransformer()); }
}
Wednesday, September 10, 14
![Page 89: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/89.jpg)
Code for Java agent
89
JVM package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // manipulate the bytes here return modified bytes; }}
Wednesday, September 10, 14
![Page 90: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/90.jpg)
90
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { 1. convert byte array to a ct class object 2. check each method of ct class for annotation @ImportantLog 3. if @ImportantLog annotation is present on method, then a. get important method parameter indexes
b. add logging statement to beginning of the method return null;}Wednesday, September 10, 14
![Page 91: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/91.jpg)
91
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); 2. check each method of ct class for annotation @ImportantLog 3. if @ImportantLog annotation present on method, then a. get important method parameter indexes
b. add logging statement to beginning of the method return null;}Wednesday, September 10, 14
![Page 92: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/92.jpg)
92
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); 3. if @ImportantLog annotation present on method, then a. get important method parameter indexes
b. add logging statement to beginning of the method } } } return null;}Wednesday, September 10, 14
![Page 93: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/93.jpg)
93
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation);
b. add logging statement to beginning of the method } } } return null;}Wednesday, September 10, 14
![Page 94: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/94.jpg)
94
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 95: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/95.jpg)
95
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 96: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/96.jpg)
96
private Annotation getAnnotation(CtMethod method) { MethodInfo mInfo = method.getMethodInfo(); // the attribute we are looking for is a runtime invisible attribute // use Retention(RetentionPolicy.RUNTIME) on the annotation to make it // visible at runtime AnnotationsAttribute attInfo = (AnnotationsAttribute) mInfo .getAttribute(AnnotationsAttribute.invisibleTag); if (attInfo != null) { // this is the type name meaning use dots instead of slashes return attInfo.getAnnotation("com.example.spring.mains.ImportantLog"); } return null; }
Wednesday, September 10, 14
![Page 97: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/97.jpg)
97
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 98: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/98.jpg)
98
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 99: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/99.jpg)
99
private List<String> getParamIndexes(Annotation annotation) { ArrayMemberValue fields = (ArrayMemberValue) annotation .getMemberValue(“fields”); if (fields != null) { MemberValue[] values = (MemberValue[]) fields.getValue(); List<String> parameterIndexes = new ArrayList<String>(); for (MemberValue val : values) { parameterIndexes.add(((StringMemberValue) val).getValue()); } return parameterIndexes; } return Collections.emptyList(); }
Wednesday, September 10, 14
![Page 100: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/100.jpg)
100
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 101: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/101.jpg)
101
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 102: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/102.jpg)
102
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 103: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/103.jpg)
103
private String createJavaString(CtMethod currentMethod, String className, List<String> indexParameters) { StringBuilder sb = new StringBuilder(); sb.append("{StringBuilder sb = new StringBuilder"); sb.append("(\"A call was made to method '\");"); sb.append("sb.append(\""); sb.append(currentMethod.getName()); sb.append("\");sb.append(\"' on class '\");"); sb.append("sb.append(\""); sb.append(className); sb.append("\");sb.append(\"'.\");"); sb.append("sb.append(\"\\n Important params:\");"); . . .
Wednesday, September 10, 14
![Page 104: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/104.jpg)
104
private String createJavaString(CtMethod currentMethod, String className, List<String> indexParameters) { StringBuilder sb = new StringBuilder(); sb.append("{StringBuilder sb = new StringBuilder"); sb.append("(\"A call was made to method '\");"); sb.append("sb.append(\""); sb.append(currentMethod.getName()); sb.append("\");sb.append(\"' on class '\");"); sb.append("sb.append(\""); sb.append(className); sb.append("\");sb.append(\"'.\");"); sb.append("sb.append(\"\\n Important params:\");"); . . .
Put multiple statements inside brackets {}
Wednesday, September 10, 14
![Page 105: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/105.jpg)
105
private String createJavaString(CtMethod currentMethod, String className, List<String> indexParameters) { . . . for (String index : indexParameters) { try { int localVar = Integer.parseInt(index) + 1; sb.append("sb.append(\"\\n Index: \");"); sb.append("sb.append(\""); sb.append(index); sb.append("\");sb.append(\" value: \");"); sb.append("sb.append($" + localVar + ");"); } catch (NumberFormatException e) { e.printStackTrace(); } } sb.append("System.out.println(sb.toString());}"); return sb.toString();}
Wednesday, September 10, 14
![Page 106: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/106.jpg)
106
private String createJavaString(CtMethod currentMethod, String className, List<String> indexParameters) { . . . for (String index : indexParameters) { try { int localVar = Integer.parseInt(index) + 1; sb.append("sb.append(\"\\n Index: \");"); sb.append("sb.append(\""); sb.append(index); sb.append("\");sb.append(\" value: \");"); sb.append("sb.append($" + localVar + ");"); } catch (NumberFormatException e) { e.printStackTrace(); } } sb.append("System.out.println(sb.toString());}"); return sb.toString();} $0, $1, $2, ... used to access “this” and method parametersWednesday, September 10, 14
![Page 107: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/107.jpg)
107
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] cfbuffer) throws IllegalClassFormatException { pool.insertClassPath(new ByteArrayClassPath(className,classfileBuffer)); CtClass cclass = pool.get(className.replaceAll("/", ".")); if (!cclass.isFrozen()) { for (CtMethod currentMethod : cclass.getDeclaredMethods()) { Annotation annotation = getAnnotation(currentMethod); if (annotation != null) { List<String> parameterIndexes = getParamIndexes(annotation); currentMethod.insertBefore(createJavaString( currentMethod, className, parameterIndexes)); } } return cclass.toBytecode(); } return null;}Wednesday, September 10, 14
![Page 108: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/108.jpg)
• Positives
• Simplicity
• Documentation
• Negatives
• Limited functionality
• Slow
108
Javassist
Wednesday, September 10, 14
![Page 109: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/109.jpg)
ASM
109
• Released in Open Source in 2002
• Actively updated
• Version 5.0.3 released May 2014
• Two ASM libraries
• Event based (SAX like)
• Object based (DOM like)
• Documentation: http://download.forge.objectweb.org/asm/asm4-guide.pdf
Wednesday, September 10, 14
![Page 110: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/110.jpg)
110
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 111: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/111.jpg)
111
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 112: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/112.jpg)
112
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 113: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/113.jpg)
113
ASM
ClassReader: event producer
ClassWriter: event consumer
ClassVisitor: event filter
BankTrans
Wednesday, September 10, 14
![Page 114: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/114.jpg)
ClassReader: given a byte[], parses a compiled class
114
ASM
ClassReader: event producer
ClassWriter: event consumer
ClassVisitor: event filter
BankTrans
Wednesday, September 10, 14
![Page 115: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/115.jpg)
ClassWriter: produces output byte[]
115
ASM
ClassReader: event producer
ClassWriter: event consumer
ClassVisitor: event filter
ClassWriter: event consumer
BankTrans
Wednesday, September 10, 14
![Page 116: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/116.jpg)
116
ASM
ClassReader: event producer
ClassWriter: event consumer
ClassVisitor: event filter
BankTrans
ClassWriter: event consumer
BankTrans
Wednesday, September 10, 14
![Page 117: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/117.jpg)
ClassVisitor: delegates class events, event filter
117
ASM
ClassReader: event producer
ClassWriter: event consumer
BankTrans
ClassVisitor: event filter
BankTrans
Wednesday, September 10, 14
![Page 118: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/118.jpg)
R:B:
118
ASM
ClassReader: event producer
ClassWriter: event consumer
BankTrans
ClassVisitor: event filter
visitField
visitMethod
BankTrans
ClassVisitor: delegates class events, event filter
Wednesday, September 10, 14
![Page 119: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/119.jpg)
119
ASM
package com.example.spring2gx.agent;
import java.lang.instrument.Instrumentation;
public class Agent {
public static void premain(String args, Instrumentation inst) { System.out.println("Starting the agent"); inst.addTransformer(new ImportantLogClassTransformer()); }
}
Wednesday, September 10, 14
![Page 120: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/120.jpg)
120
package com.example.spring2gx.agent;
public class ImportantLogClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // manipulate the bytes here return modified bytes; }}
ASM
Wednesday, September 10, 14
![Page 121: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/121.jpg)
121
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES);
cr.accept(cw, 0); return cw.toByteArray();
}
ASM
Wednesday, September 10, 14
![Page 122: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/122.jpg)
122
public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
ClassReader cr = new ClassReader(classfileBuffer); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = new LogMethodClassVisitor(cw, className); cr.accept(cv, 0); return cw.toByteArray();
}
ASM
Wednesday, September 10, 14
![Page 123: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/123.jpg)
R:B:
123
ASM
ClassReader: event producer
ClassWriter: event consumer
BankTrans
ClassVisitor: event filter
visitField
visitMethod
BankTrans
Wednesday, September 10, 14
![Page 124: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/124.jpg)
R:B:
124
ASM
ClassReader: event producer
ClassWriter: event consumer
BankTransvisitField
visitMethod
BankTrans
LogMethodClassVisitor:event filter
Wednesday, September 10, 14
![Page 125: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/125.jpg)
125
ASM
ClassReader: event producer
BankTrans
ClassWriter: event consumer
BankTrans
LogMethodClassVisitor:event filter
visitMethod
Wednesday, September 10, 14
![Page 126: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/126.jpg)
126
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 127: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/127.jpg)
127
ASMpublic class LogMethodClassVisitor extends ClassVisitor {
private String className;
public LogMethodIfAnnotationVisitor(ClassVisitor cv, String className) { super(Opcodes.ASM5, cv); this.className = className; }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // put our logic in here }}
Wednesday, September 10, 14
![Page 128: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/128.jpg)
128
ASMpublic class LogMethodClassVisitor extends ClassVisitor {
private String className;
public LogMethodIfAnnotationVisitor(ClassVisitor cv, String className) { super(Opcodes.ASM5, cv); this.className = className; }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // put our logic in here }}
Wednesday, September 10, 14
![Page 129: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/129.jpg)
129
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 130: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/130.jpg)
130
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 131: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/131.jpg)
131
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 132: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/132.jpg)
132
ASM
Method Visitor
visitAnnotation
Method Visitor
visitCode
visitEnd
Login Method Login Method
Wednesday, September 10, 14
![Page 133: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/133.jpg)
133
ASMpublic class LogMethodClassVisitor extends ClassVisitor { private String className;
public LogMethodIfAnnotationVisitor(ClassVisitor cv, String className) { super(Opcodes.ASM5, cv); this.className = className; }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // put our logic in here }}Wednesday, September 10, 14
![Page 134: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/134.jpg)
134
ASMpublic class LogMethodClassVisitor extends ClassVisitor { private String className;
public LogMethodIfAnnotationVisitor(ClassVisitor cv, String className) { super(Opcodes.ASM5, cv); this.className = className; }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); return new PrintMessageMethodVisitor(mv, name, className); }}Wednesday, September 10, 14
![Page 135: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/135.jpg)
135
ASM
Source: http://download.forge.objectweb.org/asm/asm4-guide.pdfWednesday, September 10, 14
![Page 136: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/136.jpg)
136
ASMpublic class PrintMessageMethodVisitor extends MethodVisitor {
@Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { }
@Override public void visitCode() { }
}
Wednesday, September 10, 14
![Page 137: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/137.jpg)
137
ASMpublic class PrintMessageMethodVisitor extends MethodVisitor {
@Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 1. check method for annotation @ImportantLog 2. if annotation present, then get important method param indexes }
@Override public void visitCode() { 3. if annotation present, add logging to beginning of the method }
}
Wednesday, September 10, 14
![Page 138: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/138.jpg)
138
ASM public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if ("Lcom/example/spring2gx/mains/ImportantLog;".equals(desc)) { isAnnotationPresent = true; return new AnnotationVisitor(Opcodes.ASM5, super.visitAnnotation(desc, visible)) { public AnnotationVisitor visitArray(String name) { if (“fields”.equals(name)) { return new AnnotationVisitor(Opcodes.ASM5, super.visitArray(name)) { public void visit(String name, Object value) { parameterIndexes.add((String) value); super.visit(name, value); } }; } else { return super.visitArray(name); } } }; } return super.visitAnnotation(desc, visible); }
Wednesday, September 10, 14
![Page 139: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/139.jpg)
139
ASMpublic class PrintMessageMethodVisitor extends MethodVisitor {
@Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 1. check method for annotation @ImportantLog 2. if annotation present, then get important method param indexes }
@Override public void visitCode() { 3. if annotation present, add logging to beginning of the method }
}
Wednesday, September 10, 14
![Page 140: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/140.jpg)
140
ASM public void visitCode() { if (isAnnotationPresent) { // create string builder mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); mv.visitInsn(Opcodes.DUP); // add everything to the string builder mv.visitLdcInsn("A call was made to method \""); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); mv.visitLdcInsn(methodName); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
. . .Wednesday, September 10, 14
![Page 141: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/141.jpg)
141
Javap
Wednesday, September 10, 14
![Page 142: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/142.jpg)
142
Javappublic class PrintMessage { private String methodName; private String className; public PrintMessage(String mName, String cName) { methodName = mName; className = cName; } public void print() { StringBuilder sb = new StringBuilder(); sb.append("A call was made to method \""); sb.append(methodName); sb.append("\" on class \""); sb.append(className); sb.append("\"."); System.out.println(sb.toString()); }
Wednesday, September 10, 14
![Page 143: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/143.jpg)
143
Javap
javap -c com/example/spring2gx/mains/PrintMessage
Wednesday, September 10, 14
![Page 144: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/144.jpg)
public void print(); Code: 0: new #38 // class java/lang/StringBuilder 3: dup 4: invokespecial #40 // Method java/lang/StringBuilder."<init>":()V 7: astore_1 8: aload_1 9: ldc #41 // String A call was made to method \" 11: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: pop 15: aload_1 16: aload_0 17: getfield #14 // Field methodName:Ljava/lang/String; 20: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;. . .
144
Javap
Wednesday, September 10, 14
![Page 145: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/145.jpg)
public void print(); Code: 0: new #38 // class java/lang/StringBuilder 3: dup 4: invokespecial #40 // Method java/lang/StringBuilder."<init>":()V 7: astore_1 8: aload_1 9: ldc #41 // String A call was made to method \" 11: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: pop 15: aload_1 16: aload_0 17: getfield #14 // Field methodName:Ljava/lang/String; 20: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;. . .
145
Javap
Wednesday, September 10, 14
![Page 146: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/146.jpg)
146
Wednesday, September 10, 14
![Page 147: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/147.jpg)
147
Wednesday, September 10, 14
![Page 148: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/148.jpg)
148
Javap
Wednesday, September 10, 14
![Page 149: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/149.jpg)
149
Javap
Wednesday, September 10, 14
![Page 150: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/150.jpg)
150
Javap
Wednesday, September 10, 14
![Page 151: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/151.jpg)
151
ASM public void visitCode() { if (isAnnotationPresent) { // create string builder mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); mv.visitInsn(Opcodes.DUP); // add everything to the string builder mv.visitLdcInsn("A call was made to method \""); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); mv.visitLdcInsn(methodName); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
. . .Wednesday, September 10, 14
![Page 152: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/152.jpg)
152
ASM• Positives
• Speed and Size
• Documentation
• Depth of functionality
• Number of people using the framework
• Negatives
• Developer ramp-up
• Writing byte code
Wednesday, September 10, 14
![Page 153: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/153.jpg)
153
Applications
Wednesday, September 10, 14
![Page 154: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/154.jpg)
154
Hibernate
Wednesday, September 10, 14
![Page 155: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/155.jpg)
155
Hibernate
LazyInitializationException
Wednesday, September 10, 14
![Page 156: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/156.jpg)
156
Hibernate
LazyInitializationException
Wednesday, September 10, 14
![Page 157: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/157.jpg)
157
Hibernate
9 instances of “throw new LazyInitializationException”
LazyInitializationException
Wednesday, September 10, 14
![Page 158: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/158.jpg)
158
Hibernate
Name Location Team
Joe Smith Dallas, TX Team 1
Jane Doe Portland, OR
Triathlon Club
Tim Doe San Fran, CA
Running Club
Sue Smith Austin, TX Red Lizards
Name Location Description
Team 1 Dallas, TX Casual runners
Triathlon Club
Beaverton, OR
Swim, bike, run
Running Club
Santa Clara, CA
For fun
Red Lizards Austin, TX Fast
Runner Team
Wednesday, September 10, 14
![Page 159: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/159.jpg)
159
Hibernate
Conference AttendeeRunner
Wednesday, September 10, 14
![Page 160: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/160.jpg)
160
Hibernate
Name: Ashley Puls
Runner
Wednesday, September 10, 14
![Page 161: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/161.jpg)
161
Hibernate
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 162: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/162.jpg)
162
Hibernate
Name: Ashley Puls
Team: Hibernate Proxy
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 163: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/163.jpg)
163
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Team
Hibernate Proxy
Name: Triathlon Club
Location: null
Description: null
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 164: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/164.jpg)
164
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Hibernate Proxy
Name: Triathlon Club
Description:
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 165: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/165.jpg)
165
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Hibernate Proxy
Name: Triathlon Club
Description:
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 166: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/166.jpg)
166
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Team
Hibernate Proxy
call a getter on the hibernate proxy:runner.getTeam().getLocation();Name: Ashley Puls
Location: Portland, OR
Runner
Name: Triathlon Club
Location: null
Description: null
Wednesday, September 10, 14
![Page 167: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/167.jpg)
167
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Team
Hibernate Proxy Team
Name: Ashley Puls
Location: Portland, OR
Runner
Name: Triathlon Club
Location: null
Description: null
Name: Triathlon Club
Location: Beaverton, OR
Description: swim, bike, run
call a getter on the hibernate proxy:runner.getTeam().getLocation();
Wednesday, September 10, 14
![Page 168: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/168.jpg)
168
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Hibernate Proxy
Name: Triathlon Club
Description:
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 169: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/169.jpg)
169
Hibernate
Name: Ashley Puls
Company:
164
Name: Ashley Puls
Team
Hibernate Proxy Team
Name: Triathlon Club
Location: Beaverton, OR
Description: swim, bike, run
Trying to access uninitialized field outside a session
LazyInitializationException
Name: Ashley Puls
Location: Portland, OR
Runner
Name: Triathlon Club
Location: null
Description: null
Wednesday, September 10, 14
![Page 170: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/170.jpg)
170
Hibernate
package org.hibernate.proxy.pojo.javassist;
/** * A Javassist-based lazy initializer proxy. * * @author Muga Nishizawa */public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler {
Wednesday, September 10, 14
![Page 171: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/171.jpg)
171
Hibernate
public static HibernateProxy getProxy( . . . ) { . . . 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(); ((Proxy) proxy).setHandler(instance); instance.constructed = true; return proxy; . . . }
Wednesday, September 10, 14
![Page 172: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/172.jpg)
172
Hibernatepublic Object invoke(final Object proxy, final Method thisMethod, final Method proceed, final Object[] args) throws Throwable { if (this.constructed) { Object result = this.invoke(thisMethod, args, proxy); if (result == INVOKE_IMPLEMENTATION) { Object target = getImplementation(); final Object returnValue = thisMethod.invoke(target, args); if (returnValue == target) { if (returnValue.getClass().isInstance(proxy)) { return proxy; } return returnValue; } else { return result; } } else { if (thisMethod.getName().equals("getHibernateLazyInitializer")) { return this; } else { return proceed.invoke(proxy, args); } }}
Wednesday, September 10, 14
![Page 173: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/173.jpg)
173
Hibernate
Hibernate Proxy
Why do we need a proxy?
Name: Ashley Puls
Team: Hibernate Proxy
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 174: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/174.jpg)
174
Hibernate
Name: Ashley Puls
Title: Software Engineer
Company: New Relic
Conference Attendee
1. Is the entity dirty? Have we changed any of the data?
2. What fields on the entity have been loaded?
Name: Ashley Puls
Team: Hibernate Proxy
Name: Ashley Puls
Location: Portland, OR
Runner
Wednesday, September 10, 14
![Page 175: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/175.jpg)
Hibernate - Build Time Tasks
• Schema Tasks• Schema Export• Schema Update• Schema Validator
175
Wednesday, September 10, 14
![Page 176: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/176.jpg)
Hibernate - Build Time Tasks
• Schema Tasks• Schema Export• Schema Update• Schema Validator
• ByteCode Tasks• EnhancementTask• InstrumentTask
176
Wednesday, September 10, 14
![Page 177: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/177.jpg)
Hibernate - Build Time Tasks
• Schema Tasks• Schema Export• Schema Update• Schema Validator
• ByteCode Tasks• EnhancementTask• InstrumentTask
177
Wednesday, September 10, 14
![Page 178: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/178.jpg)
Hibernate - Ant
178
<taskdef name="enhance" classname="org.hibernate.tool.enhance.EnhancementTask" classpathref="enhancement.classpath" />
<enhance> <fileset dir="${ejb-classes}/org/hibernate/auction/model" includes="**/*.class"/></enhance>
Wednesday, September 10, 14
![Page 179: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/179.jpg)
Hibernate - Gradle
179
apply plugin: 'java'apply plugin: 'maven'apply plugin: 'enhance'buildscript { repositories { mavenCentral() } dependencies { classpath 'org.hibernate:hibernate-gradle-plugin:VERSION' }}dependencies { compile group: 'org.hibernate.javax.persistence', name: 'hibernate-jpa-[SPEC-VERSION]-api', version: '[IMPL-VERSION]' compile group: 'org.hibernate', name: 'hibernate-gradle-plugin', version: 'VERSION'}
Wednesday, September 10, 14
![Page 180: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/180.jpg)
180
Hibernatepublic class EnhancementTask extends Task implements EnhancementContext { private List<FileSet> filesets = new ArrayList<FileSet>(); private final ClassPool classPool = new ClassPool( false ); private final Enhancer enhancer = new Enhancer( this ); @Override public void execute() throws BuildException { for (FileSet fileSet : filesets) { final File fileSetBaseDir = fileSet.getDir(project);
for (String relativeIncludedFileName :scanner.getIncludedFiles()) { final File javaClassFile = new File( fileSetBaseDir, relativeIncludedFileName ); processClassFile( javaClassFile); } } }Wednesday, September 10, 14
![Page 181: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/181.jpg)
181
Hibernatepublic class EnhancementTask extends Task implements EnhancementContext { private List<FileSet> filesets = new ArrayList<FileSet>(); private final ClassPool classPool = new ClassPool( false ); private final Enhancer enhancer = new Enhancer( this ); @Override public void execute() throws BuildException { for (FileSet fileSet : filesets) { final File fileSetBaseDir = fileSet.getDir(project);
for (String relativeIncludedFileName :scanner.getIncludedFiles()) { final File javaClassFile = new File( fileSetBaseDir, relativeIncludedFileName ); processClassFile( javaClassFile); } } }Wednesday, September 10, 14
![Page 182: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/182.jpg)
182
Hibernatepublic class EnhancementTask extends Task implements EnhancementContext { private List<FileSet> filesets = new ArrayList<FileSet>(); private final ClassPool classPool = new ClassPool( false ); private final Enhancer enhancer = new Enhancer( this ); @Override public void execute() throws BuildException { for (FileSet fileSet : filesets) { final File fileSetBaseDir = fileSet.getDir(project);
for (String relativeIncludedFileName :scanner.getIncludedFiles()) { final File javaClassFile = new File( fileSetBaseDir, relativeIncludedFileName ); processClassFile( javaClassFile); } } }Wednesday, September 10, 14
![Page 183: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/183.jpg)
183
Hibernatepublic class EnhancementTask extends Task implements EnhancementContext { private List<FileSet> filesets = new ArrayList<FileSet>(); private final ClassPool classPool = new ClassPool( false ); private final Enhancer enhancer = new Enhancer( this ); @Override public void execute() throws BuildException { for (FileSet fileSet : filesets) { final File fileSetBaseDir = fileSet.getDir(project);
for (String relativeIncludedFileName :scanner.getIncludedFiles()) { final File javaClassFile = new File( fileSetBaseDir, relativeIncludedFileName ); processClassFile( javaClassFile); } } }Wednesday, September 10, 14
![Page 184: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/184.jpg)
184
Hibernate
/** * Atm only process files annotated with either @Entity or @Embeddable */ private void processClassFile(File javaClassFile) {
final CtClass ctClass = classPool.makeClass( new FileInputStream( javaClassFile ) );
processEntityClassFile(javaClassFile, ctClass); }
Wednesday, September 10, 14
![Page 185: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/185.jpg)
/** * Atm only process files annotated with either @Entity or @Embeddable */ private void processClassFile(File javaClassFile) {
final CtClass ctClass = classPool.makeClass( new FileInputStream( javaClassFile ) );
processEntityClassFile(javaClassFile, ctClass); }
185
Hibernate
Wednesday, September 10, 14
![Page 186: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/186.jpg)
/** * Atm only process files annotated with either @Entity or @Embeddable */ private void processClassFile(File javaClassFile) {
final CtClass ctClass = classPool.makeClass( new FileInputStream( javaClassFile ) );
processEntityClassFile(javaClassFile, ctClass); }
186
Hibernate
Wednesday, September 10, 14
![Page 187: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/187.jpg)
187
Hibernate
private void processEntityClassFile(File javaClassFile, CtClass ctClass ) {
byte[] result = enhancer.enhance(ctClass.getName(),ctClass.toBytecode()); if(result != null) writeEnhancedClass(javaClassFile, result); }
}
Wednesday, September 10, 14
![Page 188: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/188.jpg)
188
Hibernate
private void processEntityClassFile(File javaClassFile, CtClass ctClass ) {
byte[] result = enhancer.enhance(ctClass.getName(),ctClass.toBytecode()); if(result != null) writeEnhancedClass(javaClassFile, result); }
}
Wednesday, September 10, 14
![Page 189: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/189.jpg)
private void enhance(CtClass managedCtClass, boolean isComposite) {
// 1. stop if managedCtClass is an interface// 2. stop if managedCtClass is already enhanced
// 3. stop if managedCtClass is not an entity }
189
Hibernate
Wednesday, September 10, 14
![Page 190: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/190.jpg)
private void enhance(CtClass managedCtClass, boolean isComposite) {
// 1. stop if managedCtClass is an interface// 2. stop if managedCtClass is already enhanced
// 3. stop if managedCtClass is not an entity // 4. enhance managedCtClass.addInterface( managedEntityCtClass ); enhancePersistentAttributes( managedCtClass ); addEntityInstanceHandling( managedCtClass ); addEntityEntryHandling( managedCtClass ); addLinkedPreviousHandling( managedCtClass ); addLinkedNextHandling( managedCtClass );}
190
Hibernate
Wednesday, September 10, 14
![Page 191: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/191.jpg)
private void enhance(CtClass managedCtClass, boolean isComposite) {
// 1. stop if managedCtClass is an interface// 2. stop if managedCtClass is already enhanced
// 3. stop if managedCtClass is not an entity // 4. enhance managedCtClass.addInterface( managedEntityCtClass ); enhancePersistentAttributes( managedCtClass ); addEntityInstanceHandling( managedCtClass ); addEntityEntryHandling( managedCtClass ); addLinkedPreviousHandling( managedCtClass ); addLinkedNextHandling( managedCtClass );}
191
Hibernate
Wednesday, September 10, 14
![Page 192: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/192.jpg)
private void enhance(CtClass managedCtClass, boolean isComposite) {
// 1. stop if managedCtClass is an interface// 2. stop if managedCtClass is already enhanced
// 3. stop if managedCtClass is not an entity // 4. enhance managedCtClass.addInterface( managedEntityCtClass ); enhancePersistentAttributes( managedCtClass ); addEntityInstanceHandling( managedCtClass ); addEntityEntryHandling( managedCtClass ); addLinkedPreviousHandling( managedCtClass ); addLinkedNextHandling( managedCtClass );}
192
Hibernate
Wednesday, September 10, 14
![Page 193: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/193.jpg)
193
Hibernateprivate CtField addField(CtClass targetClass, CtClass fieldType, String fieldName, boolean makeTransient) { final ConstPool constPool = targetClass.getClassFile().getConstPool(); final CtField theField = new CtField( fieldType, fieldName, targetClass ); targetClass.addField( theField ); // make that new field (1) private, (2) transient and (3) @Transient if ( makeTransient ) { theField.setModifiers( theField.getModifiers() | Modifier.TRANSIENT ); } theField.setModifiers( Modifier.setPrivate( theField.getModifiers() ) );
final AnnotationsAttribute annotationsAttribute = getVisibleAnnotations(theField.getFieldInfo()); annotationsAttribute.addAnnotation( new Annotation( Transient.class.getName(), constPool ) ); return theField;}Wednesday, September 10, 14
![Page 194: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/194.jpg)
194
Hibernateprivate CtField addField(CtClass targetClass, CtClass fieldType, String fieldName, boolean makeTransient) { final ConstPool constPool = targetClass.getClassFile().getConstPool(); final CtField theField = new CtField( fieldType, fieldName, targetClass ); targetClass.addField( theField ); // make that new field (1) private, (2) transient and (3) @Transient if ( makeTransient ) { theField.setModifiers( theField.getModifiers() | Modifier.TRANSIENT ); } theField.setModifiers( Modifier.setPrivate( theField.getModifiers() ) );
final AnnotationsAttribute annotationsAttribute = getVisibleAnnotations(theField.getFieldInfo()); annotationsAttribute.addAnnotation( new Annotation( Transient.class.getName(), constPool ) ); return theField;}Wednesday, September 10, 14
![Page 195: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/195.jpg)
195
Hibernateprivate CtField addField(CtClass targetClass, CtClass fieldType, String fieldName, boolean makeTransient) { final ConstPool constPool = targetClass.getClassFile().getConstPool(); final CtField theField = new CtField( fieldType, fieldName, targetClass ); targetClass.addField( theField ); // make that new field (1) private, (2) transient and (3) @Transient if ( makeTransient ) { theField.setModifiers( theField.getModifiers() | Modifier.TRANSIENT ); } theField.setModifiers( Modifier.setPrivate( theField.getModifiers() ) );
final AnnotationsAttribute annotationsAttribute = getVisibleAnnotations(theField.getFieldInfo()); annotationsAttribute.addAnnotation( new Annotation( Transient.class.getName(), constPool ) ); return theField;}Wednesday, September 10, 14
![Page 196: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/196.jpg)
196
Hibernateprivate CtField addField(CtClass targetClass, CtClass fieldType, String fieldName, boolean makeTransient) { final ConstPool constPool = targetClass.getClassFile().getConstPool(); final CtField theField = new CtField( fieldType, fieldName, targetClass ); targetClass.addField( theField ); // make that new field (1) private, (2) transient and (3) @Transient if ( makeTransient ) { theField.setModifiers( theField.getModifiers() | Modifier.TRANSIENT ); } theField.setModifiers( Modifier.setPrivate( theField.getModifiers() ) );
final AnnotationsAttribute annotationsAttribute = getVisibleAnnotations(theField.getFieldInfo()); annotationsAttribute.addAnnotation( new Annotation( Transient.class.getName(), constPool ) ); return theField;}Wednesday, September 10, 14
![Page 197: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/197.jpg)
197
Hibernate
private void addGetter(CtClass targetClass, CtField theField, String getterName) { targetClass.addMethod( CtNewMethod.getter( getterName, theField ) );}
private void addSetter(CtClass targetClass, CtField theField, String setterName) { targetClass.addMethod( CtNewMethod.setter( setterName, theField ) );}
Wednesday, September 10, 14
![Page 198: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/198.jpg)
198
Hibernate
private void addGetter(CtClass targetClass, CtField theField, String getterName) { targetClass.addMethod( CtNewMethod.getter( getterName, theField ) );}
private void addSetter(CtClass targetClass, CtField theField, String setterName) { targetClass.addMethod( CtNewMethod.setter( setterName, theField ) );}
Wednesday, September 10, 14
![Page 199: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/199.jpg)
199
Hibernate
private byte[] getByteCode(CtClass managedCtClass) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); final DataOutputStream out = new DataOutputStream( byteStream ); try { managedCtClass.toBytecode( out ); return byteStream.toByteArray(); } finally { out.close(); }}
Wednesday, September 10, 14
![Page 200: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/200.jpg)
200
Hibernate
private byte[] getByteCode(CtClass managedCtClass) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); final DataOutputStream out = new DataOutputStream( byteStream ); try { managedCtClass.toBytecode( out ); return byteStream.toByteArray(); } finally { out.close(); }}
Wednesday, September 10, 14
![Page 201: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/201.jpg)
201
Hibernate
private void processEntityClassFile(File javaClassFile, CtClass ctClass ) {
byte[] result = enhancer.enhance(ctClass.getName(),ctClass.toBytecode()); if(result != null) writeEnhancedClass(javaClassFile, result); }
}
Wednesday, September 10, 14
![Page 202: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/202.jpg)
202
Hibernate
private void processEntityClassFile(File javaClassFile, CtClass ctClass ) {
byte[] result = enhancer.enhance(ctClass.getName(),ctClass.toBytecode()); if(result != null) writeEnhancedClass(javaClassFile, result); }
}
Wednesday, September 10, 14
![Page 203: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/203.jpg)
203
Hibernate private void writeEnhancedClass(File javaClassFile, byte[] result) {
if ( javaClassFile.delete() ) { if ( ! javaClassFile.createNewFile() ) { log( "Unable to recreate class file [" + javaClassFile.getName() + "]", Project.MSG_INFO ); } }
FileOutputStream outputStream = new FileOutputStream( javaClassFile, false ); try { outputStream.write( result); outputStream.flush(); } finally { outputStream.close(); } }
Wednesday, September 10, 14
![Page 204: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/204.jpg)
204
Hibernate private void writeEnhancedClass(File javaClassFile, byte[] result) {
if ( javaClassFile.delete() ) { if ( ! javaClassFile.createNewFile() ) { log( "Unable to recreate class file [" + javaClassFile.getName() + "]", Project.MSG_INFO ); } }
FileOutputStream outputStream = new FileOutputStream( javaClassFile, false ); try { outputStream.write( result); outputStream.flush(); } finally { outputStream.close(); } }
Wednesday, September 10, 14
![Page 205: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/205.jpg)
205
Hibernate private void writeEnhancedClass(File javaClassFile, byte[] result) {
if ( javaClassFile.delete() ) { if ( ! javaClassFile.createNewFile() ) { log( "Unable to recreate class file [" + javaClassFile.getName() + "]", Project.MSG_INFO ); } }
FileOutputStream outputStream = new FileOutputStream( javaClassFile, false ); try { outputStream.write( result); outputStream.flush(); } finally { outputStream.close(); } }
Wednesday, September 10, 14
![Page 206: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/206.jpg)
206
Spring
Wednesday, September 10, 14
![Page 207: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/207.jpg)
207
Spring
Wednesday, September 10, 14
![Page 208: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/208.jpg)
208
Spring
https://github.com/scottfrederick/spring-music
Wednesday, September 10, 14
![Page 209: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/209.jpg)
209
Springpackage org.cloudfoundry.samples.music.config.web;
@Configuration@ComponentScan(basePackageClasses = { AlbumController.class })public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean public InternalResourceViewResolver internalResourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); internalResourceViewResolver.setPrefix("/WEB-INF/"); . . . Wednesday, September 10, 14
![Page 210: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/210.jpg)
210
Springpackage org.cloudfoundry.samples.music.config.web;
@Configuration@ComponentScan(basePackageClasses = { AlbumController.class })public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean public InternalResourceViewResolver internalResourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); internalResourceViewResolver.setPrefix("/WEB-INF/"); . . . Wednesday, September 10, 14
![Page 211: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/211.jpg)
211
Springpackage org.cloudfoundry.samples.music.config.web;
@Configuration@ComponentScan(basePackageClasses = { AlbumController.class })public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean public InternalResourceViewResolver internalResourceViewResolver() { InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); internalResourceViewResolver.setPrefix("/WEB-INF/"); . . . Wednesday, September 10, 14
![Page 212: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/212.jpg)
212
Spring
@Controller@RequestMapping(value = "/albums")public class AlbumController { private static final Logger logger = LoggerFactory.getLogger(AlbumController.class);
private final AlbumRepository repository; private SongsService songs;
Wednesday, September 10, 14
![Page 213: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/213.jpg)
213
Spring
@Controller@RequestMapping(value = "/albums")public class AlbumController { private static final Logger logger = LoggerFactory.getLogger(AlbumController.class);
private final AlbumRepository repository; private SongsService songs;
Wednesday, September 10, 14
![Page 214: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/214.jpg)
214
Spring
@Component: A generic Spring component
@Repository: Class at the persistence layer
@Controller: Class which receives HTTP servlet requests and responses
@Service: Class at the service level
AlbumRepositoryPopulator
MongoAlbumRepository, JpaAlbumRepository
ErrorController, InfoController, AlbumController
Wednesday, September 10, 14
![Page 215: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/215.jpg)
215
Springpackage org.springframework.context.annotation;
/** * A component provider that scans the classpath from a base package. * It then applies exclude and include filters to the resulting * classes to find candidates. * * <p>This implementation is based on Spring's * {@link org.springframework.core.type.classreading.MetadataReader * MetadataReader} * facility, backed by an ASM * {@linkorg.springframework.asm.ClassReader ClassReader}. */public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
Wednesday, September 10, 14
![Page 216: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/216.jpg)
216
Spring
public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + resourcePattern; Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (isCandidateComponent(sbd)) { candidates.add(sbd); } } } return candidates;}
Wednesday, September 10, 14
![Page 217: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/217.jpg)
217
Spring
public Set<BeanDefinition> findCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>(); String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + "/" + resourcePattern; Resource[] resources = resourcePatternResolver.getResources(packageSearchPath); for (Resource resource : resources) { MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource); if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (isCandidateComponent(sbd)) { candidates.add(sbd); } } } return candidates;}
Wednesday, September 10, 14
![Page 218: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/218.jpg)
218
SpringSimpleMetadataReader
Resource
Wednesday, September 10, 14
![Page 219: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/219.jpg)
R:B:
219
SpringSimpleMetadataReader
Resource
Wednesday, September 10, 14
![Page 220: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/220.jpg)
R:B:
220
SpringSimpleMetadataReader
metadataResource
Wednesday, September 10, 14
![Page 221: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/221.jpg)
221
Spring
package org.springframework.core.type.classreading;
final class SimpleMetadataReader implements MetadataReader {
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new
AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
Wednesday, September 10, 14
![Page 222: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/222.jpg)
222
Spring
package org.springframework.core.type.classreading;
final class SimpleMetadataReader implements MetadataReader {
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new
AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
Wednesday, September 10, 14
![Page 223: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/223.jpg)
223
Spring
package org.springframework.core.type.classreading;
final class SimpleMetadataReader implements MetadataReader {
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new
AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
Wednesday, September 10, 14
![Page 224: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/224.jpg)
224
Spring
package org.springframework.core.type.classreading;
final class SimpleMetadataReader implements MetadataReader {
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new
AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
Wednesday, September 10, 14
![Page 225: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/225.jpg)
225
Spring
package org.springframework.core.type.classreading;
final class SimpleMetadataReader implements MetadataReader {
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException { InputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader = new ClassReader(is); AnnotationMetadataReadingVisitor visitor = new
AnnotationMetadataReadingVisitor(classLoader); classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
Wednesday, September 10, 14
![Page 226: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/226.jpg)
R:B:
226
Spring
ClassReader
SimpleMetadataReader
metadata
AnnotationMetadataReadingVisitor
Resource
Wednesday, September 10, 14
![Page 227: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/227.jpg)
R:B:
227
ASM
ClassReader: event producer
ClassWriter: event consumer
BankTrans
ClassVisitor: event filter
visitField
visitMethod
BankTrans
ClassVisitor: delegates class events, event filter
Wednesday, September 10, 14
![Page 228: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/228.jpg)
228
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 229: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/229.jpg)
229
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 230: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/230.jpg)
230
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 231: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/231.jpg)
R:B:
231
Spring
ClassReader
SimpleMetadataReader
metadata
AnnotationMetadataReadingVisitor
Resource
visitMethod
Wednesday, September 10, 14
![Page 232: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/232.jpg)
232
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 233: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/233.jpg)
233
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 234: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/234.jpg)
234
Springpublic class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor implements AnnotationMetadata {
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ((access & Opcodes.ACC_BRIDGE) != 0) { return super.visitMethod(access, name, desc, signature, exceptions); } return new MethodMetadataReadingVisitor(name, access, getClassName(), classLoader, methodMetadataSet); }
public AnnotationVisitor visitAnnotation(final String desc, boolean visible) { String className = Type.getType(desc).getClassName(); this.annotationSet.add(className); return new AnnotationAttributesReadingVisitor(className, attributesMap,
metaAnnotationMap, classLoader); }Wednesday, September 10, 14
![Page 235: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/235.jpg)
R:B:
235
Spring
ClassReader
SimpleMetadataReader
metadata
AnnotationMetadataReadingVisitor
Resource
visitMethod
visitAnnotation
Wednesday, September 10, 14
![Page 236: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/236.jpg)
R:B:
236
Spring
ClassReader
SimpleMetadataReader
metadata
AnnotationMetadataReadingVisitor
Resource
visitMethod
visitAnnotation
visitAnnotation
visitvisitAnnotation
visitArrayvisitEnum
Wednesday, September 10, 14
![Page 237: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/237.jpg)
237
Springrepackaging ASM in spring-core
Source: http://www.clker.com/clipart-3085.html
Wednesday, September 10, 14
![Page 238: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/238.jpg)
238
Springrepackaging ASM in spring-core
Source: http://www.clker.com/clipart-3085.html
https://jira.spring.io/browse/SPR-10292
Wednesday, September 10, 14
![Page 239: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/239.jpg)
239
Lessons Learned
Wednesday, September 10, 14
![Page 240: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/240.jpg)
240
Lessons Learned
Source: http://www.mindbodygreen.com/0-4965/How-Baby-Steps-Lead-to-Big-Results.html
Wednesday, September 10, 14
![Page 241: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/241.jpg)
241
Lessons Learned
Source: http://www.dishesandsocks.com/2011/06/16/teacher-classroom-organization-part-1/
Wednesday, September 10, 14
![Page 242: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/242.jpg)
242
Lessons Learned
Source: http://4hdwallpapers.com/transformer-isolated-on-white-background-3d-render.html
Wednesday, September 10, 14
![Page 243: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/243.jpg)
243
Applications
Obfuscate so users can not view your source code
Find bugs
Write your own compiler for a language that runs on the JVM
Add logging to an application
Perform preprocessing of code at build time
Restrict API methods for specific users
Determine if a collection is accessed by multiple threads
Lazy load data from a databaseFind differences between jars
Wednesday, September 10, 14
![Page 244: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/244.jpg)
244
Make bytecode manipulation frameworks your friend. They might save your job one day.
Source: http://www.kulfoto.com/dog-pictures/15799/mans-best-friend
Wednesday, September 10, 14
![Page 245: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/245.jpg)
245
Wednesday, September 10, 14
![Page 246: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.vdocument.in/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/246.jpg)
Source: http://alangregerman.typepad.com/.a/6a00d83516c0ad53ef017c3329aba8970b-800wi
Questions?
246
Wednesday, September 10, 14