|
Comments
|
Today's Top SOA Links
Enterprise Bytecode Generation Tips and Tricks
Simplify runtime
By: Pavel Vlasov
Apr. 7, 2005 12:00 AM
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
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 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:
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
Adding a method is as straightforward as creating an interface itself:
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:
But fields in interfaces are static final and shall be initialized in the static initializer:
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. Reader Feedback: Page 1 of 1
Your Feedback
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||