Recently I needed to create a megabyte file full of random bytes in order to test network bandwidth with an uncompressible file.  I decided to try using Java, it was simple and had a reasonable random number generator.  So here’s the resulting script:

        #!/bin/sh        # testbandwidth host login passwd        host=$1; login=$2; pass=$3

        echo "Building mbyte file"        cd /tmp        cat <<EOF> test.java        import java.util.*;        class test {            public static void main (String args[]) {                try {                    Random r = new Random();                    byte[] data = new byte [1024*1024];                    r.nextBytes(data);                    System.out.write(data,0,data.length);                } catch (Exception e) {                    System.out.println(e);                }            }        }        EOF        javac test.java        java test>mbyte

        echo "Upload Test"        ftp -i -n -v $host << EOF            user $login@$host $pass            put mbyte        EOF

        echo "Download Test"        ftp -i -n -v $host << EOF            user $login@$host $pass            get mbyte        EOF

Well, that’s sorta nifty, but boy is the java a verbose hunk of the code!  Lets enumerate some of the irritations:

  • Have to create the temporary .java and .class files somewhere (here we used /tmp) rather than have it simply execute the commands in place.
  • I’ve got to make a class and a static void Main method in the class, the Java cliché for building an application.
  • Then it all gets wrapped with a try/catch construct due to possible I/O errors.
  • Testing is tedious, requiring compilation and running rather than more immediate feedback.
  • The flow of the Unix script is broken up .. its hard to tell, for example, what the point of it all is!

Well, I often use

BeanShell

while hacking because its so easy to test a piece of code w/o the compile/run steps.  (See

this article
) I just keep a shell running and cut & paste code pieces from my project.  So being somewhat comfortable with BeanShell, I decided to replace the Java part of the above script w/ the BeanShell equivalent.

        cat<<EOF>/tmp/temp.bsh            r = new java.util.Random();            data = new byte [1024*1024];            r.nextBytes(data);            System.out.write(data,0,data.length);        EOF        java bsh.Interpreter /tmp/temp.bsh > mbyte

So we’ve replaced 17 lines of Java code with 7 lines almost identical code, but without the verbosity.  Very readable and appropriate, and quite readable.  (Note that we still had to create a temporary file due to BeanShell not coming with a “wrapper” shell script that would handle stdin as program text.  Minor.)  The treat for me was the ability to use the standard, well documented (JavaDoc) classes easily from scripts.  Note that I did not bother with an import statement, I fully specified the Random class.  Due to “loose typing” allowed by BeanShell, I could avoid the equivalent

        java.util.Random r = new java.util.Random();

..which seemed to warrant the use of the import statement.

Wanting to fuss with this a bit more, I rewrote this all in

PNuts
, a Java Shell written with a slightly different set of goals (see

this article
).  It uses incremental compilation for speed, and has a Java-like syntax but with several differences.  For example, rather than Java’s


        import java.util.*


form, PNuts uses a procedure form:


        import("java.util.*")



So the PNuts form of the Java code is:

        pnuts<<EOF>mbyte            r = class java.util.Random()            data = byte [1024*1024]            r.nextBytes(data)            class java.lang.System::out.write(data,0,data.length)        EOF

Slightly shorter due to being able to use a “here file” for stdin.

There have been several articles on Java scripting languages,

this one

includes these two and several others.  And

this article

collects all the languages that run on top of the Java VM.

Have you had good luck w/ these or other Java scripting languages? Jython seems interesting, for example.