BeanShell FAQ

Authors:
Pat Niemeyer(pat@pat.net)
Daniel Leuck(dan@econtix.com)


Why is it called "BeanShell"?

It's partially a pun on "bash" (the GNU "Bourne again" shell) "bash"->"bsh" and then there's the obvious beans reference.
In the future I want to add more functionality for working with JavaBeans (editors, etc.) and make BeanShell more accessible for use *as* a JavaBean.

How does BeanShell relate to other Java scripting languages like JavaScript, Jacl, and JPython.

JavaScript is evolving, but fragile and gross - not unlike, I'd imagine, the first slimy creatures to crawl out of the oceans billions of years ago. JavaScript's history has had little to do with Java and I am therefore highly skeptical about it.
I was, on the other hand, very excited about Sun's announcement that they intended to port Tcl to Java (Jacl) and provide greater Tcl/Java integration. Tcl is cool and my desire for an embeddable / extensible scripting language for Java drove me to start this project. However I have not seen much progress on this project since John Ousterhout left Sun.
JPython is a port of the Python language to Java. I like Python as a more object oriented and structured / regular alternative to Perl. (Although the use of formatting for code blocking offends my C sensibilities ;) ). Python may be the best choice for a full blown scripting language. However it is signifigantly heavier than BeanShell for use as a scripting extension language and it does require that programmers learn yet another language (albeit a good one).
It is entirely possible that one or more of these languages will eventually supercede the role of BeanShell. However their full implementations will undoubtedly be quite large (many megs) and there will probably always be a role for a light weight, "obvious" and simple scripting extension language. The goal then is to keep the core of bsh as small as possible. The core of BeanShell is currently about 135K and may actually get smaller in the future.

What is BeanShell's size?

Right now the core beanshell interpreter (without the misc shell tools) is approximately 135K in the compressed JAR file (Bsh is about 175K with all of its utilities). About 75-80% of that is the parser, which is generated using Sun's JavaCC tool. It is possible that a more advanced parser generator could reduce this size in the future.

What tools were used to create BeanShell?

Beanshell is based on the Sun Java 1.1 grammar and the parser is generated using JavaCC (Sun's YACC for Java). There are some bsh extensions to the Java grammar and some subtractions of course. The bsh grammar and supporting code are supplied in the source release. You may marvel at its beauty or retreat in horror at its ugliness depending on where you look ;)
I took some liberties with the Java grammar and "unrolled" some constructs to make it easier to deal with early on. Some of these decisions were probably mistakes but some may actually make bsh slightly more efficient. A future rewrite may clean up the grammar.

Does BeanShell reparse scripted methods on each invocation?

No. Scripted methods are parsed once and stored in a parse tree. Reparsing can be forced by calling the source command.

Why does BeanShell encounter problems during deserialization of primitive type (class) identifiers? / Why do I get a java.lang.ClassNotFoundException during deserialization?

This problem is due to a known bug occurring in JDK/JRE 1.3.1 and below. The numeric primitive types class identifiers (e.g. Integer.TYPE) aren't properly deserialized by ObjectInputStream. Attempting to do so will cause a java.lang.ClassNotFoundException When using JDK 1.3.1 or lower you can employ a workaround by subclassing ObjectInputStream. The workaround is described in detail here.

Why is bsh slower executing the first few commands?

The BeanShell parser uses a lot of small classes to build the parse tree. Java may not load (and verify) a given classes until you happen to exercise the corresponding part of the Java grammar. (For example, it may not load the class bsh.ASTForStatement until you use a "for" loop.) You may notice this as a slight slow down on the first couple of commands you execute.
To ameliorate the situation, as its first action, bsh prints its banner message using its own bsh "eval" command... This gets things moving a bit.

Why is BeanShell so slow when executing certain operations such as for loops?

As with any scripting language, BeanShell trades performance for flexibility. Certain operations are slower than others. For loops, for example, are noticeably slower than Java because the primitives involved are being coerced to objects. Object creation is computationally expensive. BeanShell will continue to be optimized but will always remain slower than Java.

How can I use JConsole as an output terminal in my application?

JConsole is a Swing component. You can use it as you would any other swing component. For example:
JConsole console = new JConsole(); myPanel.add(console);
If you want to connect it to an interpreter simply add
Interpreter interpreter = new Interpreter( console ); interpreter.run();
JConsole can also be connected to the interpreter directly with Interpreter setConsole(). JConsole can supply a PrintWriter through getOut() and has a full suite of direct print() methods. When interacting with the console from outside the event handling thread employ the normal Swing-related thread safety facilities such as SwingUtilities.invokeNow() and invokeLater().

Consult the user manual for complete details.


What's wrong with running the interpreter on the command line under Solaris?

Very old versions of Java for Solaris that use "green threads" (non native threads) have a problem. Reading input from stdin (System.in) blocks all other threads. Note: this does *not* affect the graphical bsh console window under Solaris or any OS. This is a well known problem relating to the implementation of user level threads. You should be fine under Solaris using any native threads implementation.
The problem is documented in a mail thread from some time ago.
Here's a local copy of one note in case that disappears.

What happened to the AWT based version of the GUI Console.

The AWT based Console was never very good. Since Swing is pure Java and is available for jdk1.1.x there should be no reason to use AWT any longer. However the old Console is still packaged for use in the Applet based remote server mode and BeanShell still looks for it if nothing else is available.

How does bsh deal with multi-line statements on the command line?

BeanShell is not very friendly as a shell. (Although the bsh console window implements a simple history for you. The raw parser does not provide any feedback on a statement by statement basis. The happy little "bsh" prompt is generated in the main interpreter loop and a little more happens before your characters ever get to the interpreter.
Normally, the parser would insist on detecting a trailing ";" before it would complete a line. In order to provide the shell-like ability to simple hit 'return' on an empty line, we have a hack. The console window detects empty lines and automatically appends a ";". This "feels better" but is a little weird. For example, you can type "a=5" and hit return twice to complete the line (the first is just trailing whitespace, the second triggers the auto ";").
When you run the bsh.Interpeter on the command line (in interactive mode), a simple stream filter takes the place of the console and preforms the ";" hack. I rationalize this by thinking that in the future this stream filter will do "real" line editing and history.
In the future, I'd like to fix all of this in a clean way and also implement some parser feedback so that we can do a proper multi-line statement prompt as in other shells.

Can I compile my beanshell scripts?

Not currently but this is planned for a future release. See "The BeanShell Parser" in the user manual for related information.

Can I subclass java classes using a scripted class?

Not currently but this is planned for a future release.