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.