#376 JRuby Basics
Aug 30, 2012 | 10 minutes | Performance, Tools
JRuby is a polished and stable Ruby implementation. Here I show the basics of setting it up and executing Java from within Ruby. I also see how it compares with MRI at running threads.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Ryan for a regular Rails application you think be better run it over jRuby in production?
I would say yes and to run it on Torquebox if it has any complexity.
Also check torquebox, I'm using it on a project right now and i'm really impressed. Problem though with jruby is slow startup time, so for example asset pipeline is unusable (compiling twitter bootstrap takes about 30s in dev on my mbp), also rspec takes longer to boot so tdd is quite painful.
+1 for torquebox though I think it's a pretty big tool and should be reserve for big projects with private server
Have you checked https://github.com/jkutner/guard-jruby-rspec ?
I use torquebox and yes, the deployments are the worst. The whole site goes down for 30 seconds.
I would also love to see Torquebox covered in an episode. I do have some experience with jRuby and concur with Martin. I would not use it for development purposes for the reasons that he mentions above.
jRuby is for deployment and integration with the Java world. It can be deployed on Tomcat which is the most widely used open source Java Server. As a matter of fact, Torquebox uses a customized Tomcat. Swing UI capabilities do seem promising though I have not written a Swing application in more than ten years, so I cannot comment on it.
All in all, a solid option for introducing Ruby in a Java entrenched enterprise.
Great work Ryan, appreciate the effort.
Well, I think the deployment headache is worth it when you see the performance if offers over MRI as well as what torquebox gives you out of the box.
While therubyrhino is awesome, if you have nodejs installed on your machine, ExecJS can use it instead. This works with JRuby as well, and makes asset compilation much faster in my experience.
+1
I am using Grails and Guard to compile my assets using JRuby which I feel has a faster asset compilation time.
In a production environment would it be possible to compile my rails app into java bytecode ? I.E. the production server would have no rails app source code.
look into using wabler to bundle the rails project into a war file for java app server:
https://github.com/jruby/jruby/wiki/JRubyOnRails#wiki-War_File_Deployment
BTW i bumped in this blog on jruby gem packaging.. http://huangzhimin.com/2012/08/06/how-to-write-a-jruby-gem-part-1/
Great stuff! I feel silly that i didn't try JRuby before.
But I have some questions:
* Is there compilation from JRuby to JVM bytecode going on over the scenes?
* And is there way to compile JRuby to Java code?
look into using wabler to bundle the rails project into a war file for java app server:
https://github.com/jruby/jruby/wiki/JRubyOnRails#wiki-War_File_Deployment
Yes! There is a way to compile Ruby to Java...try to type 'jrubyc' in the shell...it simply takes Ruby files and converto to java .class
If you want a compiled version of your Rails app try:
$ warble compiled war
I am trying to add JRuby support to my C-extension gem, by writing a Java class and executing it when the gem is installed on JRuby.
NameError: cannot load Java class com.dockyard.PgArrayParser
Any suggestion?
thanks
Make sure that:
you're running it in JRuby (sorry but it happens ;) )
you've called
require 'java'
you've called
java_import 'com.dockyard.PgArrayParser'
you've compiled the class using
javac
the .class file, or a jar file that contains it, is in your classpath at runtime
if the class is in a class file, rather than in a .jar file, then it will need to be in a com/dockyard subdirectory of a directory in your classpath.
-- Keith
Ryan -
Nice presentation, and thanks for getting the word out about JRuby. I think it offers a lot of possibilities to supplement MRI Ruby.
Regarding using JRuby to write Swing apps, if anyone's interested in seeing a small but nontrivial JRuby Swing app, check out my Game of Life Viewer at [https://github.com/keithrbennett/life_game_viewer], blog article at [http://www.bbs-software.com/blog/2012/09/05/conways-game-of-life-viewer/].
Also, in many cases you can eliminate JRuby's JVM startup times by using Nailgun (blog article at [http://www.bbs-software.com/blog/2012/09/15/hello-nailgun-goodbye-jvm-startup-delays/).
And, for more information to supplement this JRuby screencast, you can check out [http://www.bbs-software.com/blog/2012/09/04/jruby-presentation-northern-virginia-ruby-user-group/].
I worked with Java Swing for several years, several years ago, and have some comments and suggestions for those who want to take it further than the basic example you provided:
In my experience it's better practice not to call
setVisible(true)
when the frame is instantiated (that is, inside the class definition), but instead make it visible after it has been created. There may be other initializations you want to perform between the creation of the frame and the displaying of it, especially if it's happening at startup time.An alternate way of instantiating a JButton is to pass it an instance of an Action class. This offers a cleaner separation between the visual button object and the business logic it executes. In addition, a single Action instance can be shared by multiple UI components. This comes in handy when you want the action to be triggerable by both a button and a menu item, for example. The UI components set themselves up as a listener to the action so that changing the enabled state of the action enables or disables all UI objects that use it.
It's a little cleaner to use Ruby-like property setter notation in the class, but make sure to preface the property with
self.
or else Ruby (any Ruby, not just JRuby) will consider it a local variable initialization. For example:Normally it's necessary to call
pack()
on a JFrame after you've added all the components to it so that the frame will lay out its components properly. I guess it's not necessary with a single button.You mention that in Java you would normally use an anonymous function for the behavior of an action listener, but I think you meant an anonymous class.
Using the JOptionPane show methods by themselves in a script without running a full fledged Swing program is a really great idea that never occurred to me. Thanks!
Cheers,
Keith
Thanks for this Ryan! One thing I'd like to mention is that Swing components should always be initialized on the EDT (Event Dispatch Thread). So, instead of
HelloWorld.new
:This will prevent deadlocks and other unwanted behavior from happening.
I made a typo, it should simply be:
While it is true that Swing event handling must all be done on that thread, it is not necessary for creation or starting of the initial Swing component needs to happen on that thread. Swing programs routinely have their first setVisible called on the main thread. I don't know if I'll be able to insert a link here, but here is an example on Oracle's site that launches the GUI by calling setVisible on the main thread: http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/BorderDemoProject/src/components/BorderDemo.java
Thanks Ryan for this !
I notice a little "cheat" on the video at 2:02 : on your console
>>require "java"
=> true
become false at 2:06. That mean that you had an unexpected thing during recording the screencast. That's normal in the real life. And if a mistake is made by you, you can be sure that many of your followers (at least me ;-) ) will do the the same. So why not explain it ? Non working things teach us many (if we get explication).
I'd rather have the notice about a frequent issue/mistake. I tell this as feedback to improve your RailsCasts that are already awesome. I'm not complaining ;-)
I saw that because I've an issue with require 'java' that raise an error (No such file to load -- java) with normal Ruby and return false with Jruby... (and I'm trying to make my app work on both platforms.) Anyone can help me saying more about that commande please ? Thanks.
[EDIT] I realized that if I've a false return with jruby, that is because java is already loaded by my app as long I use the rails console. Indeed my app has a presenter that require java.
For you it might be different : the record in pause then you have written some more lines, made some try and rewrite first lines before restart record and as it was not the first time it was required, require 'java' return false this time... [/EDIT]
How to configure Torquebox for https connection? I have tried as per document. When i send request though web brower , it not accepting http connection.
Thank you
soo cool!!