OSGi-friendly bytecode weaving – enhance your classes, not your dependency graph!

download OSGi-friendly bytecode weaving – enhance your classes, not your dependency graph!

If you can't read please download the document

Transcript of OSGi-friendly bytecode weaving – enhance your classes, not your dependency graph!

Centennial - White

OSGi-friendly bytecode weaving enhance your classes, not your dependency graph!

Tim Ward

What we're going to cover

What weaving is

How weaving is done in Java SE (10,000 foot view)

Why OSGi needs a different approach

How to use OSGi weaving hooks

How to do classpath scanning in OSGi

A real world demo using classpath scanning and weaving

What is bytecode weaving?

Simply put, bytecode weaving involves generating or editing code by directly modifying existing .class files

This can occur at different points in the application lifecycle At compile time

At packaging time

At class load time

After a class has been loaded

Weaving later is more flexible (to a point)

Outside a VM

Inside a VM

How do we normally weave bytecode?

In Java 1.4 you had to create your own ClassLoader and mess about with the class bytes before defineClass()

Java 5 introduced Java Agents and a defined transformation API (java.lang.instrument) ClassFileTransformers registered on a VM wide basis

Java 6 supports re-transformation (post class load) and addition of Java Agents to a running VM

In all cases we get an opportunity to read/change the bytes of the class file before they are loaded into the VM

Why do we need a Weaving Hook?

Clearly the base VM support exists already but...

OSGi is modular Java Agent Class transformation is VM wide

OSGi has a ClassLoader graph, not a flat classpath Weaving often adds new dependencies to a class

New dependencies cannot be loaded without being imported by the bundle hosting the woven class

How to use a Weaving Hook

This is very simple!

Register your implementation as a service using the org.osgi.framework.hooks.weaving.WeavingHook interface

Bundle

WeavingHook

The framework will call your hook for every class loaded by any bundle If security is on then you need AdminPermission WEAVE to make any changes for a given bundle

How to use a Weaving Hook (2)

You only implement a single method public void weave(WovenClass classInfo)

The WovenClass provides access to: The Bundle defining the class

Read/Replace the class bytes that will be used

The BundleWiring and Bundle ClassLoader

A List of dynamic package imports to add, this allows us to add new dependencies based on what we weave!

Working out what to weave

Most weavers use XML and annotations to configure which classes should be woven and what to do to them Annotations mean we need access to the class

We don't know the name of the class

In Java SE we tend to rely on searching the file system to find class files to load on the classpath OSGi does not (in general) let you do this

Scanning the bundle Classpath

The BundleWiring API adds a new method public Collection listResources( String path, String filePattern, int options )

This method lets us scan for resources on the classpath path can be used to specify a package folder

filePattern lets you specify a type (e.g. *.class)

options lets you specify whether to recurse into sub-packages, and whether to include resources that are imported from other bundles

Combining the two specifications

There are two options for scanning Up front

When the WeavingHook is called

The BundleWiring is accessible from the Bundle object using the adapt method bundle.adapt(BundleWiring.class);

The BundleWiring is also available from the WovenClass wovenClass.getBundleWiring();

Live demo!

The Apache Aries JPA container uses both scanning and a Weaving Hook to provide load-time entity enhancement Well it will once OSGi 4.3 is in Maven Central and I've finished the tests :)

Using a debugger we can see the various pieces in action!

Any Questions?

Apache Aries:

http://aries.apache.org/

Tim Ward:

@TimothyWard, [email protected]

2011 IBM Corporation