Living in the Matrix with Bytecode Manipulation (New Relic)
description
Transcript of Living in the Matrix with Bytecode Manipulation (New Relic)
![Page 1: Living in the Matrix with Bytecode Manipulation (New Relic)](https://reader031.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/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.fdocuments.us/reader031/viewer/2022020207/558a2930d8b42a4c028b45c3/html5/thumbnails/246.jpg)
Source: http://alangregerman.typepad.com/.a/6a00d83516c0ad53ef017c3329aba8970b-800wi
Questions?
246
Wednesday, September 10, 14