SlideShare a Scribd company logo
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Lecture 10 :

Advanced Reflection in Java
LSINF 2335
Programming Paradigms
Prof. Kim Mens
UCL / EPL / INGI


(Slides partly based on chapter 5 of
the book “Java Reflection in Action”
and on slides by Pr. Walter Cazzola)
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Advanced reflective features
■ Dynamic proxies
– Proxy
– InvocationHandler
■ Call stack introspection
– Throwable
– StackTraceElement
■ Instrumentation
– java.lang.instrument
■ Conclusion
2
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Proxy Design Pattern
3
■ The proxy pattern defines a proxy as a surrogate
for another object to control access to it
– a proxy keeps a reference to the real object,
– is substitutable with it (identical interface)
– and delegates requests to it
■ Typical examples of usage of proxies:
– local representation of remote objects
– delay of expensive operations
– access protection for secure objects
– ...
Client
action()
Subject
action()
Proxy
action()
RealSubject
delegate
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Dynamic proxies
■ To easily implement proxies, Java 1.3 introduced
the Dynamic Proxy API
■ A dynamic proxy requires
– an instance of the Proxy class
– a proxy interface
• this is the interface that is implemented by the proxy class
• interestingly, one proxy can implement multiple interfaces
– each proxy instance has an InvocationHandler
4Proxy
InvocationHandler
delegates to
IProxy
implements
ProxyHandler
implements
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
InvocationHandler
■ Each proxy instance has an InvocationHandler
– The invocation handler determines how to treat messages
that are sent to the proxy instance
– When a method is invoked on a proxy instance, the
method invocation is encoded and dispatched to the
invoke() method of its invocation handler



Object invoke(Object proxy, Method m, Object[] args)
5
Proxy
invoke(Object, Method, Object[]) : Object
<<interface>>
InvocationHandlerdelegates to
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example: an InvocationHandler
to trace method calls
6
public class TraceHandler implements InvocationHandler {
private Object baseObject; // the real object the proxy delegates to
public TraceHandler(Object base) {
baseObject = base;
}
public Object invoke(Object proxy, Method m, Object[] args) {
Object result = null; // result to be returned by the method
try {
System.out.println("before " + m.getName());
result = m.invoke(baseObject, args);
System.out.println("after " + m.getName());
}
catch (Exception e) {

e.printStackTrace();
}
return result;
}

}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Proxy class
■ Provides static methods for creating dynamic proxy classes and
instances
■ Is also the superclass of all dynamic proxy classes created by those
methods
■ To create a proxy for some class Foo

InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
■ or more simply:

Foo f = (Foo) Proxy.

newProxyInstance( Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler );
7
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example: a Proxy that traces
method calls
8
public class Component1 implements IComponent {
Color myColor;
public Color getColor() {
System.out.println("Inside the getColor() method of Component1.");
return myColor;
}
public void setColor(Color color) {
myColor = color;
System.out.println("The color of component 1 has been set.");
}
}
public interface IComponent {
public Color getColor();
public void setColor(Color color);
}
interface
shared by real
object and proxy
real object to
which proxy will
delegate
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example: a Proxy that traces
method calls
9
IComponent c1 = new Component1(new Color(0));
InvocationHandler th = new TraceHandler(c1);
IComponent proxy = (IComponent) Proxy.newProxyInstance(
c1.getClass().getClassLoader(),

c1.getClass().getInterfaces(),
th);
/* standard call */
c1.getColor();
/* traced call */
proxy.getColor();
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
How Java creates a proxy
10
Bibliography Examples: Tracing and Proxy Chaining.
Java’s Dynamic Proxy.
How Java Creates a Proxy.
extends
implements
implements
implements
$IPoint
InvocationHandlerIPoint Proxy
Point TraceHandler
Classes
Interfaces
p thpth
- int x
- int y
+ getX(): int
+ getY(): int
+ getX(): int
+ getY(): int
+ getX(): int
+ getY(): int
- Object base
+ invoke(): Object
- InvocationHandler i
+ invoke(): Object
Generated
on-the-fly
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Advanced reflective features
■ Dynamic proxies
– Proxy
– InvocationHandler
■ Call stack introspection
– Throwable
– StackTraceElement
■ Instrumentation
– java.lang.instrument
■ Conclusion
11
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Call Stack Introspection
■ State introspection
■ Call stack
■ Reifying the call stack
– Throwable
– StackTraceElement
■ Examples:
– printing the call stack
– show warnings for unimplemented methods
12
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
State Introspection
13
■ Introspection is not only application structure
introspection
■ Information about the program execution can be
introspected as well
– the execution state
– the call stack
■ Each thread has a call stack consisting of stack
frames
■ Call stack introspection allows a thread to examine
its context
– the execution trace and the current frame
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Call Stack
1. package reflectionexample;
2.
3. public class Example {
4.
5. public static void m1() {
6. m2();
7. }
8.
9. public static void m2() {
10. m3();
11. }
12.
13. public static void m3() {
14. // do something
15. }
16.
17. public static void main(String[] args) {
18. m1();
19. }
20.
21. }
class: Example
method: main
line: 18
class: Example
method: m1
line: 6
Call Stack:
class: Example
method: m2
line: 10
class: Example
method: m3
line: 14
(m3)
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Reifying the call stack :
Throwable
15
■ In Java there is no accessible CallStack meta-object
■ But...
– When an instance of Throwable is created, the call stack is
saved as an array of StackTraceElement
– By writing: new Throwable().getStackTrace()
– This gives us access to a representation of the call stack at
the moment when Throwable was created.
– The getStackTrace() method returns the current call stack
as an array of StackTraceElement.
• The first frame (position 0) is the current frame
■ Only introspection
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 1: print the call stack
16
public class CallStackExample1 {
public static void m1() {
m2();
}
public static void m2() {
m3();
}
public static void m3() {
StackTraceElement[] stack = new Throwable().getStackTrace();
for (int i = 0; i < stack.length; i++) {
System.out.println(stack[i]);
}
}
public static void main(String[] args) {
m1();
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 2: show warnings for
unimplemented methods
■ How to create an auxiliary method to be used as
placeholder for unimplemented methods?
– I have a method todo() remaining to be implemented
– I provide the following dummy implementation
– When calling that method todo() I want to get a warning:
– as well as a warning message on the Console:
Warning:
reflectionexample.CallStackExample2.todo(CallStackExample2.java:8)
() : this method remains to be implemented
public static void todo() {
toBeImplemented();
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
18
Example 2: show warnings for
methods to be implemented
public class CallStackExample2 {
public static void todo() {
toBeImplemented();
}
public static void toBeImplemented() {
// Get the stack element referring to the method calling this one
StackTraceElement el = new Throwable().getStackTrace()[1];
// Show a dialog box with information on the method remaining to be
implemented
String msg = el.toString() + "() : this method remains to be implemented";
// Show this message in a dialog box
JOptionPane.showMessageDialog(null, msg, "Erreur", JOptionPane.ERROR_MESSAGE);
// Print this warning on the console
System.err.println("Warning: " + msg);
}
public static void main(String[] args) {
todo();
}
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Reifying the call stack :
StackTraceElement
■ From a frame we can get:
– getFileName() : the filename containing the execution point
– getLineNumber() : the line number where the call occurs
– getClassName() : the name of the class containing the

execution point
– getMethodName() : the name of the method containing the 

execution point
19
“myPackage.Example.m3(Example.java:14)”
StackTraceElement:
class: Example
method: m3
line: 14
filename: Example.java
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Advanced reflective features
■ Dynamic proxies
– Proxy
– InvocationHandler
■ Call stack introspection
– Throwable
– StackTraceElement
■ Instrumentation
– java.lang.instrument
■ Conclusion
20
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Suppose we want to...
1. Instrument a Java program to print a message on
the console whenever a class is loaded by the JVM
2. Instrument a Java program to print all messages
being sent while the program is running
3. Replace the definition of a class at runtime
– even for classes with currently active instances
– for example, to change the behaviour of some messages
understood by those instances
21
... then Java instrumentation may be your answer
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Java Instrumentation
(goal)
22
■ java.lang.instrument
– Provides services that allow Java programming language
agents to instruments programs running on the JVM.
– This instrumentation is achieved by modifying byte-code.
– Allows you to create agents, that run embedded in a JVM
and intercept the classloading process, to
• monitor the classloading process
• modify the bytecode of classes
■ Can be combined with dedicated libraries for Java
bytecode manipulation, like Javassist or BCEL.
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Java Instrumentation
(mechanics)
23
To implement an agent that intercepts classloading
you need to define
– a class implementing the premain method



public static void premain(String agentArguments, 

Instrumentation instrumentation) { ... }
– a class implementing a transformer (which describes how the
bytecode should be transformed)



public class SomeTransformer implements ClassFileTransformer

public byte[] transform(ClassLoader loader, 

String className, Class redefiningClass,

ProtectionDomain domain, byte[] bytes)

throws IllegalClassFormatException { ... }
– you can put both methods in a single class
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Java Instrumentation
(mechanics)
24
– The transform method receives information on the class to be
loaded and can modify its bytecode.



public byte[] transform(ClassLoader loader, 

String className, Class redefiningClass,

ProtectionDomain domain, byte[] bytes)

• returns null if there's no modification, else returns the new
bytecode
• to modify the bytecode you can use a specialised library like
Javassist

– The premain method should add the transformer to the agent:



public static void premain(String agentArguments, 

Instrumentation instrumentation) {

instrumentation.addTransformer(new SomeTransformer()); }

SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Java Instrumentation
(mechanics)
25
– To plug the agent into the JVM and execute it, you need to put
it inside a jar:

jar cvfm MyAgent.jar ManifestFile.txt

MyAgent.class SomeTransformer.class
– The manifest file for this jar has to declare the premain class:

Premain-Class: MyAgent

If the agent modifies the bytecode, this also has to be
declared in the manifest file:

Can-Redefine-Classes: true
– Finally, to instrument a Java program you need to add the
javaagent parameter when you execute the JVM:
> java -javaagent:MyAgent.jar MyProgram
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Examples
1. Instrument a Java program to print a message on
the console whenever a class is loaded by the JVM
2. Instrument a Java program to print all messages
being sent while the program is running
3. Replace the definition of a class at runtime
– even for classes with currently active instances
– for example, to change the behaviour of some messages
understood by those instances
26
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 1: Instrument Java code
27
/**
* Just prints a message to stdout before each Class is loaded
* > java -javaagent:LogClassLoad.jar <the_Main_Class_to_execute>
*/
public class LogClassLoad implements ClassFileTransformer {
public static void premain(String options, Instrumentation ins) {
ins.addTransformer(new LogClassLoad());
}
public byte[] transform(ClassLoader loader, String className, Class cBR,
java.security.ProtectionDomain pD, byte[] classfileBuffer)
throws IllegalClassFormatException {
try {
System.out.println("LOADING: " + className);
}
catch (Throwable exc) {
System.err.println(exc);
}
return null; // For this first example no transformation is required :
// we are only logging when classes are loaded
}
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 1: Instrument Java code
28
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Examples
1. Instrument a Java program to print a message on
the console whenever a class is loaded by the JVM
2. Instrument a Java program to print all messages
being sent while the program is running
3. Replace the definition of a class at runtime
– even for classes with currently active instances
– for example, to change the behaviour of some messages
understood by those instances
29
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 2: Print all messages
30
public class TraceMethodCall implements ClassFileTransformer {
public static void premain(String options, Instrumentation ins) {
ins.addTransformer(new TraceMethodCall());
}
public byte[] transform(ClassLoader loader, String className, Class cBR,
java.security.ProtectionDomain pD, byte[] classfileBuffer)
throws IllegalClassFormatException {
try {
if(isSystemClass(className)) return null;
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get(className);
CtMethod[] allmethods = cc.getMethods();
for(CtMethod method : allmethods) {
try {
method.insertBefore("TraceMethodCall.trace();");
} catch (Exception e) { }
}
return cc.toBytecode();
}
catch (Throwable exc) { }
return null; // No transformation required
}
for(CtMethod method : allmethods) {
try {
method.insertBefore("TraceMethodCall.trace();");
} catch (Exception e) { }
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 2: Print all messages
31
public class TraceMethodCall implements ClassFileTransformer {
...
/** Check if a class is a system class, based on the package name. **/
public static boolean isSystemClass(String className) { ... }
public static boolean isDottedSystemClass(String className) { ... }
...
public static void trace() {
Throwable thw = new Throwable();
if(thw.getStackTrace().length > 2) {
StackTraceElement stackTo = thw.getStackTrace()[1];
StackTraceElement stackFrom = thw.getStackTrace()[2];
if(!isDottedSystemClass(stackFrom.getClassName())) {
System.out.println(""" + stackFrom.getClassName() + "." 

+ stackFrom.getMethodName() + "" -> " + """ 

+ stackTo.getClassName() + "." + stackTo.getMethodName() + """);
}
}
}
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Example 2: Print all messages
32
package reflectionexample;
public class CallStackExample0 {
public static void m1() { m2(); }
public static void m2() { m3(); }
public static void m3() { }
public static void main(String[] args) { m1(); }
}
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Examples
1. Instrument a Java program to print a message on
the console whenever a class is loaded by the JVM
2. Instrument a Java program to print all messages
being sent while the program is running
3. Replace the definition of a class at runtime
– even for classes with currently active instances
– for example, to change the behaviour of some messages
understood by those instances
33
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example 2: Replacing a class
(goal)
34
/**
* This modified class replaces the original class at run-time.
* The modified class has the same name but is located in a subdirectory.
* It is a clone of the original class where one method was changed.
* Instances of this class will react differently to those messages.
*/
public class SwappedClass {
public void message() {
System.out.println("I am the MODIFIED SwapedClass");
}
}
/**
* This is the original class that will be replaced by a modified copy at run-time.
* The modified copy of this class is located in the "modif" subdirectory.
*/
public class SwappedClass {
public void message() {
System.out.println("I am the original SwapedClass");
}
}
original
modifie
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example 2: Replacing a class
(mechanics)
■ to dynamically replace a class execute this code:
35
import java.lang.instrument.Instrumentation;
public class SwapClass {
private static Instrumentation instCopy;
public static void premain(String options, Instrumentation inst) {
instCopy = inst;
}
public static Instrumentation getInstrumentation() {
return instCopy;
}
}
SwapClass.getInstrumentation().redefineClasses(...)
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example 2: Replacing a class
(code)
36
public class SwapTest {
public static void main (String[] args) {
try {
// Create an instance of the class that will be modified
SwappedClass swapped = new SwappedClass();
// Send a message to the instance; the original message should be displayed
swapped.message();
// Now replace the class by a modified version
// 1. read the class definition from file
FileChannel fc =
new FileInputStream(new File("modif/SwappedClass.class")).getChannel();
ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int)fc.size());
byte[] classBuffer = new byte[buf.capacity()];
buf.get(classBuffer, 0, classBuffer.length);
// 2. use instrumentation API to replace the old class’s definition by the new one
SwapClass.getInstrumentation().redefineClasses(
new ClassDefinition[] {
new ClassDefinition(swapped.getClass(), classBuffer)});
// Send a message to the old instance; the MODIFIED message will be displayed
swapped.message();
}
catch (Exception e){
System.out.println(e);
}
}
}
SwapClass.getInstrumentation().redefineClasses(
new ClassDefinition[] {
new ClassDefinition(swapped.getClass(), classBuffer)});
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic. Example 2: Replacing a class
(at work)
37
SINF2335:Prog.Paradigms:
Theory,Pract.andApplic.
Reflection in Java: Conclusions
38
■ Benefits
– reflection in Java opens up the structure and the
execution trace of the program;
– the reflection API is (relatively) simple and quite
complete.
■ Drawbacks
– reflection in Java is (mostly) limited to introspection;
– there isn't a clear separation between base and meta-
level;
– reflection in Java has been proved inefficient

More Related Content

What's hot (20)

PPTX
Graal in GraalVM - A New JIT Compiler
Koichi Sakata
 
PPTX
Core java
Shivaraj R
 
PDF
Java 9 New Features
Ali BAKAN
 
PPTX
JVM++: The Graal VM
Martin Toshev
 
PDF
JVM JIT-compiler overview @ JavaOne Moscow 2013
Vladimir Ivanov
 
PPTX
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
PPTX
Core java
Sun Technlogies
 
PDF
Native Java with GraalVM
Sylvain Wallez
 
PDF
Spring Boot Interview Questions | Edureka
Edureka!
 
PPTX
Java 8 Date-Time API
Anindya Bandopadhyay
 
ODP
Multithreading In Java
parag
 
PDF
GraalVm and Quarkus
Sascha Rodekamp
 
PPTX
Coroutines in Kotlin
Alexey Soshin
 
PDF
Java Concurrency by Example
CodeOps Technologies LLP
 
PPTX
Android Booting Sequence
Jayanta Ghoshal
 
PDF
Advanced Node.JS Meetup
LINAGORA
 
PDF
Java 10 New Features
Ali BAKAN
 
PPTX
1 java programming- introduction
jyoti_lakhani
 
PDF
Introduction to Java Programming Language
jaimefrozr
 
PDF
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 
Graal in GraalVM - A New JIT Compiler
Koichi Sakata
 
Core java
Shivaraj R
 
Java 9 New Features
Ali BAKAN
 
JVM++: The Graal VM
Martin Toshev
 
JVM JIT-compiler overview @ JavaOne Moscow 2013
Vladimir Ivanov
 
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
Lucas Jellema
 
Core java
Sun Technlogies
 
Native Java with GraalVM
Sylvain Wallez
 
Spring Boot Interview Questions | Edureka
Edureka!
 
Java 8 Date-Time API
Anindya Bandopadhyay
 
Multithreading In Java
parag
 
GraalVm and Quarkus
Sascha Rodekamp
 
Coroutines in Kotlin
Alexey Soshin
 
Java Concurrency by Example
CodeOps Technologies LLP
 
Android Booting Sequence
Jayanta Ghoshal
 
Advanced Node.JS Meetup
LINAGORA
 
Java 10 New Features
Ali BAKAN
 
1 java programming- introduction
jyoti_lakhani
 
Introduction to Java Programming Language
jaimefrozr
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Edureka!
 

Similar to Advanced Reflection in Java (20)

PDF
Java reflection
Ranjith Chaz
 
PDF
Optimizing JavaScript and Dynamic Languages on the JVM
Marcus Lagergren
 
PPTX
Beirut Java User Group JVM presentation
Mahmoud Anouti
 
PDF
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
PPT
Basic info on java intro
kabirmahlotra
 
PPT
Basic info on java intro
kabirmahlotra
 
PDF
invokedynamic for Mere Mortals [Code One 2019]
David Buck
 
PPT
Java14
aiter2002
 
PPTX
Java interface
Md. Tanvir Hossain
 
PPTX
Metaprogramming Techniques In Groovy And Grails
zenMonkey
 
PDF
Unveiling the Hidden Layers of Java Class Files: Beyond Bytecode (Devnexus 2025)
NTT DATA Technology & Innovation
 
PPTX
Java and the JVM
Manish Pandit
 
PDF
J9's MethodHandle Compilation Pipeline #JFokus2015
DanHeidinga
 
PDF
Invoke dynamic your api to hotspot
Boundary
 
PPTX
Making Java more dynamic: runtime code generation for the JVM
Rafael Winterhalter
 
PDF
Java Enterprise Edition
Francesco Nolano
 
PPTX
Java Basics
Emprovise
 
PDF
Invoke dynamite in Java EE with invoke dynamic
Antoine Sabot-Durand
 
PPTX
Java byte code in practice
Rafael Winterhalter
 
PDF
Dynamic Proxy by Java
Kan-Han (John) Lu
 
Java reflection
Ranjith Chaz
 
Optimizing JavaScript and Dynamic Languages on the JVM
Marcus Lagergren
 
Beirut Java User Group JVM presentation
Mahmoud Anouti
 
JRuby and Invokedynamic - Japan JUG 2015
Charles Nutter
 
Basic info on java intro
kabirmahlotra
 
Basic info on java intro
kabirmahlotra
 
invokedynamic for Mere Mortals [Code One 2019]
David Buck
 
Java14
aiter2002
 
Java interface
Md. Tanvir Hossain
 
Metaprogramming Techniques In Groovy And Grails
zenMonkey
 
Unveiling the Hidden Layers of Java Class Files: Beyond Bytecode (Devnexus 2025)
NTT DATA Technology & Innovation
 
Java and the JVM
Manish Pandit
 
J9's MethodHandle Compilation Pipeline #JFokus2015
DanHeidinga
 
Invoke dynamic your api to hotspot
Boundary
 
Making Java more dynamic: runtime code generation for the JVM
Rafael Winterhalter
 
Java Enterprise Edition
Francesco Nolano
 
Java Basics
Emprovise
 
Invoke dynamite in Java EE with invoke dynamic
Antoine Sabot-Durand
 
Java byte code in practice
Rafael Winterhalter
 
Dynamic Proxy by Java
Kan-Han (John) Lu
 
Ad

More from kim.mens (20)

PDF
Software Maintenance and Evolution
kim.mens
 
PDF
Context-Oriented Programming
kim.mens
 
PDF
Software Reuse and Object-Oriented Programming
kim.mens
 
PDF
Bad Code Smells
kim.mens
 
PDF
Object-Oriented Design Heuristics
kim.mens
 
PDF
Software Patterns
kim.mens
 
PDF
Code Refactoring
kim.mens
 
PDF
Domain Modelling
kim.mens
 
PDF
Object-Oriented Application Frameworks
kim.mens
 
PDF
Towards a Context-Oriented Software Implementation Framework
kim.mens
 
PDF
Towards a Taxonomy of Context-Aware Software Variabilty Approaches
kim.mens
 
PDF
Breaking the Walls: A Unified Vision on Context-Oriented Software Engineering
kim.mens
 
PDF
Context-oriented programming
kim.mens
 
PDF
Basics of reflection
kim.mens
 
PDF
Reflection in Ruby
kim.mens
 
PDF
Introduction to Ruby
kim.mens
 
PDF
Introduction to Smalltalk
kim.mens
 
PDF
A gentle introduction to reflection
kim.mens
 
PDF
Managing the Evolution of Information Systems with Intensional Views and Rela...
kim.mens
 
PDF
Usage contracts (presented at SATToSE 2014 in L'Aquila, Italy)
kim.mens
 
Software Maintenance and Evolution
kim.mens
 
Context-Oriented Programming
kim.mens
 
Software Reuse and Object-Oriented Programming
kim.mens
 
Bad Code Smells
kim.mens
 
Object-Oriented Design Heuristics
kim.mens
 
Software Patterns
kim.mens
 
Code Refactoring
kim.mens
 
Domain Modelling
kim.mens
 
Object-Oriented Application Frameworks
kim.mens
 
Towards a Context-Oriented Software Implementation Framework
kim.mens
 
Towards a Taxonomy of Context-Aware Software Variabilty Approaches
kim.mens
 
Breaking the Walls: A Unified Vision on Context-Oriented Software Engineering
kim.mens
 
Context-oriented programming
kim.mens
 
Basics of reflection
kim.mens
 
Reflection in Ruby
kim.mens
 
Introduction to Ruby
kim.mens
 
Introduction to Smalltalk
kim.mens
 
A gentle introduction to reflection
kim.mens
 
Managing the Evolution of Information Systems with Intensional Views and Rela...
kim.mens
 
Usage contracts (presented at SATToSE 2014 in L'Aquila, Italy)
kim.mens
 
Ad

Recently uploaded (20)

PPTX
CNS.pptx Central nervous system meninges ventricles of brain it's structure a...
Ashwini I Chuncha
 
PDF
Carbon-richDustInjectedintotheInterstellarMediumbyGalacticWCBinaries Survives...
Sérgio Sacani
 
PPTX
Ghent University Global Campus: Overview
Ghent University Global Campus
 
DOCX
Analytical methods in CleaningValidation.docx
Markus Janssen
 
PDF
Service innovation with AI: Transformation of value proposition and market se...
Selcen Ozturkcan
 
PPT
Experimental Design by Cary Willard v3.ppt
MohammadRezaNirooman1
 
PDF
Integrating Lifestyle Data into Personalized Health Solutions (www.kiu.ac.ug)
publication11
 
PPTX
Neuroinflammation and microglial subtypes
KanakChaudhary10
 
PPTX
Phage Therapy and Bacteriophage Biology.pptx
Prachi Virat
 
PDF
A High-Caliber View of the Bullet Cluster through JWST Strong and Weak Lensin...
Sérgio Sacani
 
PDF
Carbonate formation and fluctuating habitability on Mars
Sérgio Sacani
 
PPTX
770043401-q1-Ppt-pe-and-Health-7-week-1-lesson-1.pptx
AizaRazonado
 
PDF
A Man of the Forest: The Contributions of Gifford Pinchot
RowanSales
 
PDF
Portable Hyperspectral Imaging (pHI) for the enhanced recording of archaeolog...
crabbn
 
PPT
Restriction digestion of DNA for students of undergraduate and post graduate ...
DrMukeshRameshPimpli
 
PDF
Pharmakon of algorithmic alchemy: Marketing in the age of AI
Selcen Ozturkcan
 
PDF
EXploring Nanobiotechnology: Bridging Nanoscience and Biology for real world ...
Aamena3
 
PDF
The emergence of galactic thin and thick discs across cosmic history
Sérgio Sacani
 
PDF
BlackBody Radiation experiment report.pdf
Ghadeer Shaabna
 
PDF
Plankton and Fisheries Bovas Joel Notes.pdf
J. Bovas Joel BFSc
 
CNS.pptx Central nervous system meninges ventricles of brain it's structure a...
Ashwini I Chuncha
 
Carbon-richDustInjectedintotheInterstellarMediumbyGalacticWCBinaries Survives...
Sérgio Sacani
 
Ghent University Global Campus: Overview
Ghent University Global Campus
 
Analytical methods in CleaningValidation.docx
Markus Janssen
 
Service innovation with AI: Transformation of value proposition and market se...
Selcen Ozturkcan
 
Experimental Design by Cary Willard v3.ppt
MohammadRezaNirooman1
 
Integrating Lifestyle Data into Personalized Health Solutions (www.kiu.ac.ug)
publication11
 
Neuroinflammation and microglial subtypes
KanakChaudhary10
 
Phage Therapy and Bacteriophage Biology.pptx
Prachi Virat
 
A High-Caliber View of the Bullet Cluster through JWST Strong and Weak Lensin...
Sérgio Sacani
 
Carbonate formation and fluctuating habitability on Mars
Sérgio Sacani
 
770043401-q1-Ppt-pe-and-Health-7-week-1-lesson-1.pptx
AizaRazonado
 
A Man of the Forest: The Contributions of Gifford Pinchot
RowanSales
 
Portable Hyperspectral Imaging (pHI) for the enhanced recording of archaeolog...
crabbn
 
Restriction digestion of DNA for students of undergraduate and post graduate ...
DrMukeshRameshPimpli
 
Pharmakon of algorithmic alchemy: Marketing in the age of AI
Selcen Ozturkcan
 
EXploring Nanobiotechnology: Bridging Nanoscience and Biology for real world ...
Aamena3
 
The emergence of galactic thin and thick discs across cosmic history
Sérgio Sacani
 
BlackBody Radiation experiment report.pdf
Ghadeer Shaabna
 
Plankton and Fisheries Bovas Joel Notes.pdf
J. Bovas Joel BFSc
 

Advanced Reflection in Java

  • 1. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Lecture 10 :
 Advanced Reflection in Java LSINF 2335 Programming Paradigms Prof. Kim Mens UCL / EPL / INGI 
 (Slides partly based on chapter 5 of the book “Java Reflection in Action” and on slides by Pr. Walter Cazzola)
  • 2. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Advanced reflective features ■ Dynamic proxies – Proxy – InvocationHandler ■ Call stack introspection – Throwable – StackTraceElement ■ Instrumentation – java.lang.instrument ■ Conclusion 2
  • 3. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Proxy Design Pattern 3 ■ The proxy pattern defines a proxy as a surrogate for another object to control access to it – a proxy keeps a reference to the real object, – is substitutable with it (identical interface) – and delegates requests to it ■ Typical examples of usage of proxies: – local representation of remote objects – delay of expensive operations – access protection for secure objects – ... Client action() Subject action() Proxy action() RealSubject delegate
  • 4. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Dynamic proxies ■ To easily implement proxies, Java 1.3 introduced the Dynamic Proxy API ■ A dynamic proxy requires – an instance of the Proxy class – a proxy interface • this is the interface that is implemented by the proxy class • interestingly, one proxy can implement multiple interfaces – each proxy instance has an InvocationHandler 4Proxy InvocationHandler delegates to IProxy implements ProxyHandler implements
  • 5. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. InvocationHandler ■ Each proxy instance has an InvocationHandler – The invocation handler determines how to treat messages that are sent to the proxy instance – When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke() method of its invocation handler
 
 Object invoke(Object proxy, Method m, Object[] args) 5 Proxy invoke(Object, Method, Object[]) : Object <<interface>> InvocationHandlerdelegates to
  • 6. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example: an InvocationHandler to trace method calls 6 public class TraceHandler implements InvocationHandler { private Object baseObject; // the real object the proxy delegates to public TraceHandler(Object base) { baseObject = base; } public Object invoke(Object proxy, Method m, Object[] args) { Object result = null; // result to be returned by the method try { System.out.println("before " + m.getName()); result = m.invoke(baseObject, args); System.out.println("after " + m.getName()); } catch (Exception e) {
 e.printStackTrace(); } return result; }
 }
  • 7. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Proxy class ■ Provides static methods for creating dynamic proxy classes and instances ■ Is also the superclass of all dynamic proxy classes created by those methods ■ To create a proxy for some class Foo
 InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); ■ or more simply:
 Foo f = (Foo) Proxy.
 newProxyInstance( Foo.class.getClassLoader(), new Class[] { Foo.class }, handler ); 7
  • 8. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example: a Proxy that traces method calls 8 public class Component1 implements IComponent { Color myColor; public Color getColor() { System.out.println("Inside the getColor() method of Component1."); return myColor; } public void setColor(Color color) { myColor = color; System.out.println("The color of component 1 has been set."); } } public interface IComponent { public Color getColor(); public void setColor(Color color); } interface shared by real object and proxy real object to which proxy will delegate
  • 9. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example: a Proxy that traces method calls 9 IComponent c1 = new Component1(new Color(0)); InvocationHandler th = new TraceHandler(c1); IComponent proxy = (IComponent) Proxy.newProxyInstance( c1.getClass().getClassLoader(),
 c1.getClass().getInterfaces(), th); /* standard call */ c1.getColor(); /* traced call */ proxy.getColor();
  • 10. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. How Java creates a proxy 10 Bibliography Examples: Tracing and Proxy Chaining. Java’s Dynamic Proxy. How Java Creates a Proxy. extends implements implements implements $IPoint InvocationHandlerIPoint Proxy Point TraceHandler Classes Interfaces p thpth - int x - int y + getX(): int + getY(): int + getX(): int + getY(): int + getX(): int + getY(): int - Object base + invoke(): Object - InvocationHandler i + invoke(): Object Generated on-the-fly
  • 11. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Advanced reflective features ■ Dynamic proxies – Proxy – InvocationHandler ■ Call stack introspection – Throwable – StackTraceElement ■ Instrumentation – java.lang.instrument ■ Conclusion 11
  • 12. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Call Stack Introspection ■ State introspection ■ Call stack ■ Reifying the call stack – Throwable – StackTraceElement ■ Examples: – printing the call stack – show warnings for unimplemented methods 12
  • 13. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. State Introspection 13 ■ Introspection is not only application structure introspection ■ Information about the program execution can be introspected as well – the execution state – the call stack ■ Each thread has a call stack consisting of stack frames ■ Call stack introspection allows a thread to examine its context – the execution trace and the current frame
  • 14. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Call Stack 1. package reflectionexample; 2. 3. public class Example { 4. 5. public static void m1() { 6. m2(); 7. } 8. 9. public static void m2() { 10. m3(); 11. } 12. 13. public static void m3() { 14. // do something 15. } 16. 17. public static void main(String[] args) { 18. m1(); 19. } 20. 21. } class: Example method: main line: 18 class: Example method: m1 line: 6 Call Stack: class: Example method: m2 line: 10 class: Example method: m3 line: 14 (m3)
  • 15. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Reifying the call stack : Throwable 15 ■ In Java there is no accessible CallStack meta-object ■ But... – When an instance of Throwable is created, the call stack is saved as an array of StackTraceElement – By writing: new Throwable().getStackTrace() – This gives us access to a representation of the call stack at the moment when Throwable was created. – The getStackTrace() method returns the current call stack as an array of StackTraceElement. • The first frame (position 0) is the current frame ■ Only introspection
  • 16. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 1: print the call stack 16 public class CallStackExample1 { public static void m1() { m2(); } public static void m2() { m3(); } public static void m3() { StackTraceElement[] stack = new Throwable().getStackTrace(); for (int i = 0; i < stack.length; i++) { System.out.println(stack[i]); } } public static void main(String[] args) { m1(); }
  • 17. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: show warnings for unimplemented methods ■ How to create an auxiliary method to be used as placeholder for unimplemented methods? – I have a method todo() remaining to be implemented – I provide the following dummy implementation – When calling that method todo() I want to get a warning: – as well as a warning message on the Console: Warning: reflectionexample.CallStackExample2.todo(CallStackExample2.java:8) () : this method remains to be implemented public static void todo() { toBeImplemented(); }
  • 18. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. 18 Example 2: show warnings for methods to be implemented public class CallStackExample2 { public static void todo() { toBeImplemented(); } public static void toBeImplemented() { // Get the stack element referring to the method calling this one StackTraceElement el = new Throwable().getStackTrace()[1]; // Show a dialog box with information on the method remaining to be implemented String msg = el.toString() + "() : this method remains to be implemented"; // Show this message in a dialog box JOptionPane.showMessageDialog(null, msg, "Erreur", JOptionPane.ERROR_MESSAGE); // Print this warning on the console System.err.println("Warning: " + msg); } public static void main(String[] args) { todo(); } }
  • 19. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Reifying the call stack : StackTraceElement ■ From a frame we can get: – getFileName() : the filename containing the execution point – getLineNumber() : the line number where the call occurs – getClassName() : the name of the class containing the
 execution point – getMethodName() : the name of the method containing the 
 execution point 19 “myPackage.Example.m3(Example.java:14)” StackTraceElement: class: Example method: m3 line: 14 filename: Example.java
  • 20. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Advanced reflective features ■ Dynamic proxies – Proxy – InvocationHandler ■ Call stack introspection – Throwable – StackTraceElement ■ Instrumentation – java.lang.instrument ■ Conclusion 20
  • 21. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Suppose we want to... 1. Instrument a Java program to print a message on the console whenever a class is loaded by the JVM 2. Instrument a Java program to print all messages being sent while the program is running 3. Replace the definition of a class at runtime – even for classes with currently active instances – for example, to change the behaviour of some messages understood by those instances 21 ... then Java instrumentation may be your answer
  • 22. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Java Instrumentation (goal) 22 ■ java.lang.instrument – Provides services that allow Java programming language agents to instruments programs running on the JVM. – This instrumentation is achieved by modifying byte-code. – Allows you to create agents, that run embedded in a JVM and intercept the classloading process, to • monitor the classloading process • modify the bytecode of classes ■ Can be combined with dedicated libraries for Java bytecode manipulation, like Javassist or BCEL.
  • 23. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Java Instrumentation (mechanics) 23 To implement an agent that intercepts classloading you need to define – a class implementing the premain method
 
 public static void premain(String agentArguments, 
 Instrumentation instrumentation) { ... } – a class implementing a transformer (which describes how the bytecode should be transformed)
 
 public class SomeTransformer implements ClassFileTransformer
 public byte[] transform(ClassLoader loader, 
 String className, Class redefiningClass,
 ProtectionDomain domain, byte[] bytes)
 throws IllegalClassFormatException { ... } – you can put both methods in a single class
  • 24. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Java Instrumentation (mechanics) 24 – The transform method receives information on the class to be loaded and can modify its bytecode.
 
 public byte[] transform(ClassLoader loader, 
 String className, Class redefiningClass,
 ProtectionDomain domain, byte[] bytes)
 • returns null if there's no modification, else returns the new bytecode • to modify the bytecode you can use a specialised library like Javassist
 – The premain method should add the transformer to the agent:
 
 public static void premain(String agentArguments, 
 Instrumentation instrumentation) {
 instrumentation.addTransformer(new SomeTransformer()); }

  • 25. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Java Instrumentation (mechanics) 25 – To plug the agent into the JVM and execute it, you need to put it inside a jar:
 jar cvfm MyAgent.jar ManifestFile.txt
 MyAgent.class SomeTransformer.class – The manifest file for this jar has to declare the premain class:
 Premain-Class: MyAgent
 If the agent modifies the bytecode, this also has to be declared in the manifest file:
 Can-Redefine-Classes: true – Finally, to instrument a Java program you need to add the javaagent parameter when you execute the JVM: > java -javaagent:MyAgent.jar MyProgram
  • 26. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Examples 1. Instrument a Java program to print a message on the console whenever a class is loaded by the JVM 2. Instrument a Java program to print all messages being sent while the program is running 3. Replace the definition of a class at runtime – even for classes with currently active instances – for example, to change the behaviour of some messages understood by those instances 26
  • 27. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 1: Instrument Java code 27 /** * Just prints a message to stdout before each Class is loaded * > java -javaagent:LogClassLoad.jar <the_Main_Class_to_execute> */ public class LogClassLoad implements ClassFileTransformer { public static void premain(String options, Instrumentation ins) { ins.addTransformer(new LogClassLoad()); } public byte[] transform(ClassLoader loader, String className, Class cBR, java.security.ProtectionDomain pD, byte[] classfileBuffer) throws IllegalClassFormatException { try { System.out.println("LOADING: " + className); } catch (Throwable exc) { System.err.println(exc); } return null; // For this first example no transformation is required : // we are only logging when classes are loaded } }
  • 29. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Examples 1. Instrument a Java program to print a message on the console whenever a class is loaded by the JVM 2. Instrument a Java program to print all messages being sent while the program is running 3. Replace the definition of a class at runtime – even for classes with currently active instances – for example, to change the behaviour of some messages understood by those instances 29
  • 30. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Print all messages 30 public class TraceMethodCall implements ClassFileTransformer { public static void premain(String options, Instrumentation ins) { ins.addTransformer(new TraceMethodCall()); } public byte[] transform(ClassLoader loader, String className, Class cBR, java.security.ProtectionDomain pD, byte[] classfileBuffer) throws IllegalClassFormatException { try { if(isSystemClass(className)) return null; ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get(className); CtMethod[] allmethods = cc.getMethods(); for(CtMethod method : allmethods) { try { method.insertBefore("TraceMethodCall.trace();"); } catch (Exception e) { } } return cc.toBytecode(); } catch (Throwable exc) { } return null; // No transformation required } for(CtMethod method : allmethods) { try { method.insertBefore("TraceMethodCall.trace();"); } catch (Exception e) { } import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod;
  • 31. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Print all messages 31 public class TraceMethodCall implements ClassFileTransformer { ... /** Check if a class is a system class, based on the package name. **/ public static boolean isSystemClass(String className) { ... } public static boolean isDottedSystemClass(String className) { ... } ... public static void trace() { Throwable thw = new Throwable(); if(thw.getStackTrace().length > 2) { StackTraceElement stackTo = thw.getStackTrace()[1]; StackTraceElement stackFrom = thw.getStackTrace()[2]; if(!isDottedSystemClass(stackFrom.getClassName())) { System.out.println(""" + stackFrom.getClassName() + "." 
 + stackFrom.getMethodName() + "" -> " + """ 
 + stackTo.getClassName() + "." + stackTo.getMethodName() + """); } } } }
  • 32. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Print all messages 32 package reflectionexample; public class CallStackExample0 { public static void m1() { m2(); } public static void m2() { m3(); } public static void m3() { } public static void main(String[] args) { m1(); } }
  • 33. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Examples 1. Instrument a Java program to print a message on the console whenever a class is loaded by the JVM 2. Instrument a Java program to print all messages being sent while the program is running 3. Replace the definition of a class at runtime – even for classes with currently active instances – for example, to change the behaviour of some messages understood by those instances 33
  • 34. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Replacing a class (goal) 34 /** * This modified class replaces the original class at run-time. * The modified class has the same name but is located in a subdirectory. * It is a clone of the original class where one method was changed. * Instances of this class will react differently to those messages. */ public class SwappedClass { public void message() { System.out.println("I am the MODIFIED SwapedClass"); } } /** * This is the original class that will be replaced by a modified copy at run-time. * The modified copy of this class is located in the "modif" subdirectory. */ public class SwappedClass { public void message() { System.out.println("I am the original SwapedClass"); } } original modifie
  • 35. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Replacing a class (mechanics) ■ to dynamically replace a class execute this code: 35 import java.lang.instrument.Instrumentation; public class SwapClass { private static Instrumentation instCopy; public static void premain(String options, Instrumentation inst) { instCopy = inst; } public static Instrumentation getInstrumentation() { return instCopy; } } SwapClass.getInstrumentation().redefineClasses(...)
  • 36. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Example 2: Replacing a class (code) 36 public class SwapTest { public static void main (String[] args) { try { // Create an instance of the class that will be modified SwappedClass swapped = new SwappedClass(); // Send a message to the instance; the original message should be displayed swapped.message(); // Now replace the class by a modified version // 1. read the class definition from file FileChannel fc = new FileInputStream(new File("modif/SwappedClass.class")).getChannel(); ByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int)fc.size()); byte[] classBuffer = new byte[buf.capacity()]; buf.get(classBuffer, 0, classBuffer.length); // 2. use instrumentation API to replace the old class’s definition by the new one SwapClass.getInstrumentation().redefineClasses( new ClassDefinition[] { new ClassDefinition(swapped.getClass(), classBuffer)}); // Send a message to the old instance; the MODIFIED message will be displayed swapped.message(); } catch (Exception e){ System.out.println(e); } } } SwapClass.getInstrumentation().redefineClasses( new ClassDefinition[] { new ClassDefinition(swapped.getClass(), classBuffer)});
  • 38. SINF2335:Prog.Paradigms: Theory,Pract.andApplic. Reflection in Java: Conclusions 38 ■ Benefits – reflection in Java opens up the structure and the execution trace of the program; – the reflection API is (relatively) simple and quite complete. ■ Drawbacks – reflection in Java is (mostly) limited to introspection; – there isn't a clear separation between base and meta- level; – reflection in Java has been proved inefficient