Aspect Oriented Programming In Java ME

Do you want to structure your Java ME applications better? Aspect Oriented Programming is a cool technology that can modularize your applications and separate the verbose infrastructure code from the application logic. The only catch is that it doesn’t exist for Java ME. Or does it?

Introduction

Aspect Oriented Programming (AOP) is gaining popularity within the Java SE/EE communities. There are many advantages of AOP especially as it provides a clear separation of concerns. The code becomes much more modular than with
traditional object technology. It’s not the intent of the article to explain all AOP
concepts and if you’re new to AOP you can find a couple of introduction sites in the
references section. Instead we will show how AOP can be used in CLDC enabled
devices such as mobile phones.
In Java ME applications there haven’t been much use of AOP. In fact, there
haven’t been any AOP frameworks available at all! Until now that is. AspectME
is a new open source project that delivers an AOP framework mainly targeted at
CLDC devices. Maybe most importantly, AspectME adds a reflection API. Reflec-
tion makes it possible to invoke methods and access fields dynamically. Advanced
frameworks use reflection to enable non-intrusive and modular mechanisms. Reflec-
tion is needed in AOP frameworks since we need information about where in the
code the aspect is executing.

What’s in the box?

AspectME consists of a runtime jar file that needs to be packaged together with
your Java ME application. Then we have an aspect weaver that is used to weave the
aspects into the compiled classfiles. During the weaving process necessary reflection
information is also added. What aspects to apply and extra reflection information is
controlled by a configuration file. And that’s all. To conclude, to use AspectME you’ll
need the following:

1. Add aspectmeruntime.jar to your Java ME project.
2. Write a configuration file that defines your aspects.
3. Run the aspect weaver after you’ve compiled your source code.

The assembly and deployment of your application is the same as before. AspectME
doesn’t change or remove debugging information so you can debug your application
as usual. Now, lets look at a small example.

Logging example

The first example is the classic logging example where we want to write enter/exit
outputs to the console around certain methods. Consider the following code:

It would be easy to add System.out statements when we enter and exit the method.
However, it would clutter the code, especially if we want to print out if we exit from
an exception:

Instead we can use AspectME and write an advice that can be used to weave logging
functionality into the code:

Now we need to define the pointcut where we want to apply the advice. In this case
it’s only one joinpoint, the bar() method, but we could apply the advice to many
joinpoints, e.g. all public methods in a package. AspectME uses the AspectJ pointcut
language because it’s powerful and de-facto standard within the AOP community.
We do this in a XML file:

Note that combining the parameters from the aspect definition actually describes
in “plain english” what the aspect does, “log around barMethod”. Now we’re ready
to weave everything together into the final executable. We do this with the weave
command from a shell:

The weave command will analyze all classes from the classes folder and weave in the
advices according to the definition in the aspectme.xml file. All modified classes will
be written to the weaved_classes folder.
But hey, didn’t we want to write to the console if we leave the method from an
exception? With AOP this becomes a breeze:

Note that we have totally separated the concern of logging in our example. We can
easily change the logging mechanism by editing a single file, even though it’s applied
in hundreds of joinpoints.

Persistence example

Figure 1

The previous example was simple but showed the basics of AspectME. Now lets
concentrate on a more interesting example. Imagine we have an application that will
manage contact information. If designed properly we would have a domain model
consisting of two classes, ContactList and Contact. The ContactList contains zero or
more Contact objects.
The MIDlet would create the ContactList at startup and pass the model to the views.
The views would use the ContactList to add and remove Contact elements. In tradition-
al application design we would add a ContactListDAO that manages the persistence mechanism. The DAO object would be used from the controller whenever a contact is added or removed. Nice design? Not really since the DAO clutters the code and adds unnecessary infrastructure code into our application.
Using the AOP approach we would intercept the execution at certain joinpoints
as shown in the picture. We start by writing a persistence advice:

The advice implements both the MethodInterceptor and ConstructorInterceptor.
The MethodInterceptor is used to intercept methods that changes the object and
store them in the record store. In our case the ContactList. The ConstructorIn-
terceptor is used to intercept the creation of ContactList objects, so rather than
creating them it will load them from the record store. This means that anywhere in
the code we execute “new ContactList()” we would load the object and return the
loaded object instead of creating it.
The serialization of objects can be made using the reflection API in AspectME.
An ObjectOutputStream reads the field values from the written object and primi-
tive fields are written to the DataOutputStream. Objects are written recursively.
Counterwise we have an ObjectInputStream that reads objects by writing the field
values by reading them from a DataInputStream. The result is very similar to Java
SE serialization mechanism as shown in the code example below.

If you’re interested in the implementation of the classes you can find them in the
code examples on the AspectME home page (see References).
All that’s left is to define our aspects in an aspectme.xml file:

After the weaving process our application will store the ContactList object into the
record store whenever a contact is added or removed. When the application is run
again the ContactList object is loaded from the record store. The application can
still run without the persistence aspect but all contact information will be lost when
the application closes. A good example of how crosscutting concerns creates total
transparency of an application mechanism.

Summary

AspectME is a promising AOP framework that can be used to take advantage of
AOP in CLDC enabled devices. The reflection capabilities add new dimensions to
CLDC applications such as object serialization. We have seen how advices can be
built and reused over many applications since it crosscuts the concern of persist-
ence. The performance impact is acceptable when dealing with large concerns such
as persistence. The bytecode footprint increases a couple of KB but that is a small
price to pay for the increased modularity. Often the footprint becomes smaller as we
gather all copy’n’paste like infrastructure code into small advices.

Originally published in JayView.

Leave a Reply

Close Menu