Here’s the slides from “JRuby: Enterprise 2.0″ from our recent talks at Sun Tech Day and the ACS Web Technologies SIG.
Category: Java
Josh Price and I will be co-presenting at the Melbourne Sun Tech Day and the Sydney ACS Web Technologies SIG. Here’s the low down:
There’s a lot of buzz around JRuby in both the Java and Ruby communities, for good reason. This talk will give you a whirlwind introduction to JRuby. We’ll show you why JRuby is regarded as such a powerful and dynamic development platform. We’ll also suggest where to use JRuby in product development and the enterprise and how to leverage your existing Java investments.
There will be sample applications, live demos and not many slides.
Sun Tech Day Melbourne
4 March 2008, 2:30pm
More info on Sun site…
ACS Web Technologies SIG Sydney
5 March 2008, 6:15pm
More info on ACS site…
Hope to see you there!
The default configuration for running JRuby on Rails using GoldSpike only allows 4 instances of the JRuby runtime. This means that if there are more than 4 simultaneous requests from clients, the web server will respond with a server overloaded error. The easiest way to see what’s going on is to take a look at the ‘createObjectPool’ method of RailsServlet.
With a dedicated production server with 1gig of memory, it is possible to allow a lot more JRuby runtimes, and hence allow for more simultaneous users. A little load testing on a fairly small app suggested that 20 instances of JRuby runtime would fit comfortably under the 1gig ceiling and not overload the processor.
An easy way to change the max number of runtimes is to edit ‘web.xml’ in a JRuby application’s WEB-INF directory. Parameter is set as follows:
<context-param> <param-name>jruby.pool.maxActive</param-name> <param-value>20</param-value> </context-param>
It is also worth checking with the web server configuration to ensure that the web server allows more threads than the number of JRuby runtimes specified in ‘web.xml’.
Say you wanted to store some information across different calls to your JRuby/Rails application on the server side. You could use a database, or memcached. However, what if you just want to do something very simple like a basic cache, and you don’t have a database for your application? Memcached seems like overkill, and would complicate your deployment considerably. So, what about just using statics?
Well, you can’t do it in Ruby, as the Rails integration servlet spawns multiple instances of the JRuby interpreter.
Ruby code in a page view:
<h1>Ruby global number</h1> <% $i ||= 0 %> <% $i += 1 %> <%= $i %> <h1>Ruby obj id</h1> <% $o ||= Object.new %> <%= $o.object_id %>
Results between multiple refreshes of the page:
Ruby global number 1 Ruby obj id 244 Ruby global number 1 Ruby obj id 256 Ruby global number 2 Ruby obj id 244 Ruby global number 2 Ruby obj id 256
Our requests seem to be switching between two instances of the Ruby interpreter.
However, we *can* do it in Java. My clever, Java-literate colleagues explained that Java application servers and servlet containers use a single instance of the JVM, but have a class loader for each application. The class loader stores class information and static values. This means that within one application, the static values will be maintained between requests, but a different application on the same server will have its own set of unrelated static values (similar to AppDomains in .NET).
If we add a call to a static method in Java that increments an integer and returns it, our view looks like this:
<h1>Ruby global number</h1> <% $i ||= 0 %> <% $i += 1 %> <%= $i %> <h1>Ruby obj id</h1> <% $o ||= Object.new %> <%= $o.object_id %> <h1>Java incrementing static integer</h1> <%= TestClass.incrementAndReturnNumber() %>
Our results now look a lot more useful. The Java static integer is getting incremented each call to the view:
Ruby global number 1 Ruby obj id 244 Java number 1 Ruby global number 1 Ruby obj id 256 Java number 2 Ruby global number 2 Ruby obj id 244 Java number 3 Ruby global number 2 Ruby obj id 256 Java number 4
From this little experiment, Java statics seem like a possible way to go for storing temporary data on the server side (eg, a cache implemented as a singleton) for JRuby / Rails. Another option may be to use the ServletContext from the JRuby Rails integration servlet – probably an area worth investigating.
Are C# and .NET losing ground as Martin Fowler suggests? Or is Java’s market share dropping? What about Ruby? And what about the Australian market in particular?
Here’s what I’ve been able to find.
Job Trends
Which technologies have the most demand for people?
From Indeed.com, which claims to search “millions of jobs from thousands of job sites”, but I suspect may have a USA focus:
“Best Talent Index May 2007” from Best People Solutions gives an Australian perspective:
Here’s job counts from the (largest?) primarily Australian job search site Seek on 5 June 2007, 3pm (today):
Keyword(s) | Number of positions found |
Java | 3,414 |
“.NET” or “dot net” | 2,744 |
“c#” or “c sharp” | 1,722 |
ruby | 100 |
As an aside, I remember doing a search on Seek for “ruby” about 6 months ago, and getting under 20 jobs mentioning it.
Search Engine Number of Hits
Extract from the TIOBE Programming Community Index for June 2007:
Position Jun 2007 |
Position Jun 2006 |
Delta in Position | Programming Language | Ratings Jun 2007 |
Delta Jun 2006 |
Status |
---|---|---|---|---|---|---|
1 | 1 | Java | 20.025% | -1.10% | A | |
2 | 2 | C | 15.967% | -2.29% | A | |
3 | 3 | C++ | 11.118% | +0.45% | A | |
4 | 4 | (Visual) Basic | 9.332% | -0.85% | A | |
5 | 5 | PHP | 8.871% | -0.72% | A | |
6 | 6 | Perl | 6.177% | +0.17% | A | |
7 | 8 | C# | 3.483% | +0.25% | A | |
8 | 7 | Python | 3.161% | -0.30% | A | |
9 | 10 | JavaScript | 2.616% | +1.16% | A | |
10 | 19 | Ruby | 2.132% | +1.65% | A |
I think this gives a good idea of web buzz, but suggest that most non-IT companies do not publish information about their projects and chosen technologies and languages on the web.
Conclusion
The data collected suggests that:
- Both .NET and Java are major players in the job market with thousands of positions advertised, implying wide industry adoption of both.
- Neither .NET nor Java seem to be undergoing any significant decline in jobs.
- Java has much more information about it on the internet, although .NET is slowing gaining ground and Java slowly losing it.
- Ruby is comparatively tiny but growing rapidly in terms of jobs and information on the internet.
Thanks
Thanks to Jason Yip and Suzi Edwards for their help finding/sourcing information.
Recently got a JRuby/Rails system with Java integration up and running. Unfortunately, it took quite a few hours, as most of the docs and code you find through Google are out of date.
If you use JRuby 0.9.2 from Codehaus, you will get an error similar to this when you try to access a rails application:
[2007-02-26 17:54:59] INFO WEBrick::HTTPServer start: pid=22540508 port=3000
<ArgumentError: Anonymous modules have no name to be referenced by>
[“c:/jruby-0.9.2/lib/ruby/gems/1.8/gems/activesupport-1.4.1/lib/
active_support/dependencies.rb:402:in `to_constant_name’…
If you’re stuck in this rut, fear not! Nick Sieger has written very helpful instructions which outline how to get and set up the latest development snapshot. Please note that in addition to the instructions, you need to set your JRUBY_HOME environment variable. Under Windows, do something like this:
set JRUBY_HOME=c:\jruby
If you’d prefer not to use the snapshot, you can get the source code through subversion from:
http://svn.codehaus.org/jruby/trunk/jruby
but at the time of this post, you need to run svn checkout or update with “–ignore-externals” to avoid the following error:
Error: URL ‘svn://rubyforge.org/var/svn/bfts/bfts/trunk’ doesn’t exist
Many thanks to Nick Sieger and the JRuby user mailing list for their help.
I was reading through some code the other day and was surprised to find that it was using doubles to represent dollar amounts. Reason for the alarm bells is that doubles and floats cannot accurately represent many decimal fractions (eg, 0.1), since doubles and floats internally work with powers of 2 rather than powers of 10. These inaccuracies are likely to lead to significant errors, especially when performing arithmetic (eg, adding up a table of dollar amounts). See this IBM article for a more in depth explanation and examples. The solution is to use types that work with powers of ten internally. In C#, you can use ‘decimal’ and in Java or Ruby, ‘BigDecimal‘, to avoid these problems.