SlideShare a Scribd company logo
1 of 210
Download to read offline
Yann-Gaël Guéhéneuc
This work is licensed under a Creative
Commons Attribution-NonCommercial-
ShareAlike 3.0 Unported LicenseDépartement de génie informatique et de génie logiciel
On Reflection in OO
Programming Languages
yann-gael.gueheneuc@polytmtl.ca
Version 1.5.5
2014/04/30
2/210
Any questions/comments are welcome at
yann-gael.gueheneuc@polymtl.ca
The source code is available at
http://www.ptidej.net/tutorial/javareflection
3/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
4/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
5/210
Use of instanceof
public abstract class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal {
}
public class Expression {
public static String speak(final Animal anAnimal) {
final String sound;
if (anAnimal instanceof Dog) {
sound = "woof";
}
else if (anAnimal instanceof Cat) {
sound = "miaow";
}
else {
sound = "";
}
return sound;
}
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(Expression.speak(fido));
}
}
6/210
Use of instanceof
public abstract class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal {
}
public class Expression {
public static String speak(final Animal anAnimal) {
final String sound;
if (anAnimal instanceof Dog) {
sound = "woof";
}
else if (anAnimal instanceof Cat) {
sound = "miaow";
}
else {
sound = "";
}
return sound;
}
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(Expression.speak(fido));
}
}
Must test the type of
the object at run-time
7/210
Use of instanceof
public abstract class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal {
}
public class Expression {
public static String speak(final Animal anAnimal) {
final String sound;
if (anAnimal instanceof Dog) {
sound = "woof";
}
else if (anAnimal instanceof Cat) {
sound = "miaow";
}
else {
sound = "";
}
return sound;
}
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(Expression.speak(fido));
}
}
Must test the type of
the object at run-time
Breaks information
hiding of Cat and Dog
8/210
Use of instanceof
public abstract class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal {
}
public class Expression {
public static String speak(final Animal anAnimal) {
final String sound;
if (anAnimal instanceof Dog) {
sound = "woof";
}
else if (anAnimal instanceof Cat) {
sound = "miaow";
}
else {
sound = "";
}
return sound;
}
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(Expression.speak(fido));
}
}
Must test the type of
the object at run-time
Breaks information
hiding of Cat and Dog
Requires
special case
9/210
Use of instanceof
 Reason
– Must bypass the compiler and virtual machine’s
choice of the method to call
– Remember that overloading is resolved by the
static type of the argument, not its run-time
type (cf. Week 2)
10/210
Use of instanceof
 Problem
“Don't repeat yourself” (DRY): “Every piece of
knowledge must have a single, unambiguous,
authoritative representation within a system.”
—Andy Hunt and Dave Thomas
(in The Pragmatic Programmer)
11/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String speak() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String speak() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(fido.speak());
}
}
12/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String speak() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String speak() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(fido.speak());
}
}
13/210
Use of instanceof
public class Cat {
public String speak() {
return "miaow";
}
}
public class Dog {
public String speak() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
14/210
Use of instanceof
public class Cat {
public String speak() {
return "miaow";
}
}
public class Dog {
public String speak() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
Discover method of
object of unrelated
classes
15/210
Plugins
 Plugins are external, user-defined pieces of
code loaded, used, and unloaded to benefit
from their features only when needed
 Problem
– Closed-world assumption (at compile-time and
runtime) leads to the need for a mechanism to
perform dynamic loading
16/210
Serialisation
 Serialisation is the process of translating
data structures or object state into a format
that can be stored (file, network…)
 Problem
– Information hiding prevents access to the
internals of the data structures and to the
complete object states
17/210
Debugging/Profiling
 Debugging/profiling are the processes of
monitoring the execution of a program
– To understand its behaviour
– To measure its space and time complexity
 Problem
– Accessing the internals of objects and
controlling the program to collect relevant data
18/210
Patching
 Patching is the process of changing the
behaviour of a class or an object
– To modify its behaviour
– To add new behaviour
 Problem
– Modifying the behaviour at run-time without the
need to recompile and restart the program
19/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
20/210
Definition
 Reflection is the ability of a computer
program to examine and modify the
structure and behaviour of an object at
runtime
21/210
Definition
 Reflection is the ability of a computer
program to examine and modify the
structure and behaviour of an object at
runtime
Problem: inspect objects and change their behaviour at runtime
Solution: reflection
22/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String speak() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String speak() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
System.out.println(fido.speak());
}
}
23/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String miaow() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String bark() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
24/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String miaow() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String bark() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
Unrelated classes
25/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String miaow() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String bark() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
Unrelated classes
Choice at run-time
26/210
Use of instanceof
public abstract class Animal {
public abstract String speak();
}
public class Cat extends Animal {
@Override
public String miaow() {
return "miaow";
}
}
public class Dog extends Animal {
@Override
public String bark() {
return "woof";
}
}
public class Expression {
public static void main(final String[] args) {
final Dog fido = new Dog();
final Method[] method = Dog.class.getDeclaredMethods();
System.out.println(method[0].invoke(fido, new Object[0]));
}
}
Unrelated classes
Choice at run-time
27/210
Outline
 Problems
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
28/210
Context
 Reflection
– Ability of a computer program to examine and
modify the structure and behaviour of an object
at runtime
29/210
Context
 Reflection
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
30/210
Context
 Reflection
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
31/210
Context
 Reflection
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
32/210
Context
 Libraries
– Collections of data structures and algorithms
(possibly encapsulated in classes) used to
develop and run programs
 Frameworks
– Reusable sets of libraries, tools, and
conventions used to develop and run programs
33/210
Context
 Libraries
– Collections of data structures and algorithms
(possibly encapsulated in classes) used to
develop and run programs
 Frameworks
– Reusable sets of libraries, tools, and
conventions used to develop and run programs
Problem: connection between clients and libraries/frameworks
Solution: linking, forking, subclassing, IPC, and dynamic loading
34/210
Interconnections
 Clients–Libraries/Frameworks
– Linking
– Forking
– Subclassing
– Inter-process communication
– Dynamic loading/invoking
35/210
Interconnections
 Linking
(Contrast with virtual machines)
– Typically C/C++
– Several object files (.o)
– One executable (.exe)
36/210
Interconnections
 Forking
– Typical in most
languages
– Process duplication
• Is a real duplication
• Creates a new OS
process
final StringBuffer commandLine = new StringBuffer();
commandLine.append("..DOTbindotty ");
commandLine.append(aFilePath);
final Process process =
Runtime.getRuntime().exec(commandLine.toString());
final OutputMonitor errorStreamMonitor =
new OutputMonitor(...,process.getErrorStream(),...);
errorStreamMonitor.start();
final OutputMonitor inputStreamMonitor =
new OutputMonitor(...,process.getInputStream(),...);
inputStreamMonitor.start();
try {
process.waitFor();
}
catch (final InterruptedException ie) {
ie.printStackTrace(
Output.getInstance().errorOutput());
}
if (process.exitValue() != 0) {
...
}
37/210
Interconnections
 IPC
– Typical in most languages
– Use remote procedure calls
– Use well-defined protocols
• COM
• CORBA
• XML-RPC
– Web services
38/210
Interconnections
package kr.ac.yonsei.cse3009.rpc;
import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
public class Client {
public static void main(final String[] args)
throws Exception {
final XmlRpcClientConfigImpl config =
new XmlRpcClientConfigImpl();
config.setServerURL(
new URL("http://127.0.0.1:8080/xmlrpc"));
final XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
final Object[] params = new Object[] {
new Integer(33), new Integer(9) };
final Integer result = (Integer)
client.execute("Calculator.add", params);
System.out.println(result);
}
}
package kr.ac.yonsei.cse3009.rpc;
import org.apache.xmlrpc.server.PropertyHandlerMapping;
import org.apache.xmlrpc.server.XmlRpcServer;
import org.apache.xmlrpc.webserver.WebServer;
public class Server {
public static void main(final String[] args)
throws Exception {
final WebServer webServer = new WebServer(8080);
final XmlRpcServer xmlRpcServer =
webServer.getXmlRpcServer();
final PropertyHandlerMapping phm =
new PropertyHandlerMapping();
phm.addHandler("Calculator", Calculator.class);
xmlRpcServer.setHandlerMapping(phm);
webServer.start();
}
}
package kr.ac.yonsei.cse3009.rpc;
public class Calculator {
public int add(final int i1, final int i2) {
return i1 + i2;
}
public int sub(final int i1, final int i2) {
return i1 - i2;
}
}
39/210
Interconnections
 Subclassing
– Typical in most object-
oriented languages
– Structural, static relation
public class OutputMonitor extends Thread {
...
public OutputMonitor(...) {
this.setName(threadName);
this.setPriority(Thread.MAX_PRIORITY);
...
}
public void run() {
try {
int value = 0;
byte[] bytes;
char lastWrittenChar;
while ((value = this.inputStream.read()) > 0) {
synchronized (System.err) {
synchronized (System.out) {
if (value != 13 && value != 10) {
lastWrittenChar = (char) value;
...
}}
}
}
catch (final IOException ioe) {
...
40/210
Interconnections
 Subclassing
– Hooks and templates
• Hot spots = hooks
• Frozen spots = templates
– Hooks are typically abstract methods
– Templates typically use hooks
41/210
Interconnections
 Subclassing
– Hooks and templates
• JUnit
42/210
Interconnections
 Template
 Hooks
public abstract class TestCase
extends Assert implements Test {
public void runBare() throws Throwable {
setUp();
try {
runTest();
}
finally {
tearDown();
}
}
protected void setUp() throws Exception {
}
protected void tearDown() throws Exception {
}
...
}
43/210
Interconnections
 Subclassing
– Heavily used in object-oriented programs
– Heavily used in design patterns
(Only Singleton does not explicitly use subclassing)
• Abstract Factory
• Composite
• Decorator
• Observer
• Visitor
44/210
Interconnections
 Dynamic loading
– In different programming languages (but not all),
it is the possibility to load, use, and unload a
piece of code at runtime
– In Java, it is the possibility to load and unload
a class and to choose and invoke its methods
(and to access its fields…) at runtime
45/210
Interconnections
 Poor man’s profiler
– Calls the main() method of a class whose name is
given at runtime, by the user
– Displays the time spent in the called method
public final class PoorManProfiler {
public static void main(final String[] args) {
try {
final Class toBeRun = Class.forName(args[0]);
final Method mainMethod =
toBeRun.getMethod("main", new Class[] { String[].class });
final long startTime = System.currentTimeMillis();
mainMethod.invoke(null, new Object[] { new String[0] });
final long endTime = System.currentTimeMillis();
System.out.println();
System.out.println(endTime - startTime);
}
catch (final Exception e) {
e.printStackTrace();
}
}
}
46/210
Return to Reflection
 Reflection enables dynamic loading
– Reflection  dynamic loading
– Dynamic loading  Reflection
• Think of dynamically-loaded shared libraries in
C-based operating systems, such as AmigaOS,
Linux, UN*X, Windows…

47/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
48/210
Scenarios
 Original problem
– Different interpretations
– Different contexts
 Four scenarios
 Three programming languages
Problem: inspect objects and change their behaviour at runtime
Solution: reflection
49/210
Scenarios
 Scenario 1: invoke an arbitrary method on
an object (see the problems with
instanceof and plugins)
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
50/210
Scenarios
 Scenario 2: access the complete (including
private) state of an object (see the problem
with serialisation)
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
51/210
Scenarios
 Scenario 3: count the number of instances of
a class created at runtime (see the problem
with debugging/profiling)
– Given a class C
– Record the number of its instances ever created
– Report this number when the program ends
52/210
Scenarios
 Scenario 4: patch the method of a class to
change its behaviour (see the problem with
patching)
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
53/210
Scenarios
Java
Smalltalk
C++
54/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
public class C {
private int i;
public C(final int anInt) {
this.i = anInt;
}
public void foo(final String s) {
System.out.print(s);
System.out.println(this.i);
}
}
55/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
Identify all the methods available on o
foo
getClass
hashCode
equals
toString
notify
notifyAll
wait
wait
wait
Invoke a method using its name foo
This is foo: 42
56/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
final C o = new C(42);
System.out.println("Identify all the methods available on o");
final Class<?> classOfO = o.getClass();
final Method[] methodsOfC = classOfO.getMethods();
for (int i = 0; i < methodsOfC.length; i++) {
final Method method = methodsOfC[i];
System.out.print('t');
System.out.println(method.getName());
}
System.out.println("Invoke a method using its name foo");
final Method fooMethod = classOfO.getMethod("foo", new Class[] { String.class });
fooMethod.invoke(o, new Object[] { "tThis is foo: " });
57/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
Identify all the methods available on o
foo
getClass
hashCode
equals
toString
notify
notifyAll
wait
wait
wait
Invoke a method using its name foo
This is foo: 42
58/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
public class C {
private int i;
public C() {
this(-1);
}
public C(final int anInt) {
this.i = anInt;
}
public void foo(final String s) {
System.out.print(s);
System.out.println(this.i);
}
}
59/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
Save on disk the complete state of o
i = 42
Restore from disk the object o at a later time
This is foo on o2: 43
60/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
final C o1 = new C(42);
System.out.println("Save on disk the complete state of o");
final Class<?> classOfO = o1.getClass();
final Field[] fieldsOfC = classOfO.getDeclaredFields();
for (int i = 0; i < fieldsOfC.length; i++) {
final Field field = fieldsOfC[i];
field.setAccessible(true);
System.out.print('t' + field.getName());
System.out.println(" = " + field.getInt(o1));
}
System.out.println("Restore from disk the object o at a later time");
final C o2 = (C) classOfO.newInstance();
final Field fieldiOfC = classOfO.getDeclaredField("i");
fieldiOfC.setAccessible(true);
fieldiOfC.setInt(o2, 43);
o2.foo("tThis is foo on o2: ");
61/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
Save on disk the complete state of o
i = 42
Restore from disk the object o at a later time
This is foo on o2: 43
62/210
Scenarios
 Scenario 3:
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
public class C {
private static int numberOfInstances;
public static int getNumberOfInstances() {
return C.numberOfInstances;
}
private int i;
public C() {
this(-1);
}
public C(final int anInt) {
C.numberOfInstances++;
this.i = anInt;
}
public void foo(final String s) {
System.out.print(s);
System.out.println(this.i);
}
}
63/210
Scenarios
 Scenario 3:
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@150bd4d
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@1bc4459
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@12b6651
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
64/210
Scenarios
 Scenario 3:
public class Main {
public static void main(final String[] args) {
final C o1 = new C(42);
final C o2 = new C(1);
final C o3 = new C(100);
System.out.println(o1 + "n" + o2 + 'n' + o3);
System.out.println(C.getNumberOfInstances());
}
}
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
65/210
Scenarios
 Scenario 3:
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@150bd4d
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@1bc4459
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@12b6651
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
66/210
Scenarios
 Scenario 3:
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@150bd4d
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@1bc4459
kr.ac.yonsei.it.cse3009.reflection.scenario3.C@12b6651
3
To fulfill this scenario,
we must modify C
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
67/210
Scenarios
 Class Class is a metaclass
– It describes other classes
 Class Method is a class
– It describes methods
 Class Field is a class
– It describes fields
68/210
Scenarios
 Class Class is a metaclass
– It allows to reify classes
 Class Method is a class
– It allows to reify methods, these language
constructs become first-class entities
 Class Field is a class
– It allows to reify fields , these language
constructs become first-class entities
69/210
Scenarios
 Class Class is a metaclass
– It allows to reify classes
 Class Method is a class
– It allows to reify methods, these language
constructs become first-class entities
 Class Field is a class
– It allows to reify fields, these language
constructs become first-class entities
70/210
Scenarios
 Class Class is a metaclass
– It allows to reify classes
 Class Method is a class
– It allows to reify methods, these language
constructs become first-class entities
 Class Field is a class
– It allows to reify fields, these language
constructs become first-class entities
Reification is the process of
making available an implicit
construct of a language
71/210
Scenarios
 We never modified class Class
– We only used it to obtain the methods and fields
declared by particular classes, e.g., C
 We used static fields and methods to count
number of instances
72/210
Scenarios
 Scenario 4:
public interface I {
public void foo(final String s);
}
public class C implements I {
private int i;
public C(final int anInt) {
this.i = anInt;
}
public void foo(final String s) {
System.out.print(s);
System.out.println(this.i);
}
}
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
73/210
Scenarios
 Scenario 4:
This is o: 42
Forwarding method: "foo"
Original arguments: "This is o: "
New arguments: "THIS IS O: "
THIS IS O: 42
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
74/210
Scenarios
 Scenario 4:
final I o = new C(42);
o.foo("This is o: ");
final InvocationHandler handler = new InvokationHandler(o);
final I proxy =
(I) Proxy.newProxyInstance(
I.class.getClassLoader(),
new Class[] { I.class },
handler);
Assert.assertTrue(proxy instanceof I);
Assert.assertFalse(proxy instanceof C);
Assert.assertTrue(proxy.equals(o));
proxy.foo("This is o: ");
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
75/210
Scenarios
Scenario4:
public class InvokationHandler implements InvocationHandler {
private final I i;
public InvokationHandler(final I aConcreteImplementationOfI) {
this.i = aConcreteImplementationOfI;
}
public Object invoke(
final Object aProxy,
final Method aMethod,
final Object[] someArgs) throws Throwable {
if (aMethod.getName().equals("foo")) {
final String arg = (String) someArgs[0];
final String newArg = arg.toUpperCase();
System.out.print("Forwarding method: "");
System.out.print(aMethod.getName());
System.out.print(""ntOriginal arguments: "");
System.out.print(arg);
System.out.print(""ntNew arguments: "");
System.out.print(newArg);
System.out.println('"');
this.i.foo(newArg);
return null;
}
else {
return aMethod.invoke(this.i, someArgs);
}
}
}
–Givenanobjecto,instanceofC
–WithoutchangingoorC
–Changethebehaviourofo.foo()
76/210
Scenarios
 Scenario 4:
final I o = new C(42);
o.foo("This is o: ");
final InvocationHandler handler = new InvokationHandler(o);
final I proxy =
(I) Proxy.newProxyInstance(
I.class.getClassLoader(),
new Class[] { I.class },
handler);
Assert.assertTrue(proxy instanceof I);
Assert.assertFalse(proxy instanceof C);
Assert.assertTrue(proxy.equals(o));
proxy.foo("This is o: ");
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
77/210
Scenarios
 Scenario 4:
final I o = new C(42);
o.foo("This is o: ");
final InvocationHandler handler = new InvokationHandler(o);
final I proxy =
(I) Proxy.newProxyInstance(
I.class.getClassLoader(),
new Class[] { I.class },
handler);
Assert.assertTrue(proxy instanceof I);
Assert.assertFalse(proxy instanceof C);
Assert.assertTrue(proxy.equals(o));
proxy.foo("This is o: ");
Properties of the
proxy ensured by
the Java VM
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
78/210
Scenarios
 Smalltalk
– Everything is an object
79/210
Scenarios
 Smalltalk
– Everything is an object
– Everything is an object, really
static
80/210
Scenarios
 Smalltalk
– SmalltalkImage is the class that “represent[s]
the current image and runtime environment,
including system organization, the virtual
machine, object memory, plugins, and source
files. [Its] instance variable #globals is a
reference to the system dictionary of global
variables and class names. [Its] singleton
instance is called Smalltalk.”
81/210
Scenarios
 Smalltalk
– Object is “the root class for almost all of the
other classes in the class hierarchy. […] Class
Object provides default behavior common to
all normal objects, such as access, copying,
comparison, error handling, message sending,
and reflection. Also utility messages that all
objects should respond to are defined here.”
82/210
Scenarios
 Smalltalk
– Class “[adds] instance-specific behavior to
various class-describing objects in the system.
This typically includes messages for initializing
class variables and instance creation messages
particular to a class. There is only one instance
of a particular Metaclass, namely the class
which is being described.”
83/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
84/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
Identify all the methods available on o
an IdentitySet(#handles: #longPrintString #actionMap
#hasContentsInExplorer [...] #foo: [...] #i: [...]
#creationStamp)
Invoke a method using its name foo
This is foo: 42
85/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
|o|
o := C newWithi: 42.
Transcript show: 'Identify all the methods available on o' ; cr.
Transcript show: C allSelectors ; cr.
Transcript show: 'Invoke a method using its name foo' ; cr.
(C compiledMethodAt: #foo:) valueWithReceiver: o arguments: #('This is foo: ').
86/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
|o|
o := C newWithi: 42.
Transcript show: 'Identify all the methods available on o' ; cr.
Transcript show: C allSelectors ; cr.
Transcript show: 'Invoke a method using its name foo' ; cr.
(C compiledMethodAt: #foo:) valueWithReceiver: o arguments: #('This is foo: ').
Simple and straightforward
87/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
88/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
Save on disk the complete state of o
42
Restore from disk the object o at a later time
This is foo on o2: 43
89/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
|o1 o2|
o1 := C newWithi: 42.
Transcript show: 'Save on disk the complete state of o' ; cr.
Transcript show: (o1 instVarAt: 1) ; cr.
Transcript show: 'Restore from disk the object o at a later time' ; cr.
o2 := C new.
o2 instVarNamed: 'i' put: 43.
o2 foo: 'This is foo on o2: '.
90/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
|o1 o2|
o1 := C newWithi: 42.
Transcript show: 'Save on disk the complete state of o' ; cr.
Transcript show: (o1 instVarAt: 1) ; cr.
Transcript show: 'Restore from disk the object o at a later time' ; cr.
o2 := C new.
o2 instVarNamed: 'i' put: 43.
o2 foo: 'This is foo on o2: '.
Again, simple and straightforward
91/210
Scenarios
 Scenario 2:
– Pharo (a recent implementation of Smalltalk)
provides is a general object serialiser that can
serialise any object
– Uses reflection to implement these methods!
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
1@2 serializeToFileNamed: 'hello.fuel'.
FLMaterializer materializeFromFileNamed: 'hello.fuel'
Thanks to Marcus Denker for pointing out these helper methods
92/210
Scenarios
 Scenario 3:
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: 'NumberOfInstances'
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
93/210
Scenarios
 Scenario 3:
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: 'NumberOfInstances'
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
Only difference with
Scenarios 1 and 2
94/210
Scenarios
 Scenario 3:
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
95/210
Scenarios
 Scenario 3:
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
Same as Scenarios 1 and 2
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
96/210
Scenarios
 Scenario 3:
C class compile: 'initialize
NumberOfInstances := 0.'.
C class compile: 'new
NumberOfInstances := NumberOfInstances + 1.
^ self basicNew initialize.'.
C class compile: 'numberOfInstances
^ NumberOfInstances.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
97/210
Scenarios
 Scenario 3:
C class compile: 'initialize
NumberOfInstances := 0.'.
C class compile: 'new
NumberOfInstances := NumberOfInstances + 1.
^ self basicNew initialize.'.
C class compile: 'numberOfInstances
^ NumberOfInstances.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
“Write access” to the metaclass
98/210
Scenarios
 Scenario 3:
|o1 o2 o3|
C initialize.
o1 := C newWithi: 42.
o2 := C newWithi: 1.
o3 := C newWithi: 100.
Transcript show: o1 ; show: ' ' ; show: o2 ; show: ' ' ; show: o3 ; cr.
Transcript show: C numberOfInstances.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
99/210
Scenarios
 Scenario 3:
a C a C a C
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
100/210
Scenarios
 Scenario 3:
a C a C a C
3
To fulfill this
scenario, we modified
C class not C
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
101/210
Scenarios
 Scenario 3:
In Smalltalk, each class has one anonymous
meta-class, which can be modified
• Adding new variables and methods which are thus
class variables and class methods
• These methods apply on the class, these fields
belong to the class (thus unique)
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
102/210
Scenarios
 Scenario 3:
– What about a subclass D of C?
– How would its instances be counted?
a C a C a C
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
Thanks to Christophe Dony for suggesting this use of class vs. class instance variables
103/210
Scenarios
 Scenario 3:
– In C++ and Java: static = global
• The class variables is shared by all the instances of
its declaring class… and its subclasses!
final D o4 = new D();
// Eclipse advises to use C to call getNumberOfInstances().
System.out.println(o4);
System.out.println(D.getNumberOfInstances());
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
104/210
Scenarios
 Scenario 3:
– In Smalltalk: class vs. class instance
• Class variable vs. class instance variable
– A class variable is shared by all the instance of the
class and all the instances of its subclasses
– A class instance variable is unique to each class,
inherited from the super-class, like instance variables
C class instanceVariableNames:
'IndividualClassNumberOfInstances'
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
105/210
Scenarios
 Scenario 3:
– In Smalltalk: class vs. class instance
C subclass: #D
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Ptidej'.
D class compile: 'initialize
IndividualClassNumberOfInstances := 0.'.
D class compile: 'new
NumberOfInstances := NumberOfInstances + 1.
IndividualClassNumberOfInstances := IndividualClassNumberOfInstances + 1.
^ self basicNew initialize.'.
D class compile: 'numberOfInstances
^ NumberOfInstances.'.
D class compile: 'individualClassNumberOfInstances
^ IndividualClassNumberOfInstances.'.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
106/210
Scenarios
 Scenario 3:
– In Smalltalk: class vs. class instance
| o4 |
D initialize.
o4 := D new.
Transcript show: o4 ; cr.
Transcript show: C numberOfInstances ; cr.
Transcript show: D numberOfInstances ; cr.
Transcript show: D individualClassNumberOfInstances ; cr.
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
a D
4
4
1
107/210
Scenarios
 Scenario 3:
– In Java: the JVM contains the world
• Possible to connect to a JVM using the Java Debug
Interface of the Java Platform Debug Architecture
• Possible to reify the classes existing in the remote
JVM and to obtain their instances
com.sun.jdi.ReferenceType.instances(long)
• Special feature of the JVM, “outside” of the normal
constructs of the language
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
http://stackoverflow.com/questions/1947122/
is-there-a-simple-way-of-obtaining-all-object-instances-of-a-specific-class-in-j/1947200#1947200
108/210
Scenarios
 Scenario 3:
– In Smalltalk: the image contains the world
• Possible to ask it all the instances of a particular class
or all the instances currently in memory
Transcript show: (C allInstances size).
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
Thanks to Marcus Denker for pointing out this solution
109/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
110/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
This is o: 42
Intercepting message send: foo:
Original arguments: This is o:
New arguments: THIS IS O:
THIS IS O: 42
111/210
Scenarios
 Scenario 4:
Several choices
• ObjectWrappers: http://magaloma.seasidehosting.st/
Kernel#ObjectTracer
• MethodWrappers: http://pharo.gforge.inria.fr/
PBE1/PBE1ch15.html
• Reflectivity: http://scg.unibe.ch/Research/Reflectivity
• …
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
112/210
Scenarios
 Scenario 4:
Several choices
• ObjectWrappers: http://magaloma.seasidehosting.st/
Kernel#ObjectTracer
• MethodWrappers: http://pharo.gforge.inria.fr/
PBE1/PBE1ch15.html
• Reflectivity: http://scg.unibe.ch/Research/Reflectivity
• …
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
113/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
| o aWrapper |
o := C newWithi: 42.
o foo: 'This is o: '.
aWrapper := WrapperForC on: o.
"o become: aWrapper."
aWrapper foo: 'This is o: '.
aWrapper xxxUnTrace.
114/210
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
ObjectTracer subclass: #WrapperForC
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
WrapperForC compile: 'doesNotUnderstand: aMessage
"Intercept the selector foo:"
| sel arg newArg |
sel := aMessage selector.
sel = ''foo:'' ifTrue: [
arg := (aMessage arguments) at: 1.
newArg := arg asUppercase.
Transcript show: ''Intercepting message send: '' ; show: sel ; cr.
Transcript tab ; show: ''Original arguments: '' ; show: arg ; cr.
Transcript tab ; show: ''New arguments: '' ; show: newArg ; cr.
aMessage argument: newArg.
aMessage sendTo: (self xxxViewedObject)
]
ifFalse: [
"Transcript show: aMessage."
]'.
115/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
This is o: 42
Intercepting message send: foo:
Original arguments: This is o:
New arguments: THIS IS O:
THIS IS O: 42
| o aWrapper |
o := C newWithi: 42.
o foo: 'This is o: '.
aWrapper := WrapperForC on: o.
"o become: aWrapper."
aWrapper foo: 'This is o: '.
aWrapper xxxUnTrace.
116/210
Scenarios
 Scenario 4:
– We created the class WrappedForC that does
not understand many messages (as subclass
of ProtoObject)
– We wrapped an instance of WrappedForC
around o and use doesNotUnderstand: to
proxy messages
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
117/210
Scenarios
 Scenario 4:
– We created the class WrappedForC that does
not understand many messages (as subclass
of ProtoObject)
– We wrapped an instance of WrappedForC
around o and use doesNotUnderstand: to
proxy messages
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
118/210
Scenarios
 Scenario 4:
Several choices
• ObjectWrappers: http://magaloma.seasidehosting.st/
Kernel#ObjectTracer
• MethodWrappers: http://pharo.gforge.inria.fr/
PBE1/PBE1ch15.html
• Reflectivity: http://scg.unibe.ch/Research/Reflectivity
• …
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
119/210
Scenarios
 Reflectivity
– Marcus Denker, RMOD Team,
INRIA Lille, and others
– Extensions to the standard reflection features of
Smalltalk (both structural and behavioural)
• Structural reflection is extended by sub-method
reflection: method bodies are first-class
• Behavioural reflection is provided by Geppetto, an
implementation of Partial Behavioural Reflection
120/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
Object subclass: #C
instanceVariableNames: 'i'
classVariableNames: ''
poolDictionaries: ''
category: 'CSE3009'.
C class compile: 'newWithi: anInt
^(self new) i: anInt ; yourself.'.
C compile: 'foo: aText
Transcript show: aText.
Transcript show: i.
Transcript cr.'.
C compile: 'i: anInt
i := anInt.'.
121/210
Scenarios
 Scenario 4:
– Sub-method reflection
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
nodes := (C>>#foo:) sends select: [:each |
((each selector ~= #show:)
or: (each arguments) size ~= 1)
ifTrue: [ false ]
ifFalse: [ (each arguments at: 1) name = 'aText'. ].
].
122/210
Scenarios
 Scenario 4:
– Meta-object
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
gpLink := GPLink metaObject: [:arg1 :node |
| newArg |
newArg := arg1 asUppercase.
Transcript show: 'Intercepting message send: '.
Transcript show: node ; cr.
Transcript tab ; show: 'Original arguments: '.
Transcript show: arg1 ; cr.
Transcript tab ; show: 'New arguments: '.
Transcript show: newArg ; cr.
Transcript show: newArg.
].
gpLink control: #instead.
123/210
Scenarios
 Scenario 4:
– Linking
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
o := C newWithi: 42.
o foo: 'This is o: '.
nodes do: [:node |
node link: gpLink].
o foo: 'This is o: '.
gpLink uninstall.
This is o: 42
Intercepting message send: foo:
Original arguments: This is o:
New arguments: THIS IS O:
THIS IS O: 42
124/210
Scenarios
 Scenarios 1, 2, 3, and 4
More difficult to implement “as is”
• http://stackoverflow.com/questions/359237/why-does-
c-not-have-reflection
• http://www.open-std.org/jtc1/sc22/wg21/docs/papers/
2005/n1751.html
125/210
Scenarios
 Scenarios 1, 2, 3, and 4
Third-party solutions
• Mirror: http://kifri.fri.uniza.sk/~chochlik/mirror-
lib/html/index.html#introduction
• VisualStudio.NET: http://msdn.microsoft.com/en-
us/library/y0114hz2%28v=vs.110%29.aspx
• …
126/210
Scenarios
 Scenarios 1, 2, 3, and 4
Third-party solutions
• Mirror: http://kifri.fri.uniza.sk/~chochlik/mirror-
lib/html/index.html#introduction
• VisualStudio.NET: http://msdn.microsoft.com/en-
us/library/y0114hz2%28v=vs.110%29.aspx
• …
127/210
Scenarios
 Mirror
– Matúš Chochlík, University of Žilina,
Žilina, Slovakia
“[C]ompile-time and run-time meta-data
describing C++ constructs like namespaces,
types typedef-ined types, enums, classes
with their base classes, member variables,
constructors, member functions, etc.”
128/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
namespace cse3009 {
class C {
private:
int i;
public:
C(const int _i) : i(_i) {
}
int get_i(void) const {
return this->i;
}
void set_i(const int _i) {
this->i = _i;
}
void foo(const std::string _s) const {
std::cout << _s << this->i << std::endl;
}
};
}
129/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
Identify all the methods available on o
(The type of o is cse3009::C)
cse3009::C::i
cse3009::C::foo
Invoke a method using its name foo
This is foo: 42
130/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
int main(void) {
cse3009::C * o = new cse3009::C(42);
std::cout << "Identify all the methods available on o" << std::endl;
identify_members(o);
std::cout << "Invoke a method using its name foo" << std::endl;
invoke_member_function(o);
return 0;
}
131/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
template<typename O>
void identify_members(O * _o) {
using namespace mirror;
typedef MIRRORED_CLASS(O) meta_Class;
std::cout << "t(The type of o is " << meta_Class::full_name()
<< ")" << std::endl;
std::cout << "t";
mp::for_each_ii< all_member_variables<meta_Class> >(info_printer());
std::cout << std::endl << "t";
mp::for_each_ii< member_functions<meta_Class> >(info_printer());
std::cout << std::endl;
}
132/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
template<typename O>
void invoke_member_function(O * _o) {
using namespace mirror;
typedef MIRRORED_CLASS(cse3009::C) meta_Class;
typedef mp::at_c<overloads<
mp::at_c<member_functions<meta_Class>, 0>::type>, 0>::type
meta_foo;
my_invoker_maker::invoker<meta_foo>::type invoker(
std::string("tThis is foo: "));
invoker.call_on(*_o);
}
133/210
Scenarios
 Mirror
– Provides essentially the same concepts and
features as java.lang.reflect of Java
– Uses templates and (manual) registration to
collect metadata that does not exist unless
manually created through macro preprocessing
134/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
MIRROR_REG_BEGIN
MIRROR_QREG_GLOBAL_SCOPE_NAMESPACE(std)
MIRROR_REG_CLASS_BEGIN(struct, std, string)
MIRROR_REG_CLASS_END
MIRROR_QREG_GLOBAL_SCOPE_NAMESPACE(cse3009)
MIRROR_REG_CLASS_BEGIN(class, cse3009, C)
MIRROR_REG_CLASS_MEM_VARS_BEGIN
MIRROR_REG_CLASS_MEM_VAR_GET_SET(
private, _, int, i, _.get_i(), _.set_i(_i))
MIRROR_REG_CLASS_MEM_VARS_END
MIRROR_REG_MEM_FUNCTIONS_BEGIN
MIRROR_REG_MEM_OVLD_FUNC_BEGIN(foo)
MIRROR_REG_MEM_FUNCTION_BEGIN(public, _, void, foo, 1)
MIRROR_REG_MEM_FUNCTION_PARAM(std::string, _s)
MIRROR_REG_MEM_FUNCTION_END(1, _)
MIRROR_REG_MEM_OVLD_FUNC_END(foo)
MIRROR_REG_MEM_FUNCTIONS_END
MIRROR_REG_CLASS_END
MIRROR_REG_END
135/210
Scenarios
 Scenario 1:
– Given a class C
– Given an object o, instance of C
– Identify all the methods available on o
– Invoke a method using its name foo
template<class Unused>
struct my_manufacturer<std::string, Unused> {
const std::string s;
template<class ConstructionInfo>
inline my_manufacturer(const std::string _s,
const ConstructionInfo construction_info) : s(_s) {
}
void finish(std::string) const {
}
inline std::string operator()(void) const {
return s;
}
};
typedef mirror::invoker_maker<my_manufacturer, mirror::default_fact_suppliers,
my_enumerator, void> my_invoker_maker;
136/210
Scenarios
 Mirror
– Uses complex code that can be easily and
advantageously hidden in libraries
– Will possibly become part of Boost and the
standard reflection library for C++
• http://kifri.fri.uniza.sk/~chochlik/jtc1_sc22_wg21/
std_cpp_refl-latest.pdf
137/210
Scenarios
 Scenario 2:
namespace cse3009 {
class C {
private:
int i;
public:
C(const int _i) : i(_i) {
}
int get_i(void) const {
return this->i;
}
void set_i(const int _i) {
this->i = _i;
}
void foo(const std::string _s) const {
std::cout << _s << this->i << std::endl;
}
};
}
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
138/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
Save on disk the complete state of o
(The type of o is cse3009::C)
cse3009::C::i = 42
Restore from disk the object o at a later time
43
139/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
int main(void) {
cse3009::C * o = new cse3009::C(42);
std::cout << "Save on disk the complete state of o" << std::endl;
save_on_disk(o);
std::cout << "Restore from disk the object o at a later time" << std::endl;
restore_from_disk<cse3009::C>();
return 0;
}
140/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<typename O>
void save_on_disk(O * _o) {
using namespace mirror;
typedef MIRRORED_CLASS(O)meta_Class;
std::cout << "t(The type of o is " <<
meta_Class::full_name() << ")" << std::endl << "t";
mp::for_each_ii<all_member_variables<meta_Class>>(
info_printer_variables<O>(*_o));
std::cout << std::endl;
}
141/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<class O>
struct info_printer_variables {
O o;
inline info_printer_variables(O _o) : o(_o) {
}
template<class IterInfo>
void operator()(IterInfo) {
using namespace mirror;
std::cout << IterInfo::type::full_name()
<< " = " << IterInfo::type::get(o);
if (!IterInfo::is_last::value)
std::cout << ", ";
}
};
142/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<class O>
struct info_printer_variables {
O o;
inline info_printer_variables(O _o) : o(_o) {
}
template<class IterInfo>
void operator()(IterInfo) {
using namespace mirror;
std::cout << IterInfo::type::full_name()
<< " = " << IterInfo::type::get(o);
if (!IterInfo::is_last::value)
std::cout << ", ";
}
};
Get the value of reflected variable
143/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<typename O>
void restore_from_disk(void) {
using namespace mirror;
typedef typename my_factory_maker::factory<O>::type my_factory_type;
my_factory_type my_factory(43);
O o(my_factory());
std::cout << "t" << o.get_i() << std::endl;
}
144/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
typedef mirror::factory_maker<
my_manufacturer,
mirror::default_fact_suppliers,
my_enumerator,
void> my_factory_maker;
145/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
typedef mirror::factory_maker<
my_manufacturer,
mirror::default_fact_suppliers,
my_enumerator,
void> my_factory_maker;
Factory generating instances
of (possibly) different types
146/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<class Unused>
struct my_manufacturer<void, Unused> {
template<typename Context>
my_manufacturer(int _value, Context) { }
void finish(int) { }
template<class ConstructionInfo>
inline int add_constructor(
int _value, ConstructionInfo) const {
return _value;
}
inline int index(void) {
return 0;
}
};
147/210
Scenarios
 Scenario 2:
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
template<class Unused>
struct my_manufacturer<void, Unused> {
template<typename Context>
my_manufacturer(int _value, Context) { }
void finish(int) { }
template<class ConstructionInfo>
inline int add_constructor(
int _value, ConstructionInfo) const {
return _value;
}
inline int index(void) {
return 0;
}
};
To pass on to
the constructor
148/210
template<class Product, typename IsEnum>
struct my_base_manufacturer {
Product x;
struct constr_param_name_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << ", ";
std::cout << IterInfo::type::base_name();
}
};
struct constr_context_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << "::";
std::cout << IterInfo::type::base_name();
}
};
template<class ConstructionInfo>
my_base_manufacturer(int tabs,
ConstructionInfo construction_info,
const Product& _x) : x(tabs) { }
void finish(int) {
}
inline Product operator()(void) {
return x;
}
};
template<class Product, class Unused>
struct my_enumerator :
my_base_manufacturer<Product, std::true_type> {
template<class ConstructionInfo>
inline my_enumerator(int tabs,
ConstructionInfo construction_info) :
my_base_manufacturer<Product, std::true_type>(
tabs, construction_info, Product()) { }
void finish(int) { }
inline Product operator()(void) {
return NULL;
}
};
template<class Product, class Unused>
struct my_manufacturer {
typedef typename mirror::factory_maker<
my_manufacturer,
mirror::default_fact_suppliers,
my_enumerator,
Unused> maker;
typename maker::template factory<Product>::type f;
template<class ConstructionInfo>
inline my_manufacturer(
int _value, ConstructionInfo construction_info) :
f(construction_info) { }
void finish(int) { }
inline Product operator()(void) {
return f();
}
};
149/210
template<class Product, typename IsEnum>
struct my_base_manufacturer {
Product x;
struct constr_param_name_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << ", ";
std::cout << IterInfo::type::base_name();
}
};
struct constr_context_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << "::";
std::cout << IterInfo::type::base_name();
}
};
template<class ConstructionInfo>
my_base_manufacturer(int tabs,
ConstructionInfo construction_info,
const Product& _x) : x(tabs) { }
void finish(int) {
}
inline Product operator()(void) {
return x;
}
};
template<class Product, class Unused>
struct my_enumerator :
my_base_manufacturer<Product, std::true_type> {
template<class ConstructionInfo>
inline my_enumerator(int tabs,
ConstructionInfo construction_info) :
my_base_manufacturer<Product, std::true_type>(
tabs, construction_info, Product()) { }
void finish(int) { }
inline Product operator()(void) {
return NULL;
}
};
template<class Product, class Unused>
struct my_manufacturer {
typedef typename mirror::factory_maker<
my_manufacturer,
mirror::default_fact_suppliers,
my_enumerator,
Unused> maker;
typename maker::template factory<Product>::type f;
template<class ConstructionInfo>
inline my_manufacturer(
int _value, ConstructionInfo construction_info) :
f(construction_info) { }
void finish(int) { }
inline Product operator()(void) {
return f();
}
};
Less complex than it looks!
150/210
template<class Product, typename IsEnum>
struct my_base_manufacturer {
Product x;
struct constr_param_name_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << ", ";
std::cout << IterInfo::type::base_name();
}
};
struct constr_context_printer {
template<class IterInfo>
inline void operator()(IterInfo) const {
if (!IterInfo::is_first::value)
std::cout << "::";
std::cout << IterInfo::type::base_name();
}
};
template<class ConstructionInfo>
my_base_manufacturer(int tabs,
ConstructionInfo construction_info,
const Product& _x) : x(tabs) { }
void finish(int) {
}
inline Product operator()(void) {
return x;
}
};
template<class Product, class Unused>
struct my_enumerator :
my_base_manufacturer<Product, std::true_type> {
template<class ConstructionInfo>
inline my_enumerator(int tabs,
ConstructionInfo construction_info) :
my_base_manufacturer<Product, std::true_type>(
tabs, construction_info, Product()) { }
void finish(int) { }
inline Product operator()(void) {
return NULL;
}
};
template<class Product, class Unused>
struct my_manufacturer {
typedef typename mirror::factory_maker<
my_manufacturer,
mirror::default_fact_suppliers,
my_enumerator,
Unused> maker;
typename maker::template factory<Product>::type f;
template<class ConstructionInfo>
inline my_manufacturer(
int _value, ConstructionInfo construction_info) :
f(construction_info) { }
void finish(int) { }
inline Product operator()(void) {
return f();
}
};
Less complex than it looks!Can be replaced by existing factories
151/210
Scenarios
 Scenario 2:
– Mirror provides many ready-to-use factories
• From strings (mirror/example/factories/tetrahedron_script.cpp)
• From a SOCI database (mirror/example/factories/tetrahedron_soci.cpp)
– Given an object o, instance of C
– Save on disk the complete state of o
– Restore from disk the object o at a later time
// make the input object for the factory
script_factory_input in;
// create a factory plugged with the script parser
script_factory_maker::factory<tetrahedron>::type f = in.data();
// make a tetrahedron object factory
soci_quick_factory_maker::factory<test::tetrahedron>::type
tetrahedron_factory = soci_fact_data(r);
while(r != e) {
test::tetrahedron t = tetrahedron_factory();
// and write it to std output
std::cout << stream::to_json::from(t, [&i](std::ostream& out) {
out << "tetrahedron_" << i; } ) << std::endl;
152/210
Scenarios
 Scenario 3:
namespace cse3009 {
class C {
private:
int i;
static int numberOfInstances;
public:
C(const int _i) : i(_i) {
numberOfInstances++;
}
...
void foo(const std::string _s) const {
std::cout << _s << this->i << std::endl;
}
static int getNumberOfInstances() {
return numberOfInstances;
}
};
}
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
153/210
Scenarios
 Scenario 3:
int cse3009::C::numberOfInstances = 0;
int main(void) {
cse3009::C * o1 = new cse3009::C(42);
cse3009::C * o2 = new cse3009::C(1);
cse3009::C * o3 = new cse3009::C(100);
std::cout << o1 << std::endl << o2 << std::endl << o3 << std::endl;
std::cout << cse3009::C::getNumberOfInstances() << std::endl;
return 0;
}
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
154/210
Scenarios
 Scenario 3:
0x800418f8
0x80041908
0x80041918
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
155/210
Scenarios
 Scenario 3:
0x800418f8
0x80041908
0x80041918
3
– Given a class C
– Record the numbers of its instance ever created
– Report this number when the program ends
To fulfill this scenario, we
must modify C as in Java
156/210
Scenarios
 Scenario 4:
– Several choices
• Bjarne Stroustrup's Template:
http://www.stroustrup.com/wrapper.pdf
• Herb Sutter's Functor-based Approach:
http://channel9.msdn.com/Shows/Going+Deep/
C-and-Beyond-2012-Herb-Sutter-Concurrency-and-
Parallelism
• Ion Armagedescu’s CPatcher:
http://www.codeproject.com/Articles/34237/A-C-Style-
of-Intercepting-Functions
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
157/210
Scenarios
 Scenario 4:
– Several choices
• Bjarne Stroustrup's Template:
http://www.stroustrup.com/wrapper.pdf
• Herb Sutter's Functor-based Approach:
http://channel9.msdn.com/Shows/Going+Deep/
C-and-Beyond-2012-Herb-Sutter-Concurrency-and-
Parallelism
• Ion Armagedescu’s CPatcher:
http://www.codeproject.com/Articles/34237/A-C-Style-
of-Intercepting-Functions
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
158/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
Bjarne Stroustrup's Template:
(Prefix::operator->())
This is o: 42
159/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
int main(void) {
std::cout << "Bjarne Stroustrup's Template:" << std::endl;
cse3009::C o2(42);
Prefix<cse3009::C> prefixed_o2(&o2);
prefixed_o2->foo("This is o: ");
std::cout << std::endl;
return 0;
}
160/210
Scenarios
 Scenario 4:
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
template<class T>
class Prefix {
T* p;
public:
Prefix(T * _p) : p(_p) { }
T* operator->() {
std::cout << "(Prefix::operator->())" << std::endl;
return p;
}
};
161/210
Scenarios
 Scenario 4:
– Is similar to a proxy in Java
– Cannot easily access and modify the
arguments of the proxy’ed method call
– Makes it difficult to do something after the
original method call
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
162/210
Scenarios
 Scenario 4:
– Several choices
• Bjarne Stroustrup's Template:
http://www.stroustrup.com/wrapper.pdf
• Herb Sutter's Functor-based Approach:
http://channel9.msdn.com/Shows/Going+Deep/
C-and-Beyond-2012-Herb-Sutter-Concurrency-and-
Parallelism
• Ion Armagedescu’s CPatcher:
http://www.codeproject.com/Articles/34237/A-C-Style-
of-Intercepting-Functions
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
163/210
Scenarios
 Scenario 4:
Dependent on the compiler!
GCC v4.8.2
vs.
Microsoft Visual Studio Express 2013
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
Visual C++ 2013 06157-004-0441005-02428
164/210
Scenarios
 Scenario 4:
– GCC v4.8.2
In file included from ..Sourcescenario4.cpp:32:0:
..Source../CPatcher/patcher.h: In instantiation of 'void
CPatch::HookClassFunctions(T1&, T2, bool, bool) [with T1 =
void (cse3009::C::*)(std::basic_string<char>); T2 = void
(class_for_patches::*)(std::basic_string<char>)]':
..Source../CPatcher/patcher_defines.h:131:2: required
from 'CPatch::CPatch(TReturnVal (TClassSource::*&)(TArg1),
TReturnVal (TClassTarget::*)(TArg1), bool, bool) [with
TClassSource = cse3009::C; TClassTarget =
class_for_patches; TReturnVal = void; TArg1 =
std::basic_string<char>]' ..Sourcescenario4.cpp:52:61:
required from here
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
165/210
Scenarios
 Scenario 4:
– GCC v4.8.2
may not be legal
• http://www.codeproject.com/Articles/34237/A-C-Style-
of-Intercepting-Functions?msg=4796042
• http://stackoverflow.com/questions/1307278/casting-
between-void-and-a-pointer-to-member-function
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
*reinterpret_cast<long*>(&fn_funcToHook)
*reinterpret_cast<long*>(&fn_Hook)
166/210
Scenarios
 Scenario 4:
– Microsoft Visual Studio Express 2013
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
void(ptidej::C::*pfn_foo)(const std::string) = &ptidej::C::foo;
class proxy {
public:
void my_foo(const std::string s) {
std::cout << "Function foo() is patched!" << std::endl << std::flush;
(reinterpret_cast<ptidej::C*>(this)->*pfn_foo)(s);
}
};
int _tmain(int argc, _TCHAR* argv[]) {
CPatch patch_aclass_doSomething(pfn_foo, &proxy::my_foo);
ptidej::C o(42);
o.foo(std::string("This is o: "));
return 0;
}
167/210
Scenarios
 Scenario 4:
– Microsoft Visual Studio Express 2013
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
Function foo() is patched!
This is o: 42
168/210
Scenarios
 Scenario 4:
– Is similar to a proxy in Java
– Can easily access and modify the arguments
of the proxy’ed method call
– Makes it difficult to do something after the
original method call
– Given an object o, instance of C
– Without changing o or C
– Change the behaviour of o.foo()
169/210
Scenarios
Java 
Smalltalk 
C++ 
170/210
Conclusion
Java 
Smalltalk 
C++ 
171/210
Conclusion
Java 
Smalltalk 
C++ 
Differences in semantics
and syntax mostly due to
the presence (or absence)
of virtual machines
172/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
173/210
Theory
 Class
– A programming construct that encapsulates
some state (fields) and behaviours (methods)
– A construct whose instances are objects
 Metaclass
– A programming construct that encapsulates
some state (fields) and behaviours (methods)
– A construct whose instances are classes
Aristote (Ἀριστοτέλης)
*-384 †-322
174/210
Theory
 An object is an instance of a class
– A class generates an object
 A class is an instance of a metaclass
– A metaclass generates a class
 A metaclass is an instance of…
175/210
Theory
 An object is an instance of a class
– A class generates an object
 A class is an instance of a metaclass
– A metaclass generates a class
 A metaclass is an instance of…
(a) A meta-metaclass?
176/210
Theory
 An object is an instance of a class
– A class generates an object
 A class is an instance of a metaclass
– A metaclass generates a class
 A metaclass is an instance of…
(a) A meta-metaclass?
(b) Itself?
177/210
Theory
 An object is an instance of a class
– A class generates an object
 A class is an instance of a metaclass
– A metaclass generates a class
 A metaclass is an instance of…
(a) A meta-metaclass?
(b) Itself
178/210
Theory
 The class Object is the parent of all
classes, including metaclasses
 The class Class is the generator of all
classes, including Object
179/210
Des langages de programmation à objets
à la représentation des connaissances à
travers le MOP : vers une intégration
par Gabriel Pavillet. Thèse de doctorat
en Informatique sous la direction de
Roland Ducournau, soutenue en 2000
à Montpellier 2
180/210
Theory
 The classes
– Class
– Method
– Field
– …
reify constructs of the programming
languages, they become first-class entities,
to allow programs to manipulate these
constructs at runtime
181/210
Theory
Java
 Field  C
 Method  C
 Static field  C
 Static method  C
 
Smalltalk
 Instance variable  C
 Instance method  C
 Class variable  C class
 Class method  C class
 Class instance variables
– To count the numbers of
instances of subclasses of C
(D, E…) independently from
one another
182/210
Theory
 Earlier, we said that reflection is of
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
183/210
Theory
 Earlier, we said that reflection is of
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
184/210
Theory
 Earlier, we said that reflection is of
– Theoretical interest
• What is an interpreter?
Brian Cantwell Smith “Procedural Reflection in
Programming Languages” (Ph.D. thesis, 1982)
– Practical interest
• Libraries
• Frameworks
A virtual machine
is an interpreter
185/210
Theory
 In Java, the metaclass is anonymous and
cannot be modified
 In Smalltalk, “[t]here is only one instance of a
particular Metaclass, namely the class which
is being described”
186/210
Theory
 Many other variations are possible
– LISP
• http://www.cliki.net/mop
– Perl 5, 6
• http://search.cpan.org/perldoc?Class::MOP
– Python
• https://www.python.org/doc/essays/metaclasses/
– MetaclassTalk – Noury Bouraqadi, Pierre Cointe
• http://csl.ensm-douai.fr/MetaclassTalk
– NeoClassTalk – Fred Rivard, Pierre Cointe
• http://c2.com/cgi/wiki?NeoClassTalk
– OpenC++ – Shigeru Chiba, Gregor Kiczales
• http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/openc++.html
187/210
Theory
 A Meta Object Protocol exposes some or all
internal structure of the interpreter to the
programmer
 The MOP is (often) a set of classes and
methods that allow a program to inspect the
state of the supporting system and alter its
behaviour
188/210
Theory
 MOP can be accessible at
– Compile-time
• OpenJava
– http://www.csg.ci.i.u-tokyo.ac.jp/openjava/
– Load-time
• Javassist
– http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
– Run-time
• AspectJ
– http://eclipse.org/aspectj/
189/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
190/210
Conclusion
 Scenario 1: invoke an arbitrary method on an object (see
the problems with instanceof and plugins)
 Scenario 2: access the complete (including private) state of
an object (see the problem with serialisation)
 Scenario 3: count the number of instances of a class
created at runtime (see the problem with
debugging/profiling)
 Scenario 4: modify the behaviour at run-time of a method
without the need to recompile and restart the program (see
the problem with patching)
191/210
Conclusion
 Reflection helps addressing these scenarios
– Depends on the capabilities of the programming
language and underlying execution environment
– Yields more or less elegant code
 Use reflection sparingly and purposefully
– Complexity
– Performance
192/210
Conclusion
Java 
Smalltalk 
C++ 
193/210
Conclusion
Java 
Smalltalk 
C++ 
194/210
Conclusion
Java 
Smalltalk 
C++ 
Differences in semantics
and syntax mostly due to
the presence (or absence)
of virtual machines
195/210
Outline
 Rationale
 Definition
 Context
– Interconnections
 Scenarios
 Theory
 Conclusion
 Class Loading
196/210
Class Loading
 Virtual machines
– Interpreters
– Closed world
 Must
– Access resources
– Load classes
197/210
Class Loading
 Virtual machines
– Interpreters
– Closed world
 Must
– Access resources
– Load classes
198/210
Class Loading
 Virtual machines
– Interpreters
– Closed world
 Must
– Access resources
– Load classes
199/210
Class Loading
 Example
– Given an interface ICommand
– Load at runtime a class implementing
ICommand using its binary name
• A binary name is in the form
<pckg1>.….<pckgn>.<ClassName>
– net.ptidej.reflection.java.scenario1.C
final Class<ICommand> command =
this.classLoader.loadClass(binaryName);
200/210
Class Loading
http://map.sdsu.edu/geog583/images/week8.3.gif
201/210
Class Loading
http://www.onjava.com/2005/01/26/graphics/Figure01_MultipleClassLoaders.JPG
202/210
Class Loading
public class ClassLoader extends java.lang.ClassLoader {
private final String directory;
public ClassLoader(
final java.lang.ClassLoader parent,
final String directory) {
super(parent);
this.directory = directory;
}
203/210
Class Loading
protected Class findClass(final String name) {
Class newClass = null;
try {
newClass = super.findClass(name);
}
catch (final ClassNotFoundException cnfe) {
final String osName =
this.directory + name.replace('.', '/') + ".class";
try {
final FileInputStream fis = new FileInputStream(osName);
newClass = this.defineClasses(name, fis);
}
catch (final ClassFormatError cfe) {
cfe.printStackTrace(Output.getInstance().errorOutput());
}
catch (final FileNotFoundException fnfe) {
// fnfe.printStackTrace();
}
}
return newClass;
}
204/210
Class Loading
protected Class findClass(final String name) {
Class newClass = null;
try {
newClass = super.findClass(name);
}
catch (final ClassNotFoundException cnfe) {
final String osName =
this.directory + name.replace('.', '/') + ".class";
try {
final FileInputStream fis = new FileInputStream(osName);
newClass = this.defineClasses(name, fis);
}
catch (final ClassFormatError cfe) {
cfe.printStackTrace(Output.getInstance().errorOutput());
}
catch (final FileNotFoundException fnfe) {
// fnfe.printStackTrace();
}
}
return newClass;
}
Use the method defined in
the superclass on this CL
205/210
Class Loading
private Class defineClasses(final String name, final InputStream inputStream) {
try {
int b;
int length = 0;
byte[] bytes = new byte[4];
while ((b = inputStream.read()) != -1) {
if (length == bytes.length) {
final byte[] temp = new byte[length + 4];
System.arraycopy(bytes, 0, temp, 0, length);
bytes = temp;
}
bytes[length] = (byte) b;
length++;
}
System.out.println(name);
final Class newClass = this.defineClass(name, bytes, 0, length);
return newClass;
}
catch (final IOException ioe) {
return null;
}
catch (final NoClassDefFoundError ncdfe) {
ncdfe.printStackTrace(Output.getInstance().errorOutput());
return null;
}
}
206/210
Class Loading
private Class defineClasses(final String name, final InputStream inputStream) {
try {
int b;
int length = 0;
byte[] bytes = new byte[4];
while ((b = inputStream.read()) != -1) {
if (length == bytes.length) {
final byte[] temp = new byte[length + 4];
System.arraycopy(bytes, 0, temp, 0, length);
bytes = temp;
}
bytes[length] = (byte) b;
length++;
}
System.out.println(name);
final Class newClass = this.defineClass(name, bytes, 0, length);
return newClass;
}
catch (final IOException ioe) {
return null;
}
catch (final NoClassDefFoundError ncdfe) {
ncdfe.printStackTrace(Output.getInstance().errorOutput());
return null;
}
}
Use the method defined in
the superclass on this CL
207/210
Class Loading
http://www.onjava.com/2005/01/26/graphics/Figure01_MultipleClassLoaders.JPG
208/210
Class Loading
protected Class findClass(final String name) {
Class newClass = null;
try {
newClass = this.getParent().loadClass(name);
}
catch (final ClassNotFoundException cnfe) {
final String osName =
this.directory + name.replace('.', '/') + ".class";
try {
final FileInputStream fis = new FileInputStream(osName);
newClass = this.defineClasses(name, fis);
}
catch (final ClassFormatError cfe) {
cfe.printStackTrace(Output.getInstance().errorOutput());
}
catch (final FileNotFoundException fnfe) {
// fnfe.printStackTrace();
}
}
return newClass;
}
209/210
Class Loading
protected Class findClass(final String name) {
Class newClass = null;
try {
newClass = this.getParent().loadClass(name);
}
catch (final ClassNotFoundException cnfe) {
final String osName =
this.directory + name.replace('.', '/') + ".class";
try {
final FileInputStream fis = new FileInputStream(osName);
newClass = this.defineClasses(name, fis);
}
catch (final ClassFormatError cfe) {
cfe.printStackTrace(Output.getInstance().errorOutput());
}
catch (final FileNotFoundException fnfe) {
// fnfe.printStackTrace();
}
}
return newClass;
}
Ask the parent CL if it
already knows the class
210/210
Conclusion
 Virtual machines must access resources and
load classes, in specific cases
– Can extend ClassLoader
– Must override (typically) method
• Class findClass(String)
– Must be careful with inheritance vs. delegation!
• super vs. getParent()

More Related Content

What's hot

What's hot (20)

Python & Stuff
Python & StuffPython & Stuff
Python & Stuff
 
Core java pract_sem iii
Core java pract_sem iiiCore java pract_sem iii
Core java pract_sem iii
 
Guice2.0
Guice2.0Guice2.0
Guice2.0
 
DCN Practical
DCN PracticalDCN Practical
DCN Practical
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Maksim Melnikau aka “max_posedon” - Telepathy protocol example
Maksim Melnikau aka “max_posedon” - Telepathy protocol exampleMaksim Melnikau aka “max_posedon” - Telepathy protocol example
Maksim Melnikau aka “max_posedon” - Telepathy protocol example
 
Advanced Python, Part 2
Advanced Python, Part 2Advanced Python, Part 2
Advanced Python, Part 2
 
Python Tutorial
Python TutorialPython Tutorial
Python Tutorial
 
java 8 Hands on Workshop
java 8 Hands on Workshopjava 8 Hands on Workshop
java 8 Hands on Workshop
 
python.ppt
python.pptpython.ppt
python.ppt
 
Python and sysadmin I
Python and sysadmin IPython and sysadmin I
Python and sysadmin I
 
The Arrow Library in Kotlin
The Arrow Library in KotlinThe Arrow Library in Kotlin
The Arrow Library in Kotlin
 
Coding in Kotlin with Arrow NIDC 2018
Coding in Kotlin with Arrow NIDC 2018Coding in Kotlin with Arrow NIDC 2018
Coding in Kotlin with Arrow NIDC 2018
 
python-message-0.1.0
python-message-0.1.0python-message-0.1.0
python-message-0.1.0
 
Howto argparse
Howto argparseHowto argparse
Howto argparse
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Biopython
BiopythonBiopython
Biopython
 
Lazy java
Lazy javaLazy java
Lazy java
 
Programming Under Linux In Python
Programming Under Linux In PythonProgramming Under Linux In Python
Programming Under Linux In Python
 

Similar to OO Reflection Tutorial

On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6Yann-Gaël Guéhéneuc
 
Polymorphism.ppt
Polymorphism.pptPolymorphism.ppt
Polymorphism.pptEmanAsem4
 
In this project you will define some interfaces, abstract classes, a.pdf
In this project you will define some interfaces, abstract classes, a.pdfIn this project you will define some interfaces, abstract classes, a.pdf
In this project you will define some interfaces, abstract classes, a.pdffathimaoptical
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet KotlinJieyi Wu
 
Object-oriented Programming-with C#
Object-oriented Programming-with C#Object-oriented Programming-with C#
Object-oriented Programming-with C#Doncho Minkov
 
Unsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST APIUnsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST APIMikhail Egorov
 
Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Abid Kohistani
 
Interfaces &amp; Abstract Classes
Interfaces &amp; Abstract ClassesInterfaces &amp; Abstract Classes
Interfaces &amp; Abstract ClassesBharat17485
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developersAnton Udovychenko
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、GaelykでハンズオンTsuyoshi Yamamoto
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2Technopark
 
encapsulation, inheritance, overriding, overloading
encapsulation, inheritance, overriding, overloadingencapsulation, inheritance, overriding, overloading
encapsulation, inheritance, overriding, overloadingShivam Singhal
 
Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphismHariz Mustafa
 

Similar to OO Reflection Tutorial (20)

On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6On Reflection in OO Programming Languages v1.6
On Reflection in OO Programming Languages v1.6
 
Abstract factory
Abstract factoryAbstract factory
Abstract factory
 
L04 Software Design 2
L04 Software Design 2L04 Software Design 2
L04 Software Design 2
 
Polymorphism.ppt
Polymorphism.pptPolymorphism.ppt
Polymorphism.ppt
 
Java2
Java2Java2
Java2
 
Introduccion del curso
Introduccion del cursoIntroduccion del curso
Introduccion del curso
 
VRaptor 4 - JavaOne
VRaptor 4 - JavaOneVRaptor 4 - JavaOne
VRaptor 4 - JavaOne
 
In this project you will define some interfaces, abstract classes, a.pdf
In this project you will define some interfaces, abstract classes, a.pdfIn this project you will define some interfaces, abstract classes, a.pdf
In this project you will define some interfaces, abstract classes, a.pdf
 
Nice to meet Kotlin
Nice to meet KotlinNice to meet Kotlin
Nice to meet Kotlin
 
Object-oriented Programming-with C#
Object-oriented Programming-with C#Object-oriented Programming-with C#
Object-oriented Programming-with C#
 
Unsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST APIUnsafe JAX-RS: Breaking REST API
Unsafe JAX-RS: Breaking REST API
 
Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#Polymorphism in C# Function overloading in C#
Polymorphism in C# Function overloading in C#
 
Interfaces &amp; Abstract Classes
Interfaces &amp; Abstract ClassesInterfaces &amp; Abstract Classes
Interfaces &amp; Abstract Classes
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developers
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Java.lang.object
Java.lang.objectJava.lang.object
Java.lang.object
 
encapsulation, inheritance, overriding, overloading
encapsulation, inheritance, overriding, overloadingencapsulation, inheritance, overriding, overloading
encapsulation, inheritance, overriding, overloading
 
Lecture04 polymorphism
Lecture04 polymorphismLecture04 polymorphism
Lecture04 polymorphism
 

More from Yann-Gaël Guéhéneuc

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Yann-Gaël Guéhéneuc
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Yann-Gaël Guéhéneuc
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Yann-Gaël Guéhéneuc
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Yann-Gaël Guéhéneuc
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Yann-Gaël Guéhéneuc
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...Yann-Gaël Guéhéneuc
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesYann-Gaël Guéhéneuc
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Yann-Gaël Guéhéneuc
 
On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1Yann-Gaël Guéhéneuc
 

More from Yann-Gaël Guéhéneuc (20)

Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5Advice for writing a NSERC Discovery grant application v0.5
Advice for writing a NSERC Discovery grant application v0.5
 
Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1Ptidej Architecture, Design, and Implementation in Action v2.1
Ptidej Architecture, Design, and Implementation in Action v2.1
 
Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22Evolution and Examples of Java Features, from Java 1.7 to Java 22
Evolution and Examples of Java Features, from Java 1.7 to Java 22
 
Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3Consequences and Principles of Software Quality v0.3
Consequences and Principles of Software Quality v0.3
 
Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9Some Pitfalls with Python and Their Possible Solutions v0.9
Some Pitfalls with Python and Their Possible Solutions v0.9
 
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
An Explanation of the Unicode, the Text Encoding Standard, Its Usages and Imp...
 
An Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its ConsequencesAn Explanation of the Halting Problem and Its Consequences
An Explanation of the Halting Problem and Its Consequences
 
Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0Are CPUs VMs Like Any Others? v1.0
Are CPUs VMs Like Any Others? v1.0
 
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
Informaticien(ne)s célèbres (v1.0.2, 19/02/20)
 
Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2Well-known Computer Scientists v1.0.2
Well-known Computer Scientists v1.0.2
 
On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1On Java Generics, History, Use, Caveats v1.1
On Java Generics, History, Use, Caveats v1.1
 
ICSOC'21
ICSOC'21ICSOC'21
ICSOC'21
 
Vissoft21.ppt
Vissoft21.pptVissoft21.ppt
Vissoft21.ppt
 
Service computation20.ppt
Service computation20.pptService computation20.ppt
Service computation20.ppt
 
Serp4 iot20.ppt
Serp4 iot20.pptSerp4 iot20.ppt
Serp4 iot20.ppt
 
Msr20.ppt
Msr20.pptMsr20.ppt
Msr20.ppt
 
Iwesep19.ppt
Iwesep19.pptIwesep19.ppt
Iwesep19.ppt
 
Icsoc20.ppt
Icsoc20.pptIcsoc20.ppt
Icsoc20.ppt
 
Icsoc18.ppt
Icsoc18.pptIcsoc18.ppt
Icsoc18.ppt
 
Icsm20.ppt
Icsm20.pptIcsm20.ppt
Icsm20.ppt
 

Recently uploaded

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 

Recently uploaded (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

OO Reflection Tutorial

  • 1. Yann-Gaël Guéhéneuc This work is licensed under a Creative Commons Attribution-NonCommercial- ShareAlike 3.0 Unported LicenseDépartement de génie informatique et de génie logiciel On Reflection in OO Programming Languages yann-gael.gueheneuc@polytmtl.ca Version 1.5.5 2014/04/30
  • 2. 2/210 Any questions/comments are welcome at yann-gael.gueheneuc@polymtl.ca The source code is available at http://www.ptidej.net/tutorial/javareflection
  • 3. 3/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 4. 4/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 5. 5/210 Use of instanceof public abstract class Animal { } public class Cat extends Animal { } public class Dog extends Animal { } public class Expression { public static String speak(final Animal anAnimal) { final String sound; if (anAnimal instanceof Dog) { sound = "woof"; } else if (anAnimal instanceof Cat) { sound = "miaow"; } else { sound = ""; } return sound; } public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(Expression.speak(fido)); } }
  • 6. 6/210 Use of instanceof public abstract class Animal { } public class Cat extends Animal { } public class Dog extends Animal { } public class Expression { public static String speak(final Animal anAnimal) { final String sound; if (anAnimal instanceof Dog) { sound = "woof"; } else if (anAnimal instanceof Cat) { sound = "miaow"; } else { sound = ""; } return sound; } public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(Expression.speak(fido)); } } Must test the type of the object at run-time
  • 7. 7/210 Use of instanceof public abstract class Animal { } public class Cat extends Animal { } public class Dog extends Animal { } public class Expression { public static String speak(final Animal anAnimal) { final String sound; if (anAnimal instanceof Dog) { sound = "woof"; } else if (anAnimal instanceof Cat) { sound = "miaow"; } else { sound = ""; } return sound; } public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(Expression.speak(fido)); } } Must test the type of the object at run-time Breaks information hiding of Cat and Dog
  • 8. 8/210 Use of instanceof public abstract class Animal { } public class Cat extends Animal { } public class Dog extends Animal { } public class Expression { public static String speak(final Animal anAnimal) { final String sound; if (anAnimal instanceof Dog) { sound = "woof"; } else if (anAnimal instanceof Cat) { sound = "miaow"; } else { sound = ""; } return sound; } public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(Expression.speak(fido)); } } Must test the type of the object at run-time Breaks information hiding of Cat and Dog Requires special case
  • 9. 9/210 Use of instanceof  Reason – Must bypass the compiler and virtual machine’s choice of the method to call – Remember that overloading is resolved by the static type of the argument, not its run-time type (cf. Week 2)
  • 10. 10/210 Use of instanceof  Problem “Don't repeat yourself” (DRY): “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” —Andy Hunt and Dave Thomas (in The Pragmatic Programmer)
  • 11. 11/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String speak() { return "miaow"; } } public class Dog extends Animal { @Override public String speak() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(fido.speak()); } }
  • 12. 12/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String speak() { return "miaow"; } } public class Dog extends Animal { @Override public String speak() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(fido.speak()); } }
  • 13. 13/210 Use of instanceof public class Cat { public String speak() { return "miaow"; } } public class Dog { public String speak() { return "woof"; } } public class Expression { public static void main(final String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } }
  • 14. 14/210 Use of instanceof public class Cat { public String speak() { return "miaow"; } } public class Dog { public String speak() { return "woof"; } } public class Expression { public static void main(final String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } } Discover method of object of unrelated classes
  • 15. 15/210 Plugins  Plugins are external, user-defined pieces of code loaded, used, and unloaded to benefit from their features only when needed  Problem – Closed-world assumption (at compile-time and runtime) leads to the need for a mechanism to perform dynamic loading
  • 16. 16/210 Serialisation  Serialisation is the process of translating data structures or object state into a format that can be stored (file, network…)  Problem – Information hiding prevents access to the internals of the data structures and to the complete object states
  • 17. 17/210 Debugging/Profiling  Debugging/profiling are the processes of monitoring the execution of a program – To understand its behaviour – To measure its space and time complexity  Problem – Accessing the internals of objects and controlling the program to collect relevant data
  • 18. 18/210 Patching  Patching is the process of changing the behaviour of a class or an object – To modify its behaviour – To add new behaviour  Problem – Modifying the behaviour at run-time without the need to recompile and restart the program
  • 19. 19/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 20. 20/210 Definition  Reflection is the ability of a computer program to examine and modify the structure and behaviour of an object at runtime
  • 21. 21/210 Definition  Reflection is the ability of a computer program to examine and modify the structure and behaviour of an object at runtime Problem: inspect objects and change their behaviour at runtime Solution: reflection
  • 22. 22/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String speak() { return "miaow"; } } public class Dog extends Animal { @Override public String speak() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); System.out.println(fido.speak()); } }
  • 23. 23/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String miaow() { return "miaow"; } } public class Dog extends Animal { @Override public String bark() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } }
  • 24. 24/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String miaow() { return "miaow"; } } public class Dog extends Animal { @Override public String bark() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } } Unrelated classes
  • 25. 25/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String miaow() { return "miaow"; } } public class Dog extends Animal { @Override public String bark() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } } Unrelated classes Choice at run-time
  • 26. 26/210 Use of instanceof public abstract class Animal { public abstract String speak(); } public class Cat extends Animal { @Override public String miaow() { return "miaow"; } } public class Dog extends Animal { @Override public String bark() { return "woof"; } } public class Expression { public static void main(final String[] args) { final Dog fido = new Dog(); final Method[] method = Dog.class.getDeclaredMethods(); System.out.println(method[0].invoke(fido, new Object[0])); } } Unrelated classes Choice at run-time
  • 27. 27/210 Outline  Problems  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 28. 28/210 Context  Reflection – Ability of a computer program to examine and modify the structure and behaviour of an object at runtime
  • 29. 29/210 Context  Reflection – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks
  • 30. 30/210 Context  Reflection – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks
  • 31. 31/210 Context  Reflection – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks
  • 32. 32/210 Context  Libraries – Collections of data structures and algorithms (possibly encapsulated in classes) used to develop and run programs  Frameworks – Reusable sets of libraries, tools, and conventions used to develop and run programs
  • 33. 33/210 Context  Libraries – Collections of data structures and algorithms (possibly encapsulated in classes) used to develop and run programs  Frameworks – Reusable sets of libraries, tools, and conventions used to develop and run programs Problem: connection between clients and libraries/frameworks Solution: linking, forking, subclassing, IPC, and dynamic loading
  • 34. 34/210 Interconnections  Clients–Libraries/Frameworks – Linking – Forking – Subclassing – Inter-process communication – Dynamic loading/invoking
  • 35. 35/210 Interconnections  Linking (Contrast with virtual machines) – Typically C/C++ – Several object files (.o) – One executable (.exe)
  • 36. 36/210 Interconnections  Forking – Typical in most languages – Process duplication • Is a real duplication • Creates a new OS process final StringBuffer commandLine = new StringBuffer(); commandLine.append("..DOTbindotty "); commandLine.append(aFilePath); final Process process = Runtime.getRuntime().exec(commandLine.toString()); final OutputMonitor errorStreamMonitor = new OutputMonitor(...,process.getErrorStream(),...); errorStreamMonitor.start(); final OutputMonitor inputStreamMonitor = new OutputMonitor(...,process.getInputStream(),...); inputStreamMonitor.start(); try { process.waitFor(); } catch (final InterruptedException ie) { ie.printStackTrace( Output.getInstance().errorOutput()); } if (process.exitValue() != 0) { ... }
  • 37. 37/210 Interconnections  IPC – Typical in most languages – Use remote procedure calls – Use well-defined protocols • COM • CORBA • XML-RPC – Web services
  • 38. 38/210 Interconnections package kr.ac.yonsei.cse3009.rpc; import java.net.URL; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; public class Client { public static void main(final String[] args) throws Exception { final XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); config.setServerURL( new URL("http://127.0.0.1:8080/xmlrpc")); final XmlRpcClient client = new XmlRpcClient(); client.setConfig(config); final Object[] params = new Object[] { new Integer(33), new Integer(9) }; final Integer result = (Integer) client.execute("Calculator.add", params); System.out.println(result); } } package kr.ac.yonsei.cse3009.rpc; import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.XmlRpcServer; import org.apache.xmlrpc.webserver.WebServer; public class Server { public static void main(final String[] args) throws Exception { final WebServer webServer = new WebServer(8080); final XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer(); final PropertyHandlerMapping phm = new PropertyHandlerMapping(); phm.addHandler("Calculator", Calculator.class); xmlRpcServer.setHandlerMapping(phm); webServer.start(); } } package kr.ac.yonsei.cse3009.rpc; public class Calculator { public int add(final int i1, final int i2) { return i1 + i2; } public int sub(final int i1, final int i2) { return i1 - i2; } }
  • 39. 39/210 Interconnections  Subclassing – Typical in most object- oriented languages – Structural, static relation public class OutputMonitor extends Thread { ... public OutputMonitor(...) { this.setName(threadName); this.setPriority(Thread.MAX_PRIORITY); ... } public void run() { try { int value = 0; byte[] bytes; char lastWrittenChar; while ((value = this.inputStream.read()) > 0) { synchronized (System.err) { synchronized (System.out) { if (value != 13 && value != 10) { lastWrittenChar = (char) value; ... }} } } catch (final IOException ioe) { ...
  • 40. 40/210 Interconnections  Subclassing – Hooks and templates • Hot spots = hooks • Frozen spots = templates – Hooks are typically abstract methods – Templates typically use hooks
  • 42. 42/210 Interconnections  Template  Hooks public abstract class TestCase extends Assert implements Test { public void runBare() throws Throwable { setUp(); try { runTest(); } finally { tearDown(); } } protected void setUp() throws Exception { } protected void tearDown() throws Exception { } ... }
  • 43. 43/210 Interconnections  Subclassing – Heavily used in object-oriented programs – Heavily used in design patterns (Only Singleton does not explicitly use subclassing) • Abstract Factory • Composite • Decorator • Observer • Visitor
  • 44. 44/210 Interconnections  Dynamic loading – In different programming languages (but not all), it is the possibility to load, use, and unload a piece of code at runtime – In Java, it is the possibility to load and unload a class and to choose and invoke its methods (and to access its fields…) at runtime
  • 45. 45/210 Interconnections  Poor man’s profiler – Calls the main() method of a class whose name is given at runtime, by the user – Displays the time spent in the called method public final class PoorManProfiler { public static void main(final String[] args) { try { final Class toBeRun = Class.forName(args[0]); final Method mainMethod = toBeRun.getMethod("main", new Class[] { String[].class }); final long startTime = System.currentTimeMillis(); mainMethod.invoke(null, new Object[] { new String[0] }); final long endTime = System.currentTimeMillis(); System.out.println(); System.out.println(endTime - startTime); } catch (final Exception e) { e.printStackTrace(); } } }
  • 46. 46/210 Return to Reflection  Reflection enables dynamic loading – Reflection  dynamic loading – Dynamic loading  Reflection • Think of dynamically-loaded shared libraries in C-based operating systems, such as AmigaOS, Linux, UN*X, Windows… 
  • 47. 47/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 48. 48/210 Scenarios  Original problem – Different interpretations – Different contexts  Four scenarios  Three programming languages Problem: inspect objects and change their behaviour at runtime Solution: reflection
  • 49. 49/210 Scenarios  Scenario 1: invoke an arbitrary method on an object (see the problems with instanceof and plugins) – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo
  • 50. 50/210 Scenarios  Scenario 2: access the complete (including private) state of an object (see the problem with serialisation) – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time
  • 51. 51/210 Scenarios  Scenario 3: count the number of instances of a class created at runtime (see the problem with debugging/profiling) – Given a class C – Record the number of its instances ever created – Report this number when the program ends
  • 52. 52/210 Scenarios  Scenario 4: patch the method of a class to change its behaviour (see the problem with patching) – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 54. 54/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo public class C { private int i; public C(final int anInt) { this.i = anInt; } public void foo(final String s) { System.out.print(s); System.out.println(this.i); } }
  • 55. 55/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo Identify all the methods available on o foo getClass hashCode equals toString notify notifyAll wait wait wait Invoke a method using its name foo This is foo: 42
  • 56. 56/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo final C o = new C(42); System.out.println("Identify all the methods available on o"); final Class<?> classOfO = o.getClass(); final Method[] methodsOfC = classOfO.getMethods(); for (int i = 0; i < methodsOfC.length; i++) { final Method method = methodsOfC[i]; System.out.print('t'); System.out.println(method.getName()); } System.out.println("Invoke a method using its name foo"); final Method fooMethod = classOfO.getMethod("foo", new Class[] { String.class }); fooMethod.invoke(o, new Object[] { "tThis is foo: " });
  • 57. 57/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo Identify all the methods available on o foo getClass hashCode equals toString notify notifyAll wait wait wait Invoke a method using its name foo This is foo: 42
  • 58. 58/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time public class C { private int i; public C() { this(-1); } public C(final int anInt) { this.i = anInt; } public void foo(final String s) { System.out.print(s); System.out.println(this.i); } }
  • 59. 59/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time Save on disk the complete state of o i = 42 Restore from disk the object o at a later time This is foo on o2: 43
  • 60. 60/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time final C o1 = new C(42); System.out.println("Save on disk the complete state of o"); final Class<?> classOfO = o1.getClass(); final Field[] fieldsOfC = classOfO.getDeclaredFields(); for (int i = 0; i < fieldsOfC.length; i++) { final Field field = fieldsOfC[i]; field.setAccessible(true); System.out.print('t' + field.getName()); System.out.println(" = " + field.getInt(o1)); } System.out.println("Restore from disk the object o at a later time"); final C o2 = (C) classOfO.newInstance(); final Field fieldiOfC = classOfO.getDeclaredField("i"); fieldiOfC.setAccessible(true); fieldiOfC.setInt(o2, 43); o2.foo("tThis is foo on o2: ");
  • 61. 61/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time Save on disk the complete state of o i = 42 Restore from disk the object o at a later time This is foo on o2: 43
  • 62. 62/210 Scenarios  Scenario 3: – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends public class C { private static int numberOfInstances; public static int getNumberOfInstances() { return C.numberOfInstances; } private int i; public C() { this(-1); } public C(final int anInt) { C.numberOfInstances++; this.i = anInt; } public void foo(final String s) { System.out.print(s); System.out.println(this.i); } }
  • 64. 64/210 Scenarios  Scenario 3: public class Main { public static void main(final String[] args) { final C o1 = new C(42); final C o2 = new C(1); final C o3 = new C(100); System.out.println(o1 + "n" + o2 + 'n' + o3); System.out.println(C.getNumberOfInstances()); } } – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 66. 66/210 Scenarios  Scenario 3: kr.ac.yonsei.it.cse3009.reflection.scenario3.C@150bd4d kr.ac.yonsei.it.cse3009.reflection.scenario3.C@1bc4459 kr.ac.yonsei.it.cse3009.reflection.scenario3.C@12b6651 3 To fulfill this scenario, we must modify C – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 67. 67/210 Scenarios  Class Class is a metaclass – It describes other classes  Class Method is a class – It describes methods  Class Field is a class – It describes fields
  • 68. 68/210 Scenarios  Class Class is a metaclass – It allows to reify classes  Class Method is a class – It allows to reify methods, these language constructs become first-class entities  Class Field is a class – It allows to reify fields , these language constructs become first-class entities
  • 69. 69/210 Scenarios  Class Class is a metaclass – It allows to reify classes  Class Method is a class – It allows to reify methods, these language constructs become first-class entities  Class Field is a class – It allows to reify fields, these language constructs become first-class entities
  • 70. 70/210 Scenarios  Class Class is a metaclass – It allows to reify classes  Class Method is a class – It allows to reify methods, these language constructs become first-class entities  Class Field is a class – It allows to reify fields, these language constructs become first-class entities Reification is the process of making available an implicit construct of a language
  • 71. 71/210 Scenarios  We never modified class Class – We only used it to obtain the methods and fields declared by particular classes, e.g., C  We used static fields and methods to count number of instances
  • 72. 72/210 Scenarios  Scenario 4: public interface I { public void foo(final String s); } public class C implements I { private int i; public C(final int anInt) { this.i = anInt; } public void foo(final String s) { System.out.print(s); System.out.println(this.i); } } – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 73. 73/210 Scenarios  Scenario 4: This is o: 42 Forwarding method: "foo" Original arguments: "This is o: " New arguments: "THIS IS O: " THIS IS O: 42 – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 74. 74/210 Scenarios  Scenario 4: final I o = new C(42); o.foo("This is o: "); final InvocationHandler handler = new InvokationHandler(o); final I proxy = (I) Proxy.newProxyInstance( I.class.getClassLoader(), new Class[] { I.class }, handler); Assert.assertTrue(proxy instanceof I); Assert.assertFalse(proxy instanceof C); Assert.assertTrue(proxy.equals(o)); proxy.foo("This is o: "); – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 75. 75/210 Scenarios Scenario4: public class InvokationHandler implements InvocationHandler { private final I i; public InvokationHandler(final I aConcreteImplementationOfI) { this.i = aConcreteImplementationOfI; } public Object invoke( final Object aProxy, final Method aMethod, final Object[] someArgs) throws Throwable { if (aMethod.getName().equals("foo")) { final String arg = (String) someArgs[0]; final String newArg = arg.toUpperCase(); System.out.print("Forwarding method: ""); System.out.print(aMethod.getName()); System.out.print(""ntOriginal arguments: ""); System.out.print(arg); System.out.print(""ntNew arguments: ""); System.out.print(newArg); System.out.println('"'); this.i.foo(newArg); return null; } else { return aMethod.invoke(this.i, someArgs); } } } –Givenanobjecto,instanceofC –WithoutchangingoorC –Changethebehaviourofo.foo()
  • 76. 76/210 Scenarios  Scenario 4: final I o = new C(42); o.foo("This is o: "); final InvocationHandler handler = new InvokationHandler(o); final I proxy = (I) Proxy.newProxyInstance( I.class.getClassLoader(), new Class[] { I.class }, handler); Assert.assertTrue(proxy instanceof I); Assert.assertFalse(proxy instanceof C); Assert.assertTrue(proxy.equals(o)); proxy.foo("This is o: "); – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 77. 77/210 Scenarios  Scenario 4: final I o = new C(42); o.foo("This is o: "); final InvocationHandler handler = new InvokationHandler(o); final I proxy = (I) Proxy.newProxyInstance( I.class.getClassLoader(), new Class[] { I.class }, handler); Assert.assertTrue(proxy instanceof I); Assert.assertFalse(proxy instanceof C); Assert.assertTrue(proxy.equals(o)); proxy.foo("This is o: "); Properties of the proxy ensured by the Java VM – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 79. 79/210 Scenarios  Smalltalk – Everything is an object – Everything is an object, really static
  • 80. 80/210 Scenarios  Smalltalk – SmalltalkImage is the class that “represent[s] the current image and runtime environment, including system organization, the virtual machine, object memory, plugins, and source files. [Its] instance variable #globals is a reference to the system dictionary of global variables and class names. [Its] singleton instance is called Smalltalk.”
  • 81. 81/210 Scenarios  Smalltalk – Object is “the root class for almost all of the other classes in the class hierarchy. […] Class Object provides default behavior common to all normal objects, such as access, copying, comparison, error handling, message sending, and reflection. Also utility messages that all objects should respond to are defined here.”
  • 82. 82/210 Scenarios  Smalltalk – Class “[adds] instance-specific behavior to various class-describing objects in the system. This typically includes messages for initializing class variables and instance creation messages particular to a class. There is only one instance of a particular Metaclass, namely the class which is being described.”
  • 83. 83/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo Object subclass: #C instanceVariableNames: 'i' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'.
  • 84. 84/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo Identify all the methods available on o an IdentitySet(#handles: #longPrintString #actionMap #hasContentsInExplorer [...] #foo: [...] #i: [...] #creationStamp) Invoke a method using its name foo This is foo: 42
  • 85. 85/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo |o| o := C newWithi: 42. Transcript show: 'Identify all the methods available on o' ; cr. Transcript show: C allSelectors ; cr. Transcript show: 'Invoke a method using its name foo' ; cr. (C compiledMethodAt: #foo:) valueWithReceiver: o arguments: #('This is foo: ').
  • 86. 86/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo |o| o := C newWithi: 42. Transcript show: 'Identify all the methods available on o' ; cr. Transcript show: C allSelectors ; cr. Transcript show: 'Invoke a method using its name foo' ; cr. (C compiledMethodAt: #foo:) valueWithReceiver: o arguments: #('This is foo: '). Simple and straightforward
  • 87. 87/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time Object subclass: #C instanceVariableNames: 'i' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'.
  • 88. 88/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time Save on disk the complete state of o 42 Restore from disk the object o at a later time This is foo on o2: 43
  • 89. 89/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time |o1 o2| o1 := C newWithi: 42. Transcript show: 'Save on disk the complete state of o' ; cr. Transcript show: (o1 instVarAt: 1) ; cr. Transcript show: 'Restore from disk the object o at a later time' ; cr. o2 := C new. o2 instVarNamed: 'i' put: 43. o2 foo: 'This is foo on o2: '.
  • 90. 90/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time |o1 o2| o1 := C newWithi: 42. Transcript show: 'Save on disk the complete state of o' ; cr. Transcript show: (o1 instVarAt: 1) ; cr. Transcript show: 'Restore from disk the object o at a later time' ; cr. o2 := C new. o2 instVarNamed: 'i' put: 43. o2 foo: 'This is foo on o2: '. Again, simple and straightforward
  • 91. 91/210 Scenarios  Scenario 2: – Pharo (a recent implementation of Smalltalk) provides is a general object serialiser that can serialise any object – Uses reflection to implement these methods! – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time 1@2 serializeToFileNamed: 'hello.fuel'. FLMaterializer materializeFromFileNamed: 'hello.fuel' Thanks to Marcus Denker for pointing out these helper methods
  • 92. 92/210 Scenarios  Scenario 3: Object subclass: #C instanceVariableNames: 'i' classVariableNames: 'NumberOfInstances' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 93. 93/210 Scenarios  Scenario 3: Object subclass: #C instanceVariableNames: 'i' classVariableNames: 'NumberOfInstances' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends Only difference with Scenarios 1 and 2
  • 94. 94/210 Scenarios  Scenario 3: C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 95. 95/210 Scenarios  Scenario 3: C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'. Same as Scenarios 1 and 2 – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 96. 96/210 Scenarios  Scenario 3: C class compile: 'initialize NumberOfInstances := 0.'. C class compile: 'new NumberOfInstances := NumberOfInstances + 1. ^ self basicNew initialize.'. C class compile: 'numberOfInstances ^ NumberOfInstances.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 97. 97/210 Scenarios  Scenario 3: C class compile: 'initialize NumberOfInstances := 0.'. C class compile: 'new NumberOfInstances := NumberOfInstances + 1. ^ self basicNew initialize.'. C class compile: 'numberOfInstances ^ NumberOfInstances.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends “Write access” to the metaclass
  • 98. 98/210 Scenarios  Scenario 3: |o1 o2 o3| C initialize. o1 := C newWithi: 42. o2 := C newWithi: 1. o3 := C newWithi: 100. Transcript show: o1 ; show: ' ' ; show: o2 ; show: ' ' ; show: o3 ; cr. Transcript show: C numberOfInstances. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 99. 99/210 Scenarios  Scenario 3: a C a C a C 3 – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 100. 100/210 Scenarios  Scenario 3: a C a C a C 3 To fulfill this scenario, we modified C class not C – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 101. 101/210 Scenarios  Scenario 3: In Smalltalk, each class has one anonymous meta-class, which can be modified • Adding new variables and methods which are thus class variables and class methods • These methods apply on the class, these fields belong to the class (thus unique) – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 102. 102/210 Scenarios  Scenario 3: – What about a subclass D of C? – How would its instances be counted? a C a C a C 3 – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends Thanks to Christophe Dony for suggesting this use of class vs. class instance variables
  • 103. 103/210 Scenarios  Scenario 3: – In C++ and Java: static = global • The class variables is shared by all the instances of its declaring class… and its subclasses! final D o4 = new D(); // Eclipse advises to use C to call getNumberOfInstances(). System.out.println(o4); System.out.println(D.getNumberOfInstances()); – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 104. 104/210 Scenarios  Scenario 3: – In Smalltalk: class vs. class instance • Class variable vs. class instance variable – A class variable is shared by all the instance of the class and all the instances of its subclasses – A class instance variable is unique to each class, inherited from the super-class, like instance variables C class instanceVariableNames: 'IndividualClassNumberOfInstances' – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 105. 105/210 Scenarios  Scenario 3: – In Smalltalk: class vs. class instance C subclass: #D instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Ptidej'. D class compile: 'initialize IndividualClassNumberOfInstances := 0.'. D class compile: 'new NumberOfInstances := NumberOfInstances + 1. IndividualClassNumberOfInstances := IndividualClassNumberOfInstances + 1. ^ self basicNew initialize.'. D class compile: 'numberOfInstances ^ NumberOfInstances.'. D class compile: 'individualClassNumberOfInstances ^ IndividualClassNumberOfInstances.'. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 106. 106/210 Scenarios  Scenario 3: – In Smalltalk: class vs. class instance | o4 | D initialize. o4 := D new. Transcript show: o4 ; cr. Transcript show: C numberOfInstances ; cr. Transcript show: D numberOfInstances ; cr. Transcript show: D individualClassNumberOfInstances ; cr. – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends a D 4 4 1
  • 107. 107/210 Scenarios  Scenario 3: – In Java: the JVM contains the world • Possible to connect to a JVM using the Java Debug Interface of the Java Platform Debug Architecture • Possible to reify the classes existing in the remote JVM and to obtain their instances com.sun.jdi.ReferenceType.instances(long) • Special feature of the JVM, “outside” of the normal constructs of the language – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends http://stackoverflow.com/questions/1947122/ is-there-a-simple-way-of-obtaining-all-object-instances-of-a-specific-class-in-j/1947200#1947200
  • 108. 108/210 Scenarios  Scenario 3: – In Smalltalk: the image contains the world • Possible to ask it all the instances of a particular class or all the instances currently in memory Transcript show: (C allInstances size). – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends Thanks to Marcus Denker for pointing out this solution
  • 109. 109/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() Object subclass: #C instanceVariableNames: 'i' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'.
  • 110. 110/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() This is o: 42 Intercepting message send: foo: Original arguments: This is o: New arguments: THIS IS O: THIS IS O: 42
  • 111. 111/210 Scenarios  Scenario 4: Several choices • ObjectWrappers: http://magaloma.seasidehosting.st/ Kernel#ObjectTracer • MethodWrappers: http://pharo.gforge.inria.fr/ PBE1/PBE1ch15.html • Reflectivity: http://scg.unibe.ch/Research/Reflectivity • … – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 112. 112/210 Scenarios  Scenario 4: Several choices • ObjectWrappers: http://magaloma.seasidehosting.st/ Kernel#ObjectTracer • MethodWrappers: http://pharo.gforge.inria.fr/ PBE1/PBE1ch15.html • Reflectivity: http://scg.unibe.ch/Research/Reflectivity • … – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 113. 113/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() | o aWrapper | o := C newWithi: 42. o foo: 'This is o: '. aWrapper := WrapperForC on: o. "o become: aWrapper." aWrapper foo: 'This is o: '. aWrapper xxxUnTrace.
  • 114. 114/210  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() ObjectTracer subclass: #WrapperForC instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. WrapperForC compile: 'doesNotUnderstand: aMessage "Intercept the selector foo:" | sel arg newArg | sel := aMessage selector. sel = ''foo:'' ifTrue: [ arg := (aMessage arguments) at: 1. newArg := arg asUppercase. Transcript show: ''Intercepting message send: '' ; show: sel ; cr. Transcript tab ; show: ''Original arguments: '' ; show: arg ; cr. Transcript tab ; show: ''New arguments: '' ; show: newArg ; cr. aMessage argument: newArg. aMessage sendTo: (self xxxViewedObject) ] ifFalse: [ "Transcript show: aMessage." ]'.
  • 115. 115/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() This is o: 42 Intercepting message send: foo: Original arguments: This is o: New arguments: THIS IS O: THIS IS O: 42 | o aWrapper | o := C newWithi: 42. o foo: 'This is o: '. aWrapper := WrapperForC on: o. "o become: aWrapper." aWrapper foo: 'This is o: '. aWrapper xxxUnTrace.
  • 116. 116/210 Scenarios  Scenario 4: – We created the class WrappedForC that does not understand many messages (as subclass of ProtoObject) – We wrapped an instance of WrappedForC around o and use doesNotUnderstand: to proxy messages – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 117. 117/210 Scenarios  Scenario 4: – We created the class WrappedForC that does not understand many messages (as subclass of ProtoObject) – We wrapped an instance of WrappedForC around o and use doesNotUnderstand: to proxy messages – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 118. 118/210 Scenarios  Scenario 4: Several choices • ObjectWrappers: http://magaloma.seasidehosting.st/ Kernel#ObjectTracer • MethodWrappers: http://pharo.gforge.inria.fr/ PBE1/PBE1ch15.html • Reflectivity: http://scg.unibe.ch/Research/Reflectivity • … – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 119. 119/210 Scenarios  Reflectivity – Marcus Denker, RMOD Team, INRIA Lille, and others – Extensions to the standard reflection features of Smalltalk (both structural and behavioural) • Structural reflection is extended by sub-method reflection: method bodies are first-class • Behavioural reflection is provided by Geppetto, an implementation of Partial Behavioural Reflection
  • 120. 120/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() Object subclass: #C instanceVariableNames: 'i' classVariableNames: '' poolDictionaries: '' category: 'CSE3009'. C class compile: 'newWithi: anInt ^(self new) i: anInt ; yourself.'. C compile: 'foo: aText Transcript show: aText. Transcript show: i. Transcript cr.'. C compile: 'i: anInt i := anInt.'.
  • 121. 121/210 Scenarios  Scenario 4: – Sub-method reflection – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() nodes := (C>>#foo:) sends select: [:each | ((each selector ~= #show:) or: (each arguments) size ~= 1) ifTrue: [ false ] ifFalse: [ (each arguments at: 1) name = 'aText'. ]. ].
  • 122. 122/210 Scenarios  Scenario 4: – Meta-object – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() gpLink := GPLink metaObject: [:arg1 :node | | newArg | newArg := arg1 asUppercase. Transcript show: 'Intercepting message send: '. Transcript show: node ; cr. Transcript tab ; show: 'Original arguments: '. Transcript show: arg1 ; cr. Transcript tab ; show: 'New arguments: '. Transcript show: newArg ; cr. Transcript show: newArg. ]. gpLink control: #instead.
  • 123. 123/210 Scenarios  Scenario 4: – Linking – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() o := C newWithi: 42. o foo: 'This is o: '. nodes do: [:node | node link: gpLink]. o foo: 'This is o: '. gpLink uninstall. This is o: 42 Intercepting message send: foo: Original arguments: This is o: New arguments: THIS IS O: THIS IS O: 42
  • 124. 124/210 Scenarios  Scenarios 1, 2, 3, and 4 More difficult to implement “as is” • http://stackoverflow.com/questions/359237/why-does- c-not-have-reflection • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ 2005/n1751.html
  • 125. 125/210 Scenarios  Scenarios 1, 2, 3, and 4 Third-party solutions • Mirror: http://kifri.fri.uniza.sk/~chochlik/mirror- lib/html/index.html#introduction • VisualStudio.NET: http://msdn.microsoft.com/en- us/library/y0114hz2%28v=vs.110%29.aspx • …
  • 126. 126/210 Scenarios  Scenarios 1, 2, 3, and 4 Third-party solutions • Mirror: http://kifri.fri.uniza.sk/~chochlik/mirror- lib/html/index.html#introduction • VisualStudio.NET: http://msdn.microsoft.com/en- us/library/y0114hz2%28v=vs.110%29.aspx • …
  • 127. 127/210 Scenarios  Mirror – Matúš Chochlík, University of Žilina, Žilina, Slovakia “[C]ompile-time and run-time meta-data describing C++ constructs like namespaces, types typedef-ined types, enums, classes with their base classes, member variables, constructors, member functions, etc.”
  • 128. 128/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo namespace cse3009 { class C { private: int i; public: C(const int _i) : i(_i) { } int get_i(void) const { return this->i; } void set_i(const int _i) { this->i = _i; } void foo(const std::string _s) const { std::cout << _s << this->i << std::endl; } }; }
  • 129. 129/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo Identify all the methods available on o (The type of o is cse3009::C) cse3009::C::i cse3009::C::foo Invoke a method using its name foo This is foo: 42
  • 130. 130/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo int main(void) { cse3009::C * o = new cse3009::C(42); std::cout << "Identify all the methods available on o" << std::endl; identify_members(o); std::cout << "Invoke a method using its name foo" << std::endl; invoke_member_function(o); return 0; }
  • 131. 131/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo template<typename O> void identify_members(O * _o) { using namespace mirror; typedef MIRRORED_CLASS(O) meta_Class; std::cout << "t(The type of o is " << meta_Class::full_name() << ")" << std::endl; std::cout << "t"; mp::for_each_ii< all_member_variables<meta_Class> >(info_printer()); std::cout << std::endl << "t"; mp::for_each_ii< member_functions<meta_Class> >(info_printer()); std::cout << std::endl; }
  • 132. 132/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo template<typename O> void invoke_member_function(O * _o) { using namespace mirror; typedef MIRRORED_CLASS(cse3009::C) meta_Class; typedef mp::at_c<overloads< mp::at_c<member_functions<meta_Class>, 0>::type>, 0>::type meta_foo; my_invoker_maker::invoker<meta_foo>::type invoker( std::string("tThis is foo: ")); invoker.call_on(*_o); }
  • 133. 133/210 Scenarios  Mirror – Provides essentially the same concepts and features as java.lang.reflect of Java – Uses templates and (manual) registration to collect metadata that does not exist unless manually created through macro preprocessing
  • 134. 134/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo MIRROR_REG_BEGIN MIRROR_QREG_GLOBAL_SCOPE_NAMESPACE(std) MIRROR_REG_CLASS_BEGIN(struct, std, string) MIRROR_REG_CLASS_END MIRROR_QREG_GLOBAL_SCOPE_NAMESPACE(cse3009) MIRROR_REG_CLASS_BEGIN(class, cse3009, C) MIRROR_REG_CLASS_MEM_VARS_BEGIN MIRROR_REG_CLASS_MEM_VAR_GET_SET( private, _, int, i, _.get_i(), _.set_i(_i)) MIRROR_REG_CLASS_MEM_VARS_END MIRROR_REG_MEM_FUNCTIONS_BEGIN MIRROR_REG_MEM_OVLD_FUNC_BEGIN(foo) MIRROR_REG_MEM_FUNCTION_BEGIN(public, _, void, foo, 1) MIRROR_REG_MEM_FUNCTION_PARAM(std::string, _s) MIRROR_REG_MEM_FUNCTION_END(1, _) MIRROR_REG_MEM_OVLD_FUNC_END(foo) MIRROR_REG_MEM_FUNCTIONS_END MIRROR_REG_CLASS_END MIRROR_REG_END
  • 135. 135/210 Scenarios  Scenario 1: – Given a class C – Given an object o, instance of C – Identify all the methods available on o – Invoke a method using its name foo template<class Unused> struct my_manufacturer<std::string, Unused> { const std::string s; template<class ConstructionInfo> inline my_manufacturer(const std::string _s, const ConstructionInfo construction_info) : s(_s) { } void finish(std::string) const { } inline std::string operator()(void) const { return s; } }; typedef mirror::invoker_maker<my_manufacturer, mirror::default_fact_suppliers, my_enumerator, void> my_invoker_maker;
  • 136. 136/210 Scenarios  Mirror – Uses complex code that can be easily and advantageously hidden in libraries – Will possibly become part of Boost and the standard reflection library for C++ • http://kifri.fri.uniza.sk/~chochlik/jtc1_sc22_wg21/ std_cpp_refl-latest.pdf
  • 137. 137/210 Scenarios  Scenario 2: namespace cse3009 { class C { private: int i; public: C(const int _i) : i(_i) { } int get_i(void) const { return this->i; } void set_i(const int _i) { this->i = _i; } void foo(const std::string _s) const { std::cout << _s << this->i << std::endl; } }; } – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time
  • 138. 138/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time Save on disk the complete state of o (The type of o is cse3009::C) cse3009::C::i = 42 Restore from disk the object o at a later time 43
  • 139. 139/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time int main(void) { cse3009::C * o = new cse3009::C(42); std::cout << "Save on disk the complete state of o" << std::endl; save_on_disk(o); std::cout << "Restore from disk the object o at a later time" << std::endl; restore_from_disk<cse3009::C>(); return 0; }
  • 140. 140/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<typename O> void save_on_disk(O * _o) { using namespace mirror; typedef MIRRORED_CLASS(O)meta_Class; std::cout << "t(The type of o is " << meta_Class::full_name() << ")" << std::endl << "t"; mp::for_each_ii<all_member_variables<meta_Class>>( info_printer_variables<O>(*_o)); std::cout << std::endl; }
  • 141. 141/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<class O> struct info_printer_variables { O o; inline info_printer_variables(O _o) : o(_o) { } template<class IterInfo> void operator()(IterInfo) { using namespace mirror; std::cout << IterInfo::type::full_name() << " = " << IterInfo::type::get(o); if (!IterInfo::is_last::value) std::cout << ", "; } };
  • 142. 142/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<class O> struct info_printer_variables { O o; inline info_printer_variables(O _o) : o(_o) { } template<class IterInfo> void operator()(IterInfo) { using namespace mirror; std::cout << IterInfo::type::full_name() << " = " << IterInfo::type::get(o); if (!IterInfo::is_last::value) std::cout << ", "; } }; Get the value of reflected variable
  • 143. 143/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<typename O> void restore_from_disk(void) { using namespace mirror; typedef typename my_factory_maker::factory<O>::type my_factory_type; my_factory_type my_factory(43); O o(my_factory()); std::cout << "t" << o.get_i() << std::endl; }
  • 144. 144/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time typedef mirror::factory_maker< my_manufacturer, mirror::default_fact_suppliers, my_enumerator, void> my_factory_maker;
  • 145. 145/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time typedef mirror::factory_maker< my_manufacturer, mirror::default_fact_suppliers, my_enumerator, void> my_factory_maker; Factory generating instances of (possibly) different types
  • 146. 146/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<class Unused> struct my_manufacturer<void, Unused> { template<typename Context> my_manufacturer(int _value, Context) { } void finish(int) { } template<class ConstructionInfo> inline int add_constructor( int _value, ConstructionInfo) const { return _value; } inline int index(void) { return 0; } };
  • 147. 147/210 Scenarios  Scenario 2: – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time template<class Unused> struct my_manufacturer<void, Unused> { template<typename Context> my_manufacturer(int _value, Context) { } void finish(int) { } template<class ConstructionInfo> inline int add_constructor( int _value, ConstructionInfo) const { return _value; } inline int index(void) { return 0; } }; To pass on to the constructor
  • 148. 148/210 template<class Product, typename IsEnum> struct my_base_manufacturer { Product x; struct constr_param_name_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << ", "; std::cout << IterInfo::type::base_name(); } }; struct constr_context_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << "::"; std::cout << IterInfo::type::base_name(); } }; template<class ConstructionInfo> my_base_manufacturer(int tabs, ConstructionInfo construction_info, const Product& _x) : x(tabs) { } void finish(int) { } inline Product operator()(void) { return x; } }; template<class Product, class Unused> struct my_enumerator : my_base_manufacturer<Product, std::true_type> { template<class ConstructionInfo> inline my_enumerator(int tabs, ConstructionInfo construction_info) : my_base_manufacturer<Product, std::true_type>( tabs, construction_info, Product()) { } void finish(int) { } inline Product operator()(void) { return NULL; } }; template<class Product, class Unused> struct my_manufacturer { typedef typename mirror::factory_maker< my_manufacturer, mirror::default_fact_suppliers, my_enumerator, Unused> maker; typename maker::template factory<Product>::type f; template<class ConstructionInfo> inline my_manufacturer( int _value, ConstructionInfo construction_info) : f(construction_info) { } void finish(int) { } inline Product operator()(void) { return f(); } };
  • 149. 149/210 template<class Product, typename IsEnum> struct my_base_manufacturer { Product x; struct constr_param_name_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << ", "; std::cout << IterInfo::type::base_name(); } }; struct constr_context_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << "::"; std::cout << IterInfo::type::base_name(); } }; template<class ConstructionInfo> my_base_manufacturer(int tabs, ConstructionInfo construction_info, const Product& _x) : x(tabs) { } void finish(int) { } inline Product operator()(void) { return x; } }; template<class Product, class Unused> struct my_enumerator : my_base_manufacturer<Product, std::true_type> { template<class ConstructionInfo> inline my_enumerator(int tabs, ConstructionInfo construction_info) : my_base_manufacturer<Product, std::true_type>( tabs, construction_info, Product()) { } void finish(int) { } inline Product operator()(void) { return NULL; } }; template<class Product, class Unused> struct my_manufacturer { typedef typename mirror::factory_maker< my_manufacturer, mirror::default_fact_suppliers, my_enumerator, Unused> maker; typename maker::template factory<Product>::type f; template<class ConstructionInfo> inline my_manufacturer( int _value, ConstructionInfo construction_info) : f(construction_info) { } void finish(int) { } inline Product operator()(void) { return f(); } }; Less complex than it looks!
  • 150. 150/210 template<class Product, typename IsEnum> struct my_base_manufacturer { Product x; struct constr_param_name_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << ", "; std::cout << IterInfo::type::base_name(); } }; struct constr_context_printer { template<class IterInfo> inline void operator()(IterInfo) const { if (!IterInfo::is_first::value) std::cout << "::"; std::cout << IterInfo::type::base_name(); } }; template<class ConstructionInfo> my_base_manufacturer(int tabs, ConstructionInfo construction_info, const Product& _x) : x(tabs) { } void finish(int) { } inline Product operator()(void) { return x; } }; template<class Product, class Unused> struct my_enumerator : my_base_manufacturer<Product, std::true_type> { template<class ConstructionInfo> inline my_enumerator(int tabs, ConstructionInfo construction_info) : my_base_manufacturer<Product, std::true_type>( tabs, construction_info, Product()) { } void finish(int) { } inline Product operator()(void) { return NULL; } }; template<class Product, class Unused> struct my_manufacturer { typedef typename mirror::factory_maker< my_manufacturer, mirror::default_fact_suppliers, my_enumerator, Unused> maker; typename maker::template factory<Product>::type f; template<class ConstructionInfo> inline my_manufacturer( int _value, ConstructionInfo construction_info) : f(construction_info) { } void finish(int) { } inline Product operator()(void) { return f(); } }; Less complex than it looks!Can be replaced by existing factories
  • 151. 151/210 Scenarios  Scenario 2: – Mirror provides many ready-to-use factories • From strings (mirror/example/factories/tetrahedron_script.cpp) • From a SOCI database (mirror/example/factories/tetrahedron_soci.cpp) – Given an object o, instance of C – Save on disk the complete state of o – Restore from disk the object o at a later time // make the input object for the factory script_factory_input in; // create a factory plugged with the script parser script_factory_maker::factory<tetrahedron>::type f = in.data(); // make a tetrahedron object factory soci_quick_factory_maker::factory<test::tetrahedron>::type tetrahedron_factory = soci_fact_data(r); while(r != e) { test::tetrahedron t = tetrahedron_factory(); // and write it to std output std::cout << stream::to_json::from(t, [&i](std::ostream& out) { out << "tetrahedron_" << i; } ) << std::endl;
  • 152. 152/210 Scenarios  Scenario 3: namespace cse3009 { class C { private: int i; static int numberOfInstances; public: C(const int _i) : i(_i) { numberOfInstances++; } ... void foo(const std::string _s) const { std::cout << _s << this->i << std::endl; } static int getNumberOfInstances() { return numberOfInstances; } }; } – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 153. 153/210 Scenarios  Scenario 3: int cse3009::C::numberOfInstances = 0; int main(void) { cse3009::C * o1 = new cse3009::C(42); cse3009::C * o2 = new cse3009::C(1); cse3009::C * o3 = new cse3009::C(100); std::cout << o1 << std::endl << o2 << std::endl << o3 << std::endl; std::cout << cse3009::C::getNumberOfInstances() << std::endl; return 0; } – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 154. 154/210 Scenarios  Scenario 3: 0x800418f8 0x80041908 0x80041918 3 – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends
  • 155. 155/210 Scenarios  Scenario 3: 0x800418f8 0x80041908 0x80041918 3 – Given a class C – Record the numbers of its instance ever created – Report this number when the program ends To fulfill this scenario, we must modify C as in Java
  • 156. 156/210 Scenarios  Scenario 4: – Several choices • Bjarne Stroustrup's Template: http://www.stroustrup.com/wrapper.pdf • Herb Sutter's Functor-based Approach: http://channel9.msdn.com/Shows/Going+Deep/ C-and-Beyond-2012-Herb-Sutter-Concurrency-and- Parallelism • Ion Armagedescu’s CPatcher: http://www.codeproject.com/Articles/34237/A-C-Style- of-Intercepting-Functions – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 157. 157/210 Scenarios  Scenario 4: – Several choices • Bjarne Stroustrup's Template: http://www.stroustrup.com/wrapper.pdf • Herb Sutter's Functor-based Approach: http://channel9.msdn.com/Shows/Going+Deep/ C-and-Beyond-2012-Herb-Sutter-Concurrency-and- Parallelism • Ion Armagedescu’s CPatcher: http://www.codeproject.com/Articles/34237/A-C-Style- of-Intercepting-Functions – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 158. 158/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() Bjarne Stroustrup's Template: (Prefix::operator->()) This is o: 42
  • 159. 159/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() int main(void) { std::cout << "Bjarne Stroustrup's Template:" << std::endl; cse3009::C o2(42); Prefix<cse3009::C> prefixed_o2(&o2); prefixed_o2->foo("This is o: "); std::cout << std::endl; return 0; }
  • 160. 160/210 Scenarios  Scenario 4: – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() template<class T> class Prefix { T* p; public: Prefix(T * _p) : p(_p) { } T* operator->() { std::cout << "(Prefix::operator->())" << std::endl; return p; } };
  • 161. 161/210 Scenarios  Scenario 4: – Is similar to a proxy in Java – Cannot easily access and modify the arguments of the proxy’ed method call – Makes it difficult to do something after the original method call – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 162. 162/210 Scenarios  Scenario 4: – Several choices • Bjarne Stroustrup's Template: http://www.stroustrup.com/wrapper.pdf • Herb Sutter's Functor-based Approach: http://channel9.msdn.com/Shows/Going+Deep/ C-and-Beyond-2012-Herb-Sutter-Concurrency-and- Parallelism • Ion Armagedescu’s CPatcher: http://www.codeproject.com/Articles/34237/A-C-Style- of-Intercepting-Functions – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 163. 163/210 Scenarios  Scenario 4: Dependent on the compiler! GCC v4.8.2 vs. Microsoft Visual Studio Express 2013 – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() Visual C++ 2013 06157-004-0441005-02428
  • 164. 164/210 Scenarios  Scenario 4: – GCC v4.8.2 In file included from ..Sourcescenario4.cpp:32:0: ..Source../CPatcher/patcher.h: In instantiation of 'void CPatch::HookClassFunctions(T1&, T2, bool, bool) [with T1 = void (cse3009::C::*)(std::basic_string<char>); T2 = void (class_for_patches::*)(std::basic_string<char>)]': ..Source../CPatcher/patcher_defines.h:131:2: required from 'CPatch::CPatch(TReturnVal (TClassSource::*&)(TArg1), TReturnVal (TClassTarget::*)(TArg1), bool, bool) [with TClassSource = cse3009::C; TClassTarget = class_for_patches; TReturnVal = void; TArg1 = std::basic_string<char>]' ..Sourcescenario4.cpp:52:61: required from here – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 165. 165/210 Scenarios  Scenario 4: – GCC v4.8.2 may not be legal • http://www.codeproject.com/Articles/34237/A-C-Style- of-Intercepting-Functions?msg=4796042 • http://stackoverflow.com/questions/1307278/casting- between-void-and-a-pointer-to-member-function – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() *reinterpret_cast<long*>(&fn_funcToHook) *reinterpret_cast<long*>(&fn_Hook)
  • 166. 166/210 Scenarios  Scenario 4: – Microsoft Visual Studio Express 2013 – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() void(ptidej::C::*pfn_foo)(const std::string) = &ptidej::C::foo; class proxy { public: void my_foo(const std::string s) { std::cout << "Function foo() is patched!" << std::endl << std::flush; (reinterpret_cast<ptidej::C*>(this)->*pfn_foo)(s); } }; int _tmain(int argc, _TCHAR* argv[]) { CPatch patch_aclass_doSomething(pfn_foo, &proxy::my_foo); ptidej::C o(42); o.foo(std::string("This is o: ")); return 0; }
  • 167. 167/210 Scenarios  Scenario 4: – Microsoft Visual Studio Express 2013 – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo() Function foo() is patched! This is o: 42
  • 168. 168/210 Scenarios  Scenario 4: – Is similar to a proxy in Java – Can easily access and modify the arguments of the proxy’ed method call – Makes it difficult to do something after the original method call – Given an object o, instance of C – Without changing o or C – Change the behaviour of o.foo()
  • 171. 171/210 Conclusion Java  Smalltalk  C++  Differences in semantics and syntax mostly due to the presence (or absence) of virtual machines
  • 172. 172/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 173. 173/210 Theory  Class – A programming construct that encapsulates some state (fields) and behaviours (methods) – A construct whose instances are objects  Metaclass – A programming construct that encapsulates some state (fields) and behaviours (methods) – A construct whose instances are classes Aristote (Ἀριστοτέλης) *-384 †-322
  • 174. 174/210 Theory  An object is an instance of a class – A class generates an object  A class is an instance of a metaclass – A metaclass generates a class  A metaclass is an instance of…
  • 175. 175/210 Theory  An object is an instance of a class – A class generates an object  A class is an instance of a metaclass – A metaclass generates a class  A metaclass is an instance of… (a) A meta-metaclass?
  • 176. 176/210 Theory  An object is an instance of a class – A class generates an object  A class is an instance of a metaclass – A metaclass generates a class  A metaclass is an instance of… (a) A meta-metaclass? (b) Itself?
  • 177. 177/210 Theory  An object is an instance of a class – A class generates an object  A class is an instance of a metaclass – A metaclass generates a class  A metaclass is an instance of… (a) A meta-metaclass? (b) Itself
  • 178. 178/210 Theory  The class Object is the parent of all classes, including metaclasses  The class Class is the generator of all classes, including Object
  • 179. 179/210 Des langages de programmation à objets à la représentation des connaissances à travers le MOP : vers une intégration par Gabriel Pavillet. Thèse de doctorat en Informatique sous la direction de Roland Ducournau, soutenue en 2000 à Montpellier 2
  • 180. 180/210 Theory  The classes – Class – Method – Field – … reify constructs of the programming languages, they become first-class entities, to allow programs to manipulate these constructs at runtime
  • 181. 181/210 Theory Java  Field  C  Method  C  Static field  C  Static method  C   Smalltalk  Instance variable  C  Instance method  C  Class variable  C class  Class method  C class  Class instance variables – To count the numbers of instances of subclasses of C (D, E…) independently from one another
  • 182. 182/210 Theory  Earlier, we said that reflection is of – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks
  • 183. 183/210 Theory  Earlier, we said that reflection is of – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks
  • 184. 184/210 Theory  Earlier, we said that reflection is of – Theoretical interest • What is an interpreter? Brian Cantwell Smith “Procedural Reflection in Programming Languages” (Ph.D. thesis, 1982) – Practical interest • Libraries • Frameworks A virtual machine is an interpreter
  • 185. 185/210 Theory  In Java, the metaclass is anonymous and cannot be modified  In Smalltalk, “[t]here is only one instance of a particular Metaclass, namely the class which is being described”
  • 186. 186/210 Theory  Many other variations are possible – LISP • http://www.cliki.net/mop – Perl 5, 6 • http://search.cpan.org/perldoc?Class::MOP – Python • https://www.python.org/doc/essays/metaclasses/ – MetaclassTalk – Noury Bouraqadi, Pierre Cointe • http://csl.ensm-douai.fr/MetaclassTalk – NeoClassTalk – Fred Rivard, Pierre Cointe • http://c2.com/cgi/wiki?NeoClassTalk – OpenC++ – Shigeru Chiba, Gregor Kiczales • http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/openc++.html
  • 187. 187/210 Theory  A Meta Object Protocol exposes some or all internal structure of the interpreter to the programmer  The MOP is (often) a set of classes and methods that allow a program to inspect the state of the supporting system and alter its behaviour
  • 188. 188/210 Theory  MOP can be accessible at – Compile-time • OpenJava – http://www.csg.ci.i.u-tokyo.ac.jp/openjava/ – Load-time • Javassist – http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/ – Run-time • AspectJ – http://eclipse.org/aspectj/
  • 189. 189/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 190. 190/210 Conclusion  Scenario 1: invoke an arbitrary method on an object (see the problems with instanceof and plugins)  Scenario 2: access the complete (including private) state of an object (see the problem with serialisation)  Scenario 3: count the number of instances of a class created at runtime (see the problem with debugging/profiling)  Scenario 4: modify the behaviour at run-time of a method without the need to recompile and restart the program (see the problem with patching)
  • 191. 191/210 Conclusion  Reflection helps addressing these scenarios – Depends on the capabilities of the programming language and underlying execution environment – Yields more or less elegant code  Use reflection sparingly and purposefully – Complexity – Performance
  • 194. 194/210 Conclusion Java  Smalltalk  C++  Differences in semantics and syntax mostly due to the presence (or absence) of virtual machines
  • 195. 195/210 Outline  Rationale  Definition  Context – Interconnections  Scenarios  Theory  Conclusion  Class Loading
  • 196. 196/210 Class Loading  Virtual machines – Interpreters – Closed world  Must – Access resources – Load classes
  • 197. 197/210 Class Loading  Virtual machines – Interpreters – Closed world  Must – Access resources – Load classes
  • 198. 198/210 Class Loading  Virtual machines – Interpreters – Closed world  Must – Access resources – Load classes
  • 199. 199/210 Class Loading  Example – Given an interface ICommand – Load at runtime a class implementing ICommand using its binary name • A binary name is in the form <pckg1>.….<pckgn>.<ClassName> – net.ptidej.reflection.java.scenario1.C final Class<ICommand> command = this.classLoader.loadClass(binaryName);
  • 202. 202/210 Class Loading public class ClassLoader extends java.lang.ClassLoader { private final String directory; public ClassLoader( final java.lang.ClassLoader parent, final String directory) { super(parent); this.directory = directory; }
  • 203. 203/210 Class Loading protected Class findClass(final String name) { Class newClass = null; try { newClass = super.findClass(name); } catch (final ClassNotFoundException cnfe) { final String osName = this.directory + name.replace('.', '/') + ".class"; try { final FileInputStream fis = new FileInputStream(osName); newClass = this.defineClasses(name, fis); } catch (final ClassFormatError cfe) { cfe.printStackTrace(Output.getInstance().errorOutput()); } catch (final FileNotFoundException fnfe) { // fnfe.printStackTrace(); } } return newClass; }
  • 204. 204/210 Class Loading protected Class findClass(final String name) { Class newClass = null; try { newClass = super.findClass(name); } catch (final ClassNotFoundException cnfe) { final String osName = this.directory + name.replace('.', '/') + ".class"; try { final FileInputStream fis = new FileInputStream(osName); newClass = this.defineClasses(name, fis); } catch (final ClassFormatError cfe) { cfe.printStackTrace(Output.getInstance().errorOutput()); } catch (final FileNotFoundException fnfe) { // fnfe.printStackTrace(); } } return newClass; } Use the method defined in the superclass on this CL
  • 205. 205/210 Class Loading private Class defineClasses(final String name, final InputStream inputStream) { try { int b; int length = 0; byte[] bytes = new byte[4]; while ((b = inputStream.read()) != -1) { if (length == bytes.length) { final byte[] temp = new byte[length + 4]; System.arraycopy(bytes, 0, temp, 0, length); bytes = temp; } bytes[length] = (byte) b; length++; } System.out.println(name); final Class newClass = this.defineClass(name, bytes, 0, length); return newClass; } catch (final IOException ioe) { return null; } catch (final NoClassDefFoundError ncdfe) { ncdfe.printStackTrace(Output.getInstance().errorOutput()); return null; } }
  • 206. 206/210 Class Loading private Class defineClasses(final String name, final InputStream inputStream) { try { int b; int length = 0; byte[] bytes = new byte[4]; while ((b = inputStream.read()) != -1) { if (length == bytes.length) { final byte[] temp = new byte[length + 4]; System.arraycopy(bytes, 0, temp, 0, length); bytes = temp; } bytes[length] = (byte) b; length++; } System.out.println(name); final Class newClass = this.defineClass(name, bytes, 0, length); return newClass; } catch (final IOException ioe) { return null; } catch (final NoClassDefFoundError ncdfe) { ncdfe.printStackTrace(Output.getInstance().errorOutput()); return null; } } Use the method defined in the superclass on this CL
  • 208. 208/210 Class Loading protected Class findClass(final String name) { Class newClass = null; try { newClass = this.getParent().loadClass(name); } catch (final ClassNotFoundException cnfe) { final String osName = this.directory + name.replace('.', '/') + ".class"; try { final FileInputStream fis = new FileInputStream(osName); newClass = this.defineClasses(name, fis); } catch (final ClassFormatError cfe) { cfe.printStackTrace(Output.getInstance().errorOutput()); } catch (final FileNotFoundException fnfe) { // fnfe.printStackTrace(); } } return newClass; }
  • 209. 209/210 Class Loading protected Class findClass(final String name) { Class newClass = null; try { newClass = this.getParent().loadClass(name); } catch (final ClassNotFoundException cnfe) { final String osName = this.directory + name.replace('.', '/') + ".class"; try { final FileInputStream fis = new FileInputStream(osName); newClass = this.defineClasses(name, fis); } catch (final ClassFormatError cfe) { cfe.printStackTrace(Output.getInstance().errorOutput()); } catch (final FileNotFoundException fnfe) { // fnfe.printStackTrace(); } } return newClass; } Ask the parent CL if it already knows the class
  • 210. 210/210 Conclusion  Virtual machines must access resources and load classes, in specific cases – Can extend ClassLoader – Must override (typically) method • Class findClass(String) – Must be careful with inheritance vs. delegation! • super vs. getParent()