Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Computing
Conference & Expo
November 2-4, 2009 NYC
Register Today and SAVE !..
SYS-CON.TV
Today's Top SOA Links


Bytecode Generation Tips and Tricks
Simplify runtime

This article introduces readers to bytecode generation and shows how to inject generated bytecode into a JVM runtime. After reading this article generating a Java class won't be any harder than creating an XML document with the DOM API.

Over last couple of years, bytecode generation has gained significant momentum. Many tools generate bytecode instead of source code to obviate the compilation step and simplify the injection of generated code at runtime.

There's a number of bytecode-generation libraries with BCEL (Byte Code Generation Library) being the most renown and probably most powerful. It's used by tools such as Xalan's stylesheet compiler and Mercury Interactive's Topaz J2EE Probe.

Bytecode vs Source Generation
You may ask: "Why bother with bytecode generation if I can produce Java source?" Ultimately, it's your call what technique to use. For example, some people create XML documents with println(), others use the DOM API. Keep the following considerations in mind:

  • With Jad, Jadclipse or DJ Java Decompiler (see Resources) a .class file is an open book as .java file. But read-only. So there's no need in (and actually no place for) formidable headers like "Generated by XXX - Do not edit!"
  • There is an additional compilation step if you produce source instead of bytecode. Compilation at runtime is a real big headache, especially if you don't control the target JVM.
  • The amount of Java code you have to write to produce Java source won't be significantly less than the amount of Java code for bytecode generation. Actually, it may be more.
  • Using different template engines has its own vices. First of all generation logic gets distributed between the Java code and template code, which makes the whole solution less manageable and more fragile, because templates aren't easy to debug. Second, as you start adding more and more to your templates they will soon become unreadable. Take a look at Xdoclet templates - they look like cuneiform on the Hammurabi stella.
Use Scenarios
BCEL can be used for code generation (this is what XSLTC and SQLC do) and for code modification (this is what the Mercury Topaz J2EE Probe does). This article covers the first scenario - code generation. In MDA parlance it describes how to build the T in PIM+T -> PSM equation where PSM is Java bytecode and PIM is a XSL stylesheet in the case of XSLTC and SQL statements in the case of SQLC.

Truth to tell BCEL API is a bit cumbersome...elaborate... I've created several helper classes to make life easier.

Runtime Generation
Classes can be generated at build time and runtime. The first case is a trivial one - generated classes can be used like any other Java classes.

Runtime code generation is a more interesting theme. When you generate classes at runtime you need to make them available to JVM. This can be done with com.pavelvlasov.InjectingClassLoader:


1.Interface myInterface=
2. new Interface(
3. "public interface com.myorg.myapp.
MyGeneratedInterface extends java.io.Serializable",
4. "My Generated interface",
5. null);
6....
7.// Injecting
8.ClassLoader parentClassLoader = ...
9.InjectingClassLoader icl=new InjectingClassLoader(parentClassLoader);
10.icl.consume(myInterface);
11....

We injected generated classes and/or interfaces in the Java runtime. How to use them? If generated classes implement interfaces or extend classes known at compile time then the answer is obvious - instantiate and cast.

What if generated classes don't comply with the statement above? How to use classes not known at compile time? Well, the answer is that information about generated classes can be obtained through reflection. Scripting environments such as JSP, JSTL, Velocity, and script interpreters won't distinguish injected classes from any other.

An important note about runtime generation: BCEL isn't thread-safe. If you're going to generate classes in multithreaded environment then each generating thread should have its own classloader for BCEL classes. This will result in a bigger memory footprint because BCEL classes will be presented in memory once per generating thread.

Generating Interfaces
Generating interfaces is the simplest task because interfaces' methods are all abstract.


1.Interface myInterface=new Interface("public interface com.myorg.myapp.MyGeneratedInterface extends
java.io.Serializable", "My Generated interface", null);

Adding a method is as straightforward as creating an interface itself:


1.myInterface.addMethod("void setMyValue(java.lang.String str)",
null, "My generated method");

If the method parameters aren't known at coding time then they can be supplied in the second parameter of addMethod(), which will either be null or a collection of com.pavelvlasov.util.Parameter implementations.

Adding a field is also a one-liner:


1.myInterface.addField("MY_CONSTANT", "java.lang.String");

But fields in interfaces are static final and shall be initialized in the static initializer:


1.InstructionList il=new InstructionList();
2.il.append(new LDC(myInterface.getClassGen().getConstantPool().addString("My constant value")));
3.il.append(myInterface.createPutField("MY_CONSTANT"));
4.il.append(new RETURN());
5.myInterface.addStaticInitializer(il, "Initializes myInterface");

Once you've created an interface and added methods you should either save it to a file for future use or inject it into the runtime. To save the interface you can invoke its save(File) method or obtain BCEL JavaClass object using getJavaClass() method and do whatever you want with that object.

About Pavel Vlasov
Pavel Vlasov is a software architect at Citigroup. His areas of focus are software artifacts governance, build and deployment automation, Java/J2EE, and SOA/ESB. He is also an author of several open source products. He can be contacted at Pavel.Vlasov@hammurapi.biz

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

I'm sorry, but it was very difficult for me to understand this article. It was almost like it was written in a foreign language (rather than in English). I thought, at first, that perhaps the author's mother tongue was not English, but then I saw that he is based in USA. So is it just me, or do other people find this article difficult to follow?
(Granted, I haven't looked at the accompanying source code, yet, so that may clarify things for me.)


Your Feedback
Avi wrote: I'm sorry, but it was very difficult for me to understand this article. It was almost like it was written in a foreign language (rather than in English). I thought, at first, that perhaps the author's mother tongue was not English, but then I saw that he is based in USA. So is it just me, or do other people find this article difficult to follow? (Granted, I haven't looked at the accompanying source code, yet, so that may clarify things for me.)
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

SYS-CON Featured Whitepapers
ADS BY GOOGLE