Playing with Java Classes
and Bytecode
What is a Class?
How it is loaded and used?
How can I write a code at runtime, usin...
Java Classloading
• Why do we care?
– Because if we gonna write code at runtime, we better know how
to load it and use it…...
Java Classloading
• So what is this classloader?
– It is a class written in Java (subclass of java.lang.ClassLoader), resp...
Java Classloading
Commandline Java App Tomcat (6)
Bootstrap
classloader
Ext
classloader
Application
/ System
classloader
A...
LETS TALK BUSINESS
Ok, we understand classes. Where is the cool stuff?
What we gonna talk about
• Aspect Oriented Programming
– Java Proxy
– Spring Aspects
– AspectJ Aspects
• Doing the real co...
The Java Proxy
• What it does
– It allows to implement one or more interfaces dynamically
• When to use it
– Generic imple...
The Java Proxy
• Example code
• The output
Spring AOP
• What it does
– Allows to intercept method calls to Spring beans, without the requirement for an
interface
– S...
Spring AOP
• Configuring Spring AOP
• Example Aspect
• Activating the Aspect
– Using Spring component scan, by adding the ...
AspectJ
• What it does
– Allows to intercept any Join Point such as method calls, exceptions, etc
– Allows writing aspects...
AspectJ
• Configuration options
– Compile time weaving
– Load time weaving
– Load time weaving with Spring
• Configuring A...
AspectJ
• META-INF/aop.xml
– declares the aspects for load time weaving and the target packages to weave into
• Class inst...
SHORT INTRO TO ASPECTJ
If we are talking about aspects…
Intro to AOP (AspectJ Style)
• Aspect – a concern that cuts across multiple classes. Examples are logging,
transaction han...
Intro to AOP (AspectJ Style)
• More on pointcuts
– Pointcuts are query expressions on the code.
– Can be joined using the ...
Intro to AOP (AspectJ Style)
• Some examples
– execution (int *())
• joinpoints who are method executions for methods who ...
Intro to AOP (AspectJ Style)
• Coding Aspects using AspectJ Java Syntax
• AspectJ AspectJ syntax
Intro to AOP (AspectJ Style)
• Adding code to existing classes using aspects (Inter-type declarations)
– Adding implemente...
Intro to AOP (AspectJ Style)
• Example of an aspect modifying a class
BACK TO THE COOL STUFF
Bootstrap classloader
• What it does
– Allows to replace java system classes
– Bypasses all java security policy set by Se...
Javaagent and Instrument
• What it does
– Allows to instrument / transform / change a class definition
as it is loaded
• W...
Writing Bytecode
• What it does
– Allows to write new classes or modify existing classes at runtime
– Load the new/modifie...
Writing Bytecode
• Limitations
– Hard to use
– Generated bytecode cannot be debugged normally - we do
not have the source ...
Writing Bytecode
• Class Generation by Example
– Write an example class of what you want to generate
– Compile it
– Run or...
Writing Bytecode
• Example – mapping objects from type A to type B
Using a superclass helper
–
– The example class
Writing Bytecode
• Running BCELifier on the class
– BCELifier has a main method, getting one parameter – the class name
• ...
Writing Bytecode
• Creating the Factory class (continued)
– Creating the constructor
– Which creates the constructor
Writing Bytecode
• Creating the Factory class (continued)
– Creating the mapToB method
public
Return type
Input arguments
...
Writing Bytecode
• Creating the Factory class (continued)
– Creating the mapToB method
Store the result as Object 2
Take O...
Writing Bytecode
• Creating the Factory class (continued)
– Creating the mapToB method
Store the result as Object 3
Create...
Writing Bytecode
• Creating the Factory class (continued)
– Creating the mapToB method
Pop the stack, writing the value to...
Writing Bytecode
• Creating the Factory class (continued)
– Creating the mapToB method – we got another mapToB method
– Th...
Writing Bytecode
• Using the generated class
– The Class loader
– Creating and loading the new class
– Add a method return...
IT IS THAT SIMPLE

Upcoming SlideShare
Loading in …5
×

Playing with Java Classes and Bytecode

1,095 views

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,095
On SlideShare
0
From Embeds
0
Number of Embeds
59
Actions
Shares
0
Downloads
29
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Playing with Java Classes and Bytecode

  1. 1. Playing with Java Classes and Bytecode What is a Class? How it is loaded and used? How can I write a code at runtime, using that code?
  2. 2. Java Classloading • Why do we care? – Because if we gonna write code at runtime, we better know how to load it and use it… – Because we do not really understand classes • So… what identifies a class? – It’s name – It’s package – It’s classloader • It means that – We can have multiple instances of a class loaded. – Two instances of the same class from different classloaders are not compatible and not assignable – Static variables are static only in the context of a classloader, not globally as we are always told.
  3. 3. Java Classloading • So what is this classloader? – It is a class written in Java (subclass of java.lang.ClassLoader), responsible to load other classes for use by the JVM – Arranged as a tree of classloaders • Bootstrap classloader – Loads the java system • jre/lib/resources.jar – series of resource files • jre/lib/rt.jar – the java.*, javax.*, etc packages • jre/lib/sunrsasign.jar • jre/lib/jsse.jar – secure socket extension • jre/lib/jce.jar – java cryptography extension • jre/lib/charsets.jar • jre/classes – The important stuff is in rt.jar – the base Java classes Bootstrap classloader Ext classloader Application / System classloader
  4. 4. Java Classloading Commandline Java App Tomcat (6) Bootstrap classloader Ext classloader Application / System classloader Application / System classloader Common classloader WAR 1 classloader WAR 2 classloader Loads the Application Jars from the classpath Loads just the bootstrap.jar and tomcat-juli.jar Loads the tomcat commons library jars Loads the jars in the webapp lib directory
  5. 5. LETS TALK BUSINESS Ok, we understand classes. Where is the cool stuff?
  6. 6. What we gonna talk about • Aspect Oriented Programming – Java Proxy – Spring Aspects – AspectJ Aspects • Doing the real cool stuff – The bootstrap classloader – The javaagent and class instrumentation – Writing bytecode at runtime
  7. 7. The Java Proxy • What it does – It allows to implement one or more interfaces dynamically • When to use it – Generic implementation of an interface – such as in the case of client code calling a service. The generic implementation can marshal the client method call to whatever “on-the-wire” format, saving the developer from coding stubs. – Simplistic aspect oriented programming – to catch method calls, perform some pre/post/around logic and delegate the call to the real implementation. Can be used for transaction handling, logging, etc. • Limitations – Can only function on Java interfaces – Intercepts only calls done on the proxy instance. When used on the delegate model, calls directly on the delegate will not be intercepted.
  8. 8. The Java Proxy • Example code • The output
  9. 9. Spring AOP • What it does – Allows to intercept method calls to Spring beans, without the requirement for an interface – Simplifies the code compared to the Java Proxy – Works in the proxy model – spring beans factory returns a proxy to the bean we intercept methods of – Allows using AspectJ selectors to select the methods to intercept – Aspects are written using the AspectJ Java syntax • When to use it – Aspect programming on Spring beans. – Transaction handling, logging, security handling – anything AOP is good for • Limitations – Can only function on Spring Beans – Intercepts only calls done on the proxy instance. Inner bean calls will not be intercepted – Supports only a small subset of AspectJ selectors – only the method execution join points are supported.
  10. 10. Spring AOP • Configuring Spring AOP • Example Aspect • Activating the Aspect – Using Spring component scan, by adding the @Component annotation on the aspect – Using Spring Beans XML
  11. 11. AspectJ • What it does – Allows to intercept any Join Point such as method calls, exceptions, etc – Allows writing aspects using Java or AspectJ syntax – Changes the actual class bytecode – Allows using AspectJ selectors to select the methods to intercept – Change existing classes, adding methods, members and super-interfaces to them – Weaves aspects on load time or compile time • When to use it – Aspect programming on any Java object – Transaction handling, logging, security handling – anything AOP is good for – Introduce compiler like coding rules • Limitations – Requires custom Java Compiler (AspectJ compiler) – Or requires custom definitions for load time weaving (depending on run environment)
  12. 12. AspectJ • Configuration options – Compile time weaving – Load time weaving – Load time weaving with Spring • Configuring AspectJ Load time weaving with Spring – Simple, isn’t it? • Well, there are additional requirements • Dependencies – aspectjrt.jar must be in the classpath • (continues on next slide)
  13. 13. AspectJ • META-INF/aop.xml – declares the aspects for load time weaving and the target packages to weave into • Class instrumentation – Commandline & JUnit applications – using the -javaagent to load instrumentation jars • -javaagent:spring-instrument-<version>.jar -javaagent:aspectjweaver-<version>.jar – Maven running JUnit – using the maven-surefire-plugin, passing it the javaagent args – Note the two javaagent params must be at the same line – Tomcat 6 – • The jar spring-instrument-tomcat-<version>.jar has to be copied to tomcats lib directory • The webapp has to have a context.xml file in WEB-INFcontent.xml, with the minimum content – Note there are alternative locations for the context file. This is the location I find easiest to use.
  14. 14. SHORT INTRO TO ASPECTJ If we are talking about aspects…
  15. 15. Intro to AOP (AspectJ Style) • Aspect – a concern that cuts across multiple classes. Examples are logging, transaction handling, security, etc. • Join Point – a point during the execution of a program. Examples are when – A method is executed – A method is called – A constructor is executed – A constructor is called – An exception handler is executed – An advice is executed – Static initialization is executed – Initialization and pre-initialization of an object • Advice – action taken by the aspect at a particular pointcut. Types of advice – Before, after returning, after throwing, after finally, around • Pointcut – a selector of pointcuts using predicates. An advice is associated with a pointcut expression and runs on any point matched by the pointcut
  16. 16. Intro to AOP (AspectJ Style) • More on pointcuts – Pointcuts are query expressions on the code. – Can be joined using the and (‘&&’), or (‘||’) or not (‘!’) operators • Some pointcut predicates – execution(…) – when a particular method body executes – call(…) – when a method is called – handler(….) – when a particular exception handler executes – this(…) – when the currently executing object is of a certain type – target(…) – when the target object is of type – args(…) – when the method arguments match a certain type – within(…) – when the executing code belongs to a certain class – cflow(…) – when the program flow is in a certain method call (the method is a parent in the stack) – @annotation(…) – methods annotated with a certain annotation – @target(…) – then the target executing object has a certain annotation – @args(…) – when the runtime type of an argument has a certain annotation – @within(…) – limits to pointcuts within a class that has a certain annotation – bean(…) – a spring bean name Not Supported by Spring AOP Only Spring AOP
  17. 17. Intro to AOP (AspectJ Style) • Some examples – execution (int *()) • joinpoints who are method executions for methods who return an int and do not take parameters – @annotation(com.example.Log) && execution(* *(..)) • joinpoints who are method executions for methods annotated with the log annotation, regardless of the method return type, class, name or parameters – call(public * *(..)) • Call to any public method – !this(Point) && call(int *(..)) • any method call to an int method when the executing object is any type except Point. – cflow(P) && cflow(Q) • each join point that is in both the control flow of P and in the control flow of Q
  18. 18. Intro to AOP (AspectJ Style) • Coding Aspects using AspectJ Java Syntax • AspectJ AspectJ syntax
  19. 19. Intro to AOP (AspectJ Style) • Adding code to existing classes using aspects (Inter-type declarations) – Adding implemented interfaces – Changing the superclass of a class – Adding methods to a class – Adding variable to a class – Turning java into multiple inheritance system – change interfaces to include method implementation and variables • Using join points as compiler errors or warnings • SoftExceptions – catching an exception at a join point and replacing it with SoftException (subclass of RuntimeException) • Privileged aspects – Can access private, package and protected members of classes, bypassing the java member visibility constraints
  20. 20. Intro to AOP (AspectJ Style) • Example of an aspect modifying a class
  21. 21. BACK TO THE COOL STUFF
  22. 22. Bootstrap classloader • What it does – Allows to replace java system classes – Bypasses all java security policy set by SecurityManager • When to use it – Snuff inside the core Java APIs – Change core Java API functionality – Terracotta uses it to replace the Java HashMap class with a distributed cache implementation • Limitations – Classes loaded by the bootstrap classloader are not able to load classes not included in the bootstrap classloader jar list • Usage – With the java commandline options • –bootclasspath: - list of jars to use instead of the standard list • –bootclasspath/a: - list of jars to append to the standard list • –bootclasspath/p: - list of jars to prepend to the standard list
  23. 23. Javaagent and Instrument • What it does – Allows to instrument / transform / change a class definition as it is loaded • When to use it – AspectJ uses it for load time weaving – To modify classes as we load them • Limitations – It works on the class file bytes – requires intimate knowledge of the class file structure. Not very useful without a framework like AspectJ, BCEL, cglib, etc. • Usage – Using the –javaagent java commandline parameter to introduce an agent jar – The agent jar has to have a premain method • public static void premain(String agentArguments, Instrumentation instrumentation) – The Instrumentation class allows to redefine a class, add & remove transformers, and retransform a class. – ClassFileTransformer has one method to transform a class file bytes (as a byte[]).
  24. 24. Writing Bytecode • What it does – Allows to write new classes or modify existing classes at runtime – Load the new/modified classes – Instantiate them – Use them as any other Java class • When to use it – Performance – when a mapping library (in my case XML to objects) was too slow because of excessive use of reflections, coding simple mapping classes proved match faster – Implementing Proxies on any class – Spring AOP and Hibernate do just that – Hibernate uses bytecode modification of classes to introduce mechanisms for lazy loading of members – Adaptor for Beans – a reporting framework used reflection on beans to read the field definitions from in it’s Java Object datasource. When adapting a java query interface that returns Map like objects, we had to generate wrapper classes adapting the Map to the beans the framework expected.
  25. 25. Writing Bytecode • Limitations – Hard to use – Generated bytecode cannot be debugged normally - we do not have the source code  • BCEL – I have found using BCEL to be easiest for me • BCEL is included with JRE 1.6 under the package com.sun.org.apache.bcel – However, the JRE version did not work for me. – I have used the apache version – 5.2 • Guidelines – keep the generated code small. Use Helper methods / superclasses whenever you can. Remember, you can debug helper classes or superclasses, but you cannot debug generated bytecode. – Classes can be generated at build time or runtime. I have found runtime generation simpler to use – Use class generation by example • Good resource – http://java.sys-con.com/node/49088
  26. 26. Writing Bytecode • Class Generation by Example – Write an example class of what you want to generate – Compile it – Run org.apache.bcel.util.BCELifier. It will create java code, that when running it, will create a factory class that generates your example class. – You can also use org.apache.bcel.util.Class2-HTML to get HTML documentation of your example class bytecode. – Modify the generated factory class to generate the bytecode for the classes you want – Use org.apache.bcel.verifier.Verifier or com.pavelvlasov.codegen.ClassGeneratorBase.verify() to verify that the generated classes are valid – Use Jad, Jadclipse or DJ Java Decompiler to decompile generated files and verify method logic. I recommend that you set the "annotate" option so you can see the bytecode instruction as comments. • Class loading – Code a new subclass of ClassLoader – Use the defineClass (protected) method to define the new generated class – Remember to link your class loader to a parent class loader
  27. 27. Writing Bytecode • Example – mapping objects from type A to type B Using a superclass helper – – The example class
  28. 28. Writing Bytecode • Running BCELifier on the class – BCELifier has a main method, getting one parameter – the class name • The created factory class – Defining the class and the class members
  29. 29. Writing Bytecode • Creating the Factory class (continued) – Creating the constructor – Which creates the constructor
  30. 30. Writing Bytecode • Creating the Factory class (continued) – Creating the mapToB method public Return type Input arguments Input argument names Method name Class name
  31. 31. Writing Bytecode • Creating the Factory class (continued) – Creating the mapToB method Store the result as Object 2 Take Object 1 – the a parameter (Object 0 is this) Cast it to Person
  32. 32. Writing Bytecode • Creating the Factory class (continued) – Creating the mapToB method Store the result as Object 3 Create new PersonDTO Invoke the personDTO constructor
  33. 33. Writing Bytecode • Creating the Factory class (continued) – Creating the mapToB method Pop the stack, writing the value to the name property of object 3 Load object 3 to the stack - Person Read the name field from object 2 to the stack Load object 2 to the stack - PersonDTO
  34. 34. Writing Bytecode • Creating the Factory class (continued) – Creating the mapToB method – we got another mapToB method – The first has signature PersonDTO mapToB(Object) – The second has signature Object mapToB(Object) – The second overrides the superclass mapToB method and calls the first. – Guess narrowing the return type of mapToB was not a really good idea, given generated class loaded at runtime does not really benefit from the narrowed type constraint – 
  35. 35. Writing Bytecode • Using the generated class – The Class loader – Creating and loading the new class – Add a method returning JavaClass to the factory class – And use it Create the classloader Create the class factory Create the class bytecode Define the new class Load the new class Get the new class constructor Call the constructor
  36. 36. IT IS THAT SIMPLE 

×