DekGenius.com
Previous Section  < Day Day Up >  Next Section

4.5 Injecting Code

To get better transparency, you can always automatically generate code and add it to the model. To date, most frameworks use this approach. Of course, since most Java developers use Ant to build their projects, adding a simple code enhancer to your applications is relatively easy to do with little intrusion on your build process. You can use code enhancement in two ways:


Source code enhancement

This technique uses a program to read through your source code and make additions in the necessary places. For example, to make code transparent with respect to a performance tool that does performance profiling, you might run a precompiler program that injects code that takes a timestamp any time you enter or exit a method you want to measure.


Byte code enhancement

Since Java programs compile to a standard compiled form called byte code, you can inject byte code to add services and still maintain transparency. For example, most JDO implementations use a byte code enhancer.

Often, when you inject code, you're actually injecting methods that perform the work of your intended service, as with the source code enhancer in Figure 4-6. Source code enhancement takes a class as an input and then generates code, typically method calls, to inject service capabilities into code, completely preserving transparency in the original class.

Figure 4-6. This source code enhancer addslogging to MyClass
figs/bflJ_0406.gif


JDO enhancers work this way: you create a class that's transparent with respect to persistence. The job of the JDO enhancer is to implement the PersistenceCapible interface. In order to make the class persistent, let your build process run it through a JDO enhancer. (Some of these use source code enhancement but most use byte code enhancement.) The enhanced class then calls the JDO framework to actually implement persistence. Some aspect-oriented programming frameworks use byte code enhancement, as well. The technique has many benefits:

  • You don't have to make any changes to source code.

  • You don't impose any restrictions on your class, so you completely preserve transparency.

  • Code injection is fast at runtime. The additional steps occur at build time, so you pay any performance penalty once, at build time.

  • This is a build-time technique. If you're using Ant or something similar, after a one-time change to your build scripts, you will not need to make other changes to your build process.

For the most part, source code injection works well for techniques that are easy to parse and inject with simple code. Tasks such as adding logging, instrumenting code for performance analysis, or intercepting method calls all work well with a simple code injector.

4.5.1 Byte code enhancement frameworks

Byte code enhancement is a little more difficult to pull off. You'll need a strong knowledge of compilers, the Java byte code specification, and finer issues like threading. For this reason, most people use byte code enhancement through other frameworks.

Some developers frown on byte code enhancement. It's been my experience that fear of the unknown drives this attitude more than practical experience. Knowledgeable teams can and do build byte code enhancers for commercial applications. Still, some perceive disadvantages:

  • Some fear that byte code enhancement may be difficult to debug. If you're the type of programmer who needs to see the Java source for every line of code in your system, byte code enhancement is not for you. I've generally found that enhancements are little more than method calls into a services layer, so it's usually not an issue.

  • Theoretically, two byte code enhancers applied to one class could possibly collide, causing some breakage. I haven't seen this happen in practice. In fact, not many byte code enhancers exist.

The framework you choose depends on the services you need. JDO uses code enhancement to add transparent persistence. Some tools that make understanding decompiled code more difficult, called obfuscators, also use byte code enhancement to help you protect your intellectual property. In addition, some AOP frameworks enhance byte code at runtime when they load classes. You'll probably wind up using byte code enhancement solely through one of these.

    Previous Section  < Day Day Up >  Next Section