Wednesday, November 15, 2006

Ruby for the Web? Check!

Well friends, it's time for another episode of "Impossible Or Not!" Today's contender is Ruby in the browser, long desired but never achieved. There are front-ends to Ruby services, delicious Ruby-JavaScript libraries, and of course the ever-popular Ruby on Rails web framework. However, developers have been clamoring for something more.

IRB in an Applet

A long, long time ago in a web far away, there was born a bright-eyed new child named Java. Java found its first public uses in flashing, twirling, annoying buttons called Applets. It was also a bit slow, having just been released into the world. So the big bad public said "Java is slow and only useful for annoying buttons!" And so Java was branded the "slow annoying button" language.

But Java has grown up. It hid away from the public eye, dwelling in dark, dank servers and enterprises. It learned the value of five nines uptime and horizontal scalability. All the while, it improved its public face, preparing for a return home to its birthplace on the web.

Now Java has grown up. It has learned how to appease the enterprise gods while presenting itself to the web in beautiful, performant glory. And it has a new friend: Ruby.

Yes, JRuby can run in an applet. No, it's not that hard. No, the archive doesn't have to be this big (the applet above is about a 1.6MB JAR file, but it includes stuff it doesn't need). Yes, this means you could start writing stuff for web pages in Ruby. No, I'm not kidding.

Yes, Virginia, there is a Santa Claus.

Updated: I fixed the issues under Windows, so it should work for those of you that reported errors. Thanks for the heads up!

19 comments:

Mikael said...

Love your work, but...
Couldn't run applet:

Java Plug-in 1.5.0_06
Använder JRE-version 1.5.0_06 Java HotSpot(TM) Client VM
Användarens hemkatalog = C:\Documents and Settings\mikael.pahmp



en_US: /res/dldir_en.res
java.lang.IllegalArgumentException: Neither current working directory (/) nor pathname (builtin/etc.rb.rb) led to an absolute path
at org.jruby.util.JRubyFile.create(JRubyFile.java:51)
at org.jruby.runtime.load.LoadService.findFile(LoadService.java:349)
at org.jruby.runtime.load.LoadService.findLibrary(LoadService.java:278)
at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:205)
at org.jruby.Ruby.init(Ruby.java:506)
at org.jruby.Ruby.newInstance(Ruby.java:225)
at org.jruby.JRubyApplet.start(JRubyApplet.java:32)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.lang.IllegalArgumentException: Neither current working directory (/) nor pathname (builtin/etc.rb.rb) led to an absolute path
at org.jruby.util.JRubyFile.create(JRubyFile.java:51)
at org.jruby.runtime.load.LoadService.findFile(LoadService.java:349)
at org.jruby.runtime.load.LoadService.findLibrary(LoadService.java:278)
at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:205)
at org.jruby.Ruby.init(Ruby.java:506)
at org.jruby.Ruby.newInstance(Ruby.java:225)
at org.jruby.JRubyApplet.start(JRubyApplet.java:32)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "thread applet-org.jruby.JRubyApplet.class" java.lang.NullPointerException
at sun.plugin.util.GrayBoxPainter.showLoadingError(Unknown Source)
at sun.plugin.AppletViewer.showAppletException(Unknown Source)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

chrismo said...

+1 previous comment. Looks like the same exception I'm getting.

mic said...

+ 1 for mikael's post

Charles Oliver Nutter said...

Well, you can't win 'em all! I have a theory that it may be a localisation problem for you three that have reported an error. Can you contact me offline at charles DOT nutter AT NOSPAM sun DOT com and help me figure out why it doesn't work for you?

Anonymous said...

java.lang.IllegalArgumentException: Neither current working directory (/) nor pathname (builtin/etc.rb.rb) led to an absolute path
at org.jruby.util.JRubyFile.create(JRubyFile.java:51)
at org.jruby.runtime.load.LoadService.findFile(LoadService.java:349)
at org.jruby.runtime.load.LoadService.findLibrary(LoadService.java:278)
at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:205)
at org.jruby.Ruby.init(Ruby.java:506)
at org.jruby.Ruby.newInstance(Ruby.java:225)
at org.jruby.JRubyApplet.start(JRubyApplet.java:32)
at sun.applet.AppletPanel.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Mirko Stocker said...

It works! :) But the bottom of the applet is kind of truncated, don't know if it's a Konqueror problem. I made a screenshot: http://misto.ch/images/jruby_applet.png

Paul said...

Thumbs up in both Omniweb and Safari.

Can it get access to the DOM and do Javascript-y stuff?

Charles Oliver Nutter said...

paul: If you can from an applet, then you should be able to from JRuby. However I don't know how to do such things, so there's some research needed there. It would be pretty fun to use JRuby as a client-side scripting language in place of JavaScript.

chrismo said...

Hm - it's working for me now.

Daniel Spiewak said...

It's interesting to note that it would be (comparitively) trivial to bulid a JavaScript library which adds the applet tag and looks through the DOM tree for any <script language="ruby">...</script>, passing the contents to the applet. The applet could then run the contents (in our ever favorite JRuby). Special stuff like access to the DOM tree or confirm() could be done in a new module, Browser which could be automatically included with all Ruby script. The only downside is that you would be forced to lug around a fairly sizable JAR file. (when I say fairly, I mean fairly, not overly bloated) :-) The extra size of the JAR probably isn't worth the syntactical beauty that you'd get from being able to do client-side AJAX in Ruby.

rvalyi said...

Hi, very nice to see you are there already. Some time ago, I used to embed Fractal Aid, a simple Lisp like/Matlab scripting language in collaborative ecological simulator java applet (called Emergy Simulator), but in the future I'm going to look toward this kind of JRuby Applet...

Anyway, may be you guys can learn also from that great scripting project called FrAid, let's have a look to: http://fraid.sourceforge.net/begin/fraid_examples.html

Also, now you are at Sun, if like I do you still dare believe in applets, please ask Sun shooting this one: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6474088

I don't think they fixed it in Mustang (or really I cant' find how) and it's potentially very very limiting: unsigned applets can't use the JDK Introspector decently as I explained while I do believe the fix is quite simple. I think this could also limit JRuby XML serialization abilities in unsigned applets.

Cheers,

Raphael Valyi, France.

Raphael Valyi said...

You tell JRuby is 1.6 M to embed in an applet... But do you know about Pack200? Hey, with Pack200, I'm pretty sure you could divide by 4 that download while serving it transparently to java 1.4 clients (no pack200 client) or to java 1.5+ clients...

with Pack200, java applets or webstart apps are a way faster to download than javascript equivalent ones... Only the cold start JVM slow startup keeps sucking, but it's getting less and less noticeable as powerful CPU come on the desktop...

Charles Oliver Nutter said...

daniel spiewak: Yes, you might be right about the applet size outweighing what you'd get. HOWEVER...since you could make a single Ruby-in-a-JAR that would work everywere, and the JVM is now open source, it would be trivial to create a browser-global plugin that works for ALL pages with a single instance. That would enable all crazy Rubyish stuff within browsers, and it would work everywhere.

rvalyi: I'll see what I can do...but of course you can now download the JVM source and make a fix yourself :) That would earn some serious geek props.

Also, Pack200 is a great idea. I didn't mess with it for the moment because I just wanted to get it out there, but it would be a great way to shrink the "Ruby in a JAR" further.

stug23 said...

Doesn't work with Firefox 2.0 on Mac OS X and Java 5.

On the other hand, why's little IRB thingy works quite well in my web browser:

http://tryruby.hobix.com/

Charles Oliver Nutter said...

stug: The issue should be fixed; for another post I uploaded a different jruby-complete.jar that interfered with the applet. I've replaced it now.

Anonymous said...

Thanks!!! this should be handy for.. lets say.. ummm.. uhhh... ummmm.... uhhhmmmmmm uhmmmmmm auhhhhhh.... hurrummph...

oh well, time well spent. onto the next ruby trick! how about running ruby running on molasses.. yes and how about a Ruby Interpreter for MUD!

yay! now we can run ruby on MUD! not to mention concret, cow-dung and garden variety compost!

Very Very handy! I love this stuff.. keep cranking this stuff out guys! you're onto something!

something completely useless!

Tom-Eric Gerritsen said...

Thanks, this looks like an awesome little applet to have some of my colleagues try ruby without them having to install anything!

jchris said...

I'd actually being interested in using this technology, if it would let me make requests to other domains from within the applet. perhaps that is a sercurity exemption the applet could request from the user... I know little about Java, but the idea of putting little brains out there on the client side seems wonderful.

Lokesh said...

This is amazing