| By Warren MacEvoy | Article Rating: |
|
| June 3, 2004 12:00 AM EDT | Reads: |
19,095 |
The Beanshell preprocessor, or BPP for short, is intended to be a convenient and powerful preprocessing tool for Java developers. It's convenient because the preprocessor is based on Beanshell, which is essentially interpreted Java. This means that Java or Beanshell programmers can quickly use all of BPP's features. It's powerful for the same reasons: all the power of the Java SDK with the convenience of the Beanshell scripting language is available as double payment: once as a development language and once as a preprocessing language.
In the current world of sexy words for new concepts in software development, a new preprocessor is sure to draw a yawn. But for Java developers, this preprocessor can revolutionize core software development. The reason is that it isn't actually just a new processor, but an entirely different kind of preprocessor: a symmetric preprocessor. A language with a symmetric preprocessor gives the full power (and syntax) of the language as a preprocessor, including the provision for a preprocessor, and so on.
Getting BPP and Beanshell
BPP is available as an executable JAR file from http://bpp.sourceforge.net. Beanshell is available from http://beanshell.org. BPP uses Beanshell under the hood and so must find its JAR file in the class path. Putting the bsh-2.0b1.jar in your classpath ensures it will be found. Once this has been set up correctly, use the command:
java bsh.Console
from a command shell to start up the Beanshell desktop. A windowed Beanshell desktop should appear. In the window, type:
you="Jay R. EE";
print("Welcome, " + you);
After seeing the expected message, add a sticky note to your monitor with the words: "Learn Beanshell now; save time later." For now, just close the Beanshell desktop (see Figure 1). BPP does not use the Beanshell desktop; instead it uses the bsh.Interpreter class internally as a lightweight Java interpreter.
Show Me How Useful BPP Is!
BPP allows you to write Java code that writes Java code in a convenient way. The preprocessor lines begin with a # sign and are executed at preprocess time, while normal lines are undecorated. $id and $(expr) on otherwise normal lines are translated in a natural way. For example, the following BPP source file will create the traditional "Hello World" Java program, but with the message appearing in four different languages.
#
# greetings=new String[] {
# "hola mundo",
# "ciao mondo",
# "hello world",
# "\u043F\u0440\u0438\u0432\u0435\u0442 \u043C\u0438\u0440",
# };
#
public class Xample1 {
public static void main(String[] args) {
#for (i=0;i<greetings.length; ++i) {
System.out.println("$(greetings[i])");
#}
}
}
If you save the above code in a file named Xample1.java.bpp, then running BPP with the line
java -jar bp.jar Xample1.java.bpp
will produce the following text in Xample1.java:

The last line is "hello world" in Russian, and may appear strangely on systems that don't understand UTF-8 encoded unicode. Point is, the #'ed lines are executed at "preprocess time" by BPP. This results in a Java source file with, in compiler optimization parlance, an "unwound loop."
Admittedly, unwinding the above loop at preprocess time will provide no particular advantage over executing the loop at runtime. There are places where such unwinding could make a great deal of difference. Similar preprocessor code could write substantial "boiler plate" code that you might otherwise use a more traditional "copy/paste/edit" approach on, but we will leave that to the reader's imagination (and online tutorials on the BPP Web site). The next example takes on a loftier software engineering goal: compile-time versus runtime safety.
Safe Sets
It's a basic principle of software engineering that the earlier you find an error, the less expensive it is. The collections framework in Java is a good example of something that's runtime safe (because you can't put in an apple and treat it like an orange without a ClassCastException), but it isn't compile-time safe, since you can add any object to any collection, even if you only really wanted oranges in it.
BPP can quickly create compile-time type-safe wrapper classes for collections (or wherever else you need them). Listing 1 provides a snippet of the type-safe template for Collection.
To use the code in Listing 1, save it in a file called "makeTypedCollection.bpp" and generate the equivalent Beanshell script with:
java -jar bpp.jar -b makeTypedCollection.bpp
The -b option tells BPP to create the script, but not execute it. The script is written in this case to makeTypedCollection.bsh. With this handy "template" around, creating a compile-time type-safe collection is a snap. For example, a string collection would be the following smidgen of lines in StringCollection.java.bp:
#source("makeTypedCollection.bsh");
#makeTypedCollection("StringCollection","java.lang.String");
Notice that I source the Beanshell script generated by BPP, not the BPP script itself.
There is a philosophical point here: judicious use of BPP can move many checks from runtime to compile time. This can make an order-of-magnitude difference in how long it takes (and expensive it is) to find and correct mistakes. Now let's look at how BPP does its magic.
You is What?
Beanshell is a get-to-the-point Java. Typing:
you="Jay R. EE";
print("Welcome, " + you);
in Beanshell is equivalent to compiling and executing the following Java code:
public class SomeClass
{
public static void main(String[] args)
{
String you="Jay R. EE";
System.out.println("Welcome, " + you);
}
}
Which one would you rather type? See www.beanshell.org for many useful resources on Beanshell. For now, here is what I claim to be the shortest tutorial of a production programming language in history:
Beanshell is an interpreted version of Java with optional types.
Types are great for safety, but they can turn the quick and dirty into the slow and tedious. Beanshell adheres to types you specify, but also allows unspecified types so you can choose your safety level. As of version 2.0, Beanshell has seamless integration with JDK 1.3 and above. Thus Beanshell is a flexible superset of Java that I encourage any Java developer to get to know.
How Does It Work?
BPP is similar in nature to servlets and php (and a very similar Perl-based preprocessor, perlpp). It works by translating the BPP code into Beanshell code under the following rules:
#n=10;
#for(i=0; i<n; ++i) {
becomes
n=10;
for(i=0; i<n; ++i) {
in the Beanshell script.
-$ is a legal start and part of a Java identifier. If you need to have such a value in a BP script use $(my$-strange$id).
-When $ is not succeeded by an identifier, a left parenthesis, or another $, it simply represents a single $. $$ on a magically quoted line represents a single $. For example:
#static import bpp.Format.*; "Dear $title $lastName; "You owe $$$(N(blnc,"#,###.00")).
becomes
static import bpp.Format.*;
print("Dear "+title+" "+lastName+";");
print("You owe $"+(N(blnc,"#,###.00"))+".");
in the Beanshell script. For those new to Beanshell, print() is equivalent to System.out.println(). The N(Number n,String f) method is a static member of the bpp.Format class as a convenience for formatting numbers.
'#static import bpp.Format.*; 'Dear $title $lastName; 'You owe $(N(blnc,"$#,###.00")).
becomes
print("#static import bpp.Format.*;");
print("Dear $title $lastName;");
print("You owe $(N(blnc,\"$#,###.00\")).");
in the Beanshell script.
Putting these together for the first example, the first BPP source file, Xample1.java.bpp, produces the Beanshell script:
greetings=new String[] {
"hola mundo",
"ciao mondo",
"hello world",
"\u043F\u0440\u0438\u0432\u0435\u0442 \u043C\u0438\u0440",
};
print("");
print("public class Xample1 {");
print(" public static void main(String[] args) {");
for (i=0;i<greetings.length; ++i) {
print(" System.out.println(\""+(greetings[i])+"\");");
}
print(" }");
print("}");
Executing this script with Beanshell generates the promised pure Java source file shown above as Xample1.java.
Conclusion
BPP facilitates versioning, templates, macros, optimizations, and compile-time type safety. These things are a normal expectation of preprocessors. However, because the preprocessor is essentially the same full-featured language as the target language, including the fact that it has a preprocessor, these features are much more accessible than, say, C++ templates are to C programmers. This provides big productivity benefits.
Here are a few other gains.
Have Fun!
Writing code over and over that's just a little different from the last time is boring. After the third time, you usually see the part that's staying the same and what is changing. With BPP you can codify that and stick to the fun (new) stuff.
Big Tools Make Little Ones
You can use BPP in development and take advantage of the latest and greatest JDKs in your development environment to produce solutions in any target language/ architecture. BPP is used in this way to support a multilanguage environment called FRAMES.
Dr. Piet Jonas in his "Type Safe Collections" article also addresses type safety, but in another manner.
Jonas' idea is to verify the types for collections at insertion time using runtime type information. This causes an exception to be thrown early (at insertion time) rather than late (at extraction time). In either case, the exception is thrown at runtime.
The type-safe wrappers we suggest using here allow for compile-time safety.
Protecting IP
The JavaBean model reduces an uber-model to one that solves a particular problem. Giving such a bean to someone else allows them to reverse-engineer your IP. BPP can generate a specific solution to a problem without revealing any general techniques on how that specific solution was constructed. Karl Castleton is writing a BPP-based tool to generate 80% of the boiler plate code for a Java servlet/ MySQL Web site based on an XML description of the database architecture. This includes the SQL initialization, basic form pages, and compile-time-safe SQL access classes.
Simplification
In both the above cases, the code that BPP writes is as readable as what a specific programmer would have written to solve the same problem. For example, the above SQL framework generates code that a Java programmer who knows nothing about BP, XML, or even SQL can easily use. In the FRAMES application, BPP writes specific documentation appropriate for each supported target language based on a single document root.
Enjoy BPP!
References
Published June 3, 2004 Reads 19,095
Copyright © 2004 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Warren MacEvoy
Warren D. MacEvoy is Asst Professor of Comp Science in the department of Computer Science, Mathematics & Statistics at Mesa State College, Grand Junction, Colorado.
![]() |
Karl Castleton 06/16/04 03:09:35 PM EDT | |||
The URL for BPPSQL is missing the ~ character. The URL should read. http://home.mesastate.edu/~kcastlet/BPPSQL.html Karl Castleton |
||||
- Kindle 2 vs Nook
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- Confessions of a Ulitzer Addict
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- It's the Java vs. C++ Shootout Revisited!
- Cloud Computing Can Revitalize Your Career as Software Developer
- IBM Could "Reinvent" Java: Mills
- Oracle & Cloud Computing: Exclusive Q&A with SVP Richard Sarwal
- A Brief History of Cloud Computing
- Kindle 2 vs Nook
- Cloud CEOs, CTOs & SVPs to Speak at 4th International Cloud Computing Expo
- Why IBM’s Server Chief Got Busted
- Is Cloud Computing Like Teenage Sex?
- Industry Experts Discuss the State of Cloud Computing
- Performance Tuning Essentials for Java
- The Difference Between Web Hosting and Cloud Computing
- Cloud Computing Expo: Exclusive Q&A with Yahoo! SVP Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Confessions of a Ulitzer Addict
- My Thoughts on Ulitzer
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- The i-Technology Right Stuff
- JavaServer Faces (JSF) vs Struts
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- What's New in Eclipse?
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- i-Technology Predictions for 2007: Where's It All Headed?









































