YOUR FEEDBACK
The 4 Core Principles of Agile Programming
Siegfried wrote: Actually, every elephant has two left feet, and two right...


2007 West
GOLD SPONSORS:
Active Endpoints
Your SOA Needs BPEL for Orchestration
BEA
Virtualized SOA: Adaptive Infrastructure for Demanding Applications
Nexaweb
Overcoming Bandwidth Challenges with Nexaweb
TIBCO
What is Service Virtualization?
SILVER SPONSORS:
WSO2
Using Web Services Technologies and FOSS Solutions
Click For 2007 East
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
SYS-CON.TV
TOP THREE LINKS YOU MUST CLICK ON


BPP: The Beanshell Preprocessor
Increase your productivity benefits

Digg This!

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:

  • Lines with a # (pound) in column one have the remainder of the line copied exactly to the Beanshell script. For example:

    
        #n=10;
        #for(i=0; i<n; ++i) {
    
         becomes 
    
        n=10;
        for(i=0; i<n; ++i) {
    

    in the Beanshell script.

  • Lines with a " (double quote) in column one have the remainder of the line "quoted magically." This means it becomes a print statement with $IDENTIFIER and $(EXPRESSION) patterns concatenated in. Two compromises were made in the magic translation:
    -$ 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.

  • Lines with a ' (single quote) in column one have the remainder of the line 'quoted exactly.' This generates a print statement in the Beanshell script that will faithfully reproduce the line of text. For example:

    
    '#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.

  • Lines with none of the above "translation codes" have the default translation applied to them. This is "quoted magically" unless the -q ('quote exactly by default') option is passed to BPP.

    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

  • Beanshell: www.beanshell.org
  • BPP: http://bpp.sourceforge.net
  • FRAMES (click on the "FRAMES" link): http://mepas.pnl.gov/earth
  • BPPSql: http://home.mesastate.edu/˜kcastlet/BPPSql.html
  • perlpp: www.linuxgazette.com/issue44/macevoy/macevoy.html
  • About 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 wrote: The URL for BPPSQL is missing the ~ character. The URL should read. http://home .mesastate.edu/~kcastlet/ BPPSQL.html Karl Castleton
    read & respond »
    LATEST JAVA STORIES & POSTS
    Case Study: Java and the Mac
    This is the story of a Mac application developer (okay - it's about two of them) who set out on a quest to find an application development tool based on Java so his boss would let him develop on the Mac platform, which he loved. There was only one catch - he had to find a tool th
    A Lightweight Approach to SOA and BPM in Java Using jBPM
    SOA is mostly associated with technologies such as BPEL, SCA and Web Services. But does SOA really imply these technologies? In this session we will show how you can use the service oriented approach while staying inside the Java world. jBPM is a powerful lightweight framework th
    JavaOne 2008: Uncommon Java Bugs
    Any large Java source base can have insidious and subtle bugs. Every experienced Java programmer knows that finding and fixing these bugs can be difficult and costly. Fortunately, there are a large number of free open source Java tools available that can be used to find and fix d
    The 4 Core Principles of Agile Programming
    One of the things I really enjoy at the moment is the recognition and adoption of agile programming as a fully fledged powerful way to deliver quality software projects. As its figurehead is a group of very talented individuals who have created the agile manifesto (http://agilema
    JavaOne 2008: Sun Adds Comprehensive Video Capabilities to JavaFX
    Sun Microsystems announced it has entered into a multi-year agreement with On2 Technologies to add comprehensive video capabilities, using On2 Technologies TrueMotion video codecs, to Sun's JavaFX, a family of products for creating Rich Internet Applications (RIAs) with immersive
    JavaOne Archives - Dvorak Comments on AMD Intel Lawsuit on SYS-CON.TV
    Conference in San Francisco. Dvorak held forth on a number of topics, including the new AMD/Intel lawsuit, the viability of Java and Sun, the value of (or lack thereof) of corporate PR, and whether or not a new book about Silicon Valley is really worth reading.
    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
    BREAKING JAVA NEWS
    KongZhong Corporation Reports Unaudited First Quarter 2008 Financial Results
    KongZhong Corporation , a leading wireless value-added services (WVAS) and wireless media co