Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Wiki Markup
{include:apache-felix-ipojo-header}
{html}
<div class="content">
{html}
h1. Dive into the iPOJO Manipulation depths
_
iPOJO (primitive) components are basedmanaged onusing abyte bytecodecode manipulation. Don't be afraid, you don't have to be fluent in bytecodebyte code to understand components ☺. This page explains how the manipulation works and how your class file is transformed. This manipulation takes care to *NOT* change the behavior of the manipulated class._

{div:class=toc}
{toc:maxLevel=4|minLevel=2}
{div}

h2. Why manipulating bundlesmanipulate bundle byte code?

The iPOJO byte code manipulation goals are twofoldtwo-fold:

• Preparing classes to be managed at runtimerun time and
• Translating XML or annotation metadata into an internal format avoiding runtimeto avoid run-time XML and annotation parsing.

!process.png!

iPOJO follows a container principlesapproach and more specially follows theemploys [inversion of control|http://en.wikipedia.org/wiki/Inversion_of_control] and [dependency injections|http://en.wikipedia.org/wiki/Dependency_injection]. The So, iPOJO container manages the classcomponent instantiation, and injection (service, properties and so on...). In orderTo to inject values and supervise the execution inside component implementation class, iPOJO providesuses an interception and injection framework. OneTo part offacilitate this, frameworkiPOJO isuses implementedclass asbyte a classcode manipulation. 

!injection.png!

Once manipulatedBesides manipulating byte code, iPOJO manipulation process translates the XML metadataor andannotation annotationsmetadata into an internal syntax. This avoids embedding a XML parser at runtime eliminates any run-time dependencies on the particular metadata format. 

h2. How Manipulationbundle byte ofcode theis bytecodemanipulated

For each class used as a ancomponent implementation class, the manipulation process prepares the class to be managed at run runtimetime. Basically, this means interception This means providing the ability to intercept methods and field accesses. This manipulation is notindependent dependent of the component type metadata. A component class will always resultsresult in the same final manipulated class, regardless of theits metadata. This allows using means it is possible to use a class as the implementation of several component types. As illustrated in the following image, the manipulated class instance interacts with an instance manager whichthat delegates to plugged handlers. The metadata impacts the set of plugged handler. So,handlers; it does not impact neither the manipulated class, nor the instance manager (which is the iPOJO container foundation).

!principles.png!

The following image explains what happens during the manipulation.

!manipulation.png!

First, each manipulated class implements the {{POJO}} interface. This interface introduces a method allowingto gettingget a reference onto the instance container of the class. So, you can detect thatwhether an object is managed by iPOJO by checking if the object implements this interface.
Moreover, aA special field, named {{\_\_IM}} is injected.  At runtime, thiswhich field contains a reference onto the instance container object ({{InstanceManager}} at run time. 

For each field, getter and setter methodmethods are generated. They are called {{\_\_get$FIELD_NAME}} and {{\_\_set$FIELD_NAME}}. Moreover aA boolean field is injected named {{\_\_F$FIELD_NAME}}. This flag enables or disables the container delegation for this field. When, the delegation is disabled, the field is managed as a regular field: getter and setter methods just return and set the field value. When the delegation is enabled, the field never receives a value., Thethe container stores the field value. The getter method asks to the container to get the value. The setter method asks to the container to update the stored value. All the field accesses (except ones from specific constructors) of the class are adapted to call the getter or the setter method.

In order to intercept methods, each method is substituted by a generated method. InEach fact, each method is renamed to {{\_\_METHOD_NAME}}, and becomes private. The original method is replaced by iPOJO code. This code allows method interception. As forwith fields, the method delegation is enabled or disabled by an injected Booleanboolean field. If the method hasis not to be intercepted, the iPOJO-generated method (replacing the method) just calls the original method. Otherwise, the iPOJO-generated method notifies the container of method entries, exits, and potential errors.

Finally, the constructors are also manipulated. Empty constructors and constructors receiving a {{BundleContext}} object are manipulated as others methods. However, they receive another argument: the {{InstanceManager}}. This instance manager is set just after the call to the super constructor. While setting the instance manager, all flags enabling / disabling delegation are set. This allows using the component to use injected values inside the constructor code itself. Constructors receiving other kind of arguments are not manipulated, and so can be used to create non-managed instance. In this case, fields won't be delegated, and methods won't be intercepted.

h3. The annotation special case

The manipulation has a special behavior when a visible (at runtimerun time) method or constructor annotation is detected. As the methods are replaced by private methods, the annotations are moved to the iPOJO-generated replacementsmethods, such as in:

{code}
public class MyClass {
  @MyAnnotation
  public void myMethod() {
     //my code here
 }
}
{code}

is transformed into:

{code}
public class MyClass {
  @MyAnnotation
  public void myMethod() {
     // iPojo code here
 }
  private void _myMethod() {
   // my code here
 } 
{code}

h2. Avoiding XML at run runtimetime

iPOJO does not use XML or annotations at runtimerun time. The manipulation process replaces the XML or annotation metadata by an internal format (between LISP and XML). The XML or annotation metadata are translated and written insideinto the bundle manifest. MoreoverAdditionally, the componentvarious type declarationsinformation (<component>in XML element) are completed with manipulation metadata. Those metadata are the component metadata is computed during the byte bytecodecode manipulation andphase to avoid usinghaving to use reflection at run runtimetime (requiringwhich would require loading the class) to get class elements (such as available fields, methods, implemented interfaces, and so on).

If you want to see how XML or annotation metadata are _tortured_, just open the manifest file of a manipulated bundle, and look at the {{iPOJO-COMPONENTS}} entry (and appreciate the Lisp-like syntax :-))...

\\
\\
{include:apache-felix-ipojo-footer}