The Java Shell

WARNING: I abandoned this project long ago.

Yet another tool to help hardcore Java programmers!

NEW: Alpha9 is out! But the project is still dead (sort of) -- I was having no time for it anymore and the mailing list is over. I'm looking forward to adding the project to a site that handles thigns for me, like SourceForge.

Also, I'm now actively using the shell in my current development project, so I may improve it eventually. This is a very interesting experience that I'd like to share: Extending jsh for your application (updated).

Because all code is GPL, maybe somebody else can move it forward. There are other similar projects around.

Check the changes.

Motivation / Presenting jsh / Get & Install / Bugs / Implementation & Contribution / History / Links / Feedback

Motivation

Look at those Java Consoles you get in browsers.  They have such options as forcing GC, checking free memory, listing threads, terminating the VM... this is cool, but useless for Java applications.  Usually, this functionality is not available for your preferred Java environment.

Now look at your favourite command shell.  You can use it to start programs.   Lots O' them, with the same shell.  You can check the status of running programs, manage them, and so on. You can use scripts to automate things and glue apps together.

I wanted a simple shell unifying both facilities.  I started including here the intelligence of my previous loop and fork utils, and making an interactive shell (i.e. CLI = read/parse/exec commands) including capability to launch apps and keep running so I can do other things.   All in a single JVM, thus avoiding the cost of multiple VMs (see the Java Fork).

There is a few other Java shells available.  But this one is Pure Java, free, and open source – besides great too!  :-)  jsh is under the GPL.

Presenting jsh

This snapshot of a session will give you an idea (the text in italics after // is inserted here).  (Tons of new stuff not shown here..)

C:\Java>jsh               // Enters the wonderful world of your Java VM!
C:\Java:jsh>help          // Don't Panic!  We've got manpages!!
Java shell tools help (tools will also understand the -help option)
... command listing ...
C:\Java:jsh>MandelApplet &    // Lauches app concurrently
C:\Java:jsh>time:0.811        // The usual crap due to the GUI app running...
                              // ...in parallel, and printing to the terminal!
C:\Java:jsh>vm                // Gets some JVM status info
Heap: 644K free, 1023K total.
Running: 2 processes, 4 ThreadGroups with 6 Threads.
C:\Java:jsh>ps                // Gets info on JVM's "processes"
4: shell.ProcessStatus (running)
2: MandelApplet (running)
C:\Java:jsh>ts                // Gets info on all JVM threads!
ThreadGroup "system" MaxPriority=10
    Thread "Finalizer thread" (daemon) (alive) Priority=1
    ThreadGroup "main" MaxPriority=10
        Thread "main" (alive) Priority=5
        Thread "Screen Updater" (alive) Priority=4
        ThreadGroup "ThreadGroup for JProcesses" MaxPriority=10
            ThreadGroup "2: MandelApplet" MaxPriority=9
                Thread "AWT-EventQueue-0" (alive) Priority=5
                Thread "AWT-Windows" (alive) Priority=5
                Thread "mandelbrot" (alive) Priority=5
            ThreadGroup "5: shell.ThreadStatus" MaxPriority=9
C:\Java:jsh>timer on               // Let's time every command.
Timer is on.
[Timer: 0.0s]
C:\Java:jsh>loop -n:10 os notepad  // Launches 10 Windows notepads!...
[Timer: 0.031s]                    // ...takes 31 microseconds
C:\Java:jsh>timer off ; prop user  // We have ';' for sequential cmds
Timer is off.
user.language=en              // Lists properties beginning with "user"
user.region=US                // (we can also read/change these properties
user.timezone=ECT             // with the prop command)
user.name=Osvaldo
user.dir=C:\Java
user.home=u:\Osvaldo
C:\Java:jsh>alias cdProj cd D:\Projects   // Aliases for lazy people!
C:\Java:jsh>cdProj            // ==> "cd D:\Projects"
D:\Projects:jsh>jsh           // Enters a new shell, "stacked" over the primary
D:\Projects:jsh>@hello        // Runs hello.jsh script! (doesn't stack a jsh)
Hello, world!                 // The script does an echo command...
D:\Projects:jsh>exit          // Exits the secondary shell, back to #1
D:\Projects:jsh>javac         // Aliases are included for all "pure" JDK tools
use: javac [-g][-O][-debug][-depend][-nowarn][-verbose][-classpath path][-nowrit
e][-deprecation][-d dir][-J<runtime flag>] file.java...
D:\Projects:jsh>cd ..         // Shows off the chdir command... we've got ls, etc.
D:\:jsh>exit                  // Exits the last shell
C:\Java>_                     // Back to the impure world! Yuck!!

As you can see, It's much like most Unix shells, even in the defects :-) Invocation of the OS's shell (e.g. to list the directory, etc.) still needs work.

Get it and Install it

You can get/see the software and open everything in the same directory, say JavaShell; this directory should be included in your CLASSPATH.  You can make an easy shell script to load it (not in Java shell script, er); otherwise you'll run with java shell.Shell.

Required:

Shell core, commands and Echidna runtime (101 Kb, changed in alpha9)

Optional:

GNU commands and docs (410 Kb) (not changed since alpha6)

Sources:

Shell core and commands (66Kb, changed in alpha9).
Echidna sources, modified for jsh (43 Kb, changed in alpha8)
GNU command's sources (118 Kb, not changed since alpha6)

Notes:  If you want to work with the GNU utils' sources, you need its .properties files which are only included in the binary package.  The GNU utilities are used as-is with the Java Shell, but the official distribution is here.  The Echidna library is modified for use with the Java Shell; the official distribution is here but only my hacked version will work with jsh!

Installation: There is a jsh.properties file that you need to extract from the zip and put in your home directory.  In Unix machines that means ~username, but in Windows it's a mess... I provide a instjsh.bat file which I hope to work on all flavors of Windows :-) Basically, this file needs to go to whatever directory becomes Java's user.home property; on WinNT, JDK 1.1.x will use %HOMEDRIVE%\%HOMEPATH%, while JDK 1.2.x will use %USERPROFILE% and in Windows 9x I'm told that %WINDIR% is the right place.

There is a jsh.bat file, you need to launch the shell with this script (if you want the exit -r command to work!) so put it somewhere in your PATH. If somebody provides me the equivalent scripts for the multiple Unix shells, I will gladly include them in the distribution. :-)

Bugs and Bad Things in General

Seems like fork and loop are broken, but they used to work and I didn't change them... maybe someting with recent JVMs?
Need specific aliases for the JDK commands in different JDKs; things like javac may fail to you because your development kit has javac in a different package/class...  Workaround: Send me updated jsh.properties files that work for you and I'll arrange this; but eventually I will test on a few different platforms
JDK 1.2 requires that you have tools.jar file in the CLASSPATH in order to use the JDK tools.  Workaround: Change the jsh script to add the additional -classpath:. I will eventually make the shell smarter and search in tools.jar by default.

Implementation & Contributing

The shell "core" does things like initialization configuration, and parsing commands. It relies on the Echidna library for the process management (but changes it a little bit).

There are no internal commands like in DOS & NT's shells.  All commands are just Java applications, not different at all than any other Java class having a main().  But I have the best of two worlds, because the commands (or any other applications) are not loaded before you need them, and they're not reloaded after you run stuff once, the code remains in the VM.  I'll try to mess with classloaders and make this perfect, by enabling unloading (useful for big apps with tons of bytecode, and for development).

You can very easily add new commands.  You need to check at classes like Shell, Alias, Utils, Exit and a few others  which contain system-wide utilities.  I will eventually make Shell itself better – a decent, customizable prompt is very needed, as well as Unix-like operators (;, (), &).   I will do them, and also guess what can I do in terms of commands.

Ideas I have now for future features (other than fixing things in the buglist):

Package navigation?  For example, pcd com.mycompany.myproject so you can load classes of that package without so much typing and without needing to create lots of aliases.
Inspecting objects, e.g. listing, assigning IDs, and printing – at least serializable objects, and those defining toString(), would be "inspectable"
Loading the jdb debugger
Having an optional AWT-based shell on top of this, for the wimpy programmers :) much better, just providing the glue for somebody else's GUI shell.
Using reflection to allow any operation with existing objects, like creating and calling methods (skij does that, and I did it for my Persistent Shell)

But here are some recommendations if you are interested to do your own Java Shell ready commands at this early stage:

How to provide feedback.
Almost everything can be implemented as independent classes; avoid messing with any of the existing code as much as possible.
All commands shall be reentrant (safe for multiple simultaneous execution), so the user can spawn multiple classes in a single shot, e.g. with the fork command or the '&' operator.
All commands shall use the public services of the core when they need to do things that are available there and are good to be consistent between commands, e.g. alias expansion.
All commands must further integrate in the system by behaving like other commands:  Providing help for the "-help" option (and also for no parameters, when parameters a required);  Living in the shell package is required for jsh-specific programs but not allowed for things other than shell-related stuff, like GUI editors; Adding an alias to the jsh.profile.
Support for both JDK 1.1.x and 1.2.x is important.

Credits, in order of appearance...

Osvaldo Pinali Doederlein, the original jsh hacker.
Rich Hoffarth did a security manager that I incorporated to prevent exit. His site.
Romain Guy, doing tons of Unix-like commands and GUI apps.  His site.
Luke Gorrie does the Echidna library, solving my problems for process management.  His site.
Kevin Raulerson does Java ports of GNU Utilities which I bundled. His site.
Gerard Collin contributed improving the parser.

History

29 Mar 00.  Released alpha9. There's a new echo command and script execution is better and easier (using "@name" syntax).   New support for extended shells: set the property "jsh.extension" to a class name, and jsh will relay to this class any input it doesn't understand (unparsed).

26 Jan 00.  Finally a new upgrade, alpha8.   Gerard Collin contributed an enhancement to the command parser; aliases can have parameters now! I fixed fork and loop to use that too. And I included the latest version of Echidna (0.4.0).

20 May 99.  Released alpha7.  New ';' and '&' operators (like in Unix shells, to run several commands in sequence or in parallel).  Fixes and enhancements in filesystem-related commands; they will run on JDK 1.1 now.  New options in exit: -a (forced or "exit all") and -r (restart, or "poor man's class unloading").  A graphical memory monitor.

25 Apr 99.  Released alpha6.  The problems with Echidna are over and we have no pauses and no overhead from process GC!  Fixed ts, added process and thread counters to vm, removed gc and fin (now I need to call GC after all process launch or batch anyway...)  Several fixes and new capabilities on Romain's commands; included his text editor and memory viewer.  Included and integrated Kevin's GNU utilities (gcd, gdu, gls, gmkdir, gmv, grm, gtouch, gdate, gecho, gpwd, gwhoami, gcat, ghead, gsplit, gwc); the g prefixes are temporary.  Lots of classes renamed for a better style.

20 Apr 99.  Released alpha5.  Romain has been really busy with several new commands (mkdir, calc, cp, time,sort) and enhancements to his previous ones, and also suggesting stuff in the core shell... so I did better parsing of the command line (supports quotes, comments, escapes).  All process management now using Echidna, I added ps and kill.   Finally, I added a trick to specify JDK-specific settings in the properties, and a new echo command.  Uff!

16 Apr 99.  Released alpha4. Added Romain's ls, cd, pwd, and a very alpha more!  Changed the help switch to -help (i.e. with hyphen) for better consistency.  Added the jsh.properties file for easy configuration and plugging of commands (no source changes required).  More error handling in jsh (NoClassDefFoundError).

14 Apr 99.  Released alpha3. Improves the aliasing a lot; Adds support for stored scripts, Adds the prop command to manage Java properties; Enhances the prompt; Fixes a minor glitch in the shell's timer.  And the name changed to jsh.   Big update of the site.

12 Apr 99.  In the afternoon, I became ambitious with this thing and produced the alpha2 version, updated the sites, posted and announced this thing for the first time.  Let's see the feedback now.  I hope I attract contributors, otherwise I will waste even more time that I should dedicate to my thesis <sigh> but it's being really cool.

11 Apr 99.  During the night, I wrote the entirely of the first release of the Java shell, now known as alpha1, and posted it.  Well, the loop and fork utilities were reused from their previous independent projects, a couple weeks ago.   I also created this page and updated fork's and loop's.

Related Links and Tips

Other Java Shells

I found some other shells; none was adequate for my needs, but possibly some of them could be for you...

There are several shells that combine Java to other languages, usually scripting-oriented languages which can be very powerful.  Pick your choice:  IBM's skij (Scheme); Scriptics' Jacl and Tcl Blend.  (Tcl/Tk); JPython (Python); Jack Woehr's FIJI (FORTH).  I didn't use them because I want the shell to be extremely lightweight (to launch and control Java applications without any significant overhead) and I want everything to be very Java-oriented (no auxiliary/secondary languages).
Rich Hoffarth wrote the jsh.  This is a simple shell.  But, I was very lucky to find this because I was stuck in security problems; I didn't ever use security managers and I would normally research the APIs, but somebody told me the only solution would be modifying java.lang.Runtime.exit() and I believed... but I reused Rich's ShellSecurityManager and fixed that!
Mike Hardy is also working on an OSS Java shell (also called jsh and using Echidna) and I wasn't able to get it.
OpenObject does BeanShell, another scripting environment and in this case for visual beans.  I didn't try it.
After launching beta3, I was notified of Jamie Cansdale's (guess the name!) jsh, and this looks good and is more concerned in emulating the Unix environment.  It beats my jsh in the process control, and has nice ideas that I can implement very easily, so I'm going to do them eventually.   :-)
Another Java Shell from Steve (not in active development).   Didn't check yet.
Patrick Beard does the JShell.   Didn't check yet.
Not a Java shell, but if you do any CORBA it doesn't matter as your objects have language transparency... you gotta try CORBAscript from Philip Merle.  This is great for testing, administration and such tasks, as it frees you from the edit-compile-run cycle.  It's a specialized shell where you can manipulate your CORBA objects and environment; supports various ORBs and OS'es.

Launching Java Classes from Windows NT

Before having such a cool shell as jsh, I created a simple hack to fool NT's Explorer so it will launch .class files on double-click.  First, you need a CMD shell script, say "jlaunch.cmd":

@call java %~n1

Now click in some .class file, and associate it with this script.  That's all.   Of course, it will fail if the clicked .class file has no main(); and you get a clunky console window too, it's kinda rude.  But it's convenients for things like PureJava installers.

Sorry, this will only work on Windows NT; Windows 9x lacks the extended syntax I use in the script, which is necessary to drop the .class extension which otherwise confuses the java.exe launcher.  But Windows 9x sucks anyway, I feel no urge to support that thing.  ;-)  I could do a better launcher in C but I'm lazy and C is ugly, so I will put my effort on the Java Shell project instead.

Return to my homepage

1