Bio Nick Sieger is a staff engineer at Sun Microsystems where he has been working on a team building a large JRuby on Rails application. He is a member of the JRuby core team, leading the effort to improve Rails deployment in a Java environment.
I have been employed at Sun for a little over a year now, I started to work on a Rails project, and I have also been doing lots of work on JRuby related tools and infrastructures specifically in Rails, running Rails on JRuby.
One of the first things I started working on couple of years ago was an ActiveRecord adaptor that allows Ruby to talk to JDBC databases inside JRuby. And after that I had some frustrations with existing tools for packaging the war files so I built a utility to build a war file that is very simple and it is based on rake I called it warbler. And then more recently a couple of months ago, around Java 1 timeframe I released a new server bridge called JRuby Rack, which allows Java servlet container to look like a Rack adaptor or a Rack compatible web server, to any Rack application so we can now run Rails with this and we can also run any other Rack based Ruby application.
Almost. There are some details that still need to be worked out, but the basic idea is that once you tell what your Rack application is, the way you do it today is you have to put some small configuration inside your .war files, web XML file to say: "Here is my Rack application", using the Rack builder type style. And then that would load up the application when the war is booted up.
Let's see, I guess I have done some work like Shell integration, I have done a little bit of work on Java integration, but most of my work is concentrated on the Rails bits.
It's just the way JRuby interacts with launching processes. Because the API that Java exposes for launching some processes is not very mature and not very close to Unix, we had to do a lot of maintenance in that area to try to make it behave more like Matz Ruby's system calls, and we are still not quite there. We have done a lot of experimentation with using just regular Java APIs to using the JNA library to do some of the more system level type stuff. We are getting pretty close, JRuby has come a long way and the edges of compatibility with JRuby between JRuby and Matz Ruby are becoming smaller day by day.
That's right, so the problem today is that every Java object when it is brought into the Ruby world inside of JRuby is it gets wrapped. A Java object is wrapped around. So there are lots of extra layers that the calls must go through in order to pass from Ruby back through to Java and the next re-write of Java integration hopes to do is to eliminate that wrapper so you can have a near direct contact between the Ruby objects and the Java objects, and that would probably happen with some runtime code generation. So this is what Charles and Tom are calling lightweights. The idea being that things like native Java types like Integers and Strings, we're going to try to attempt to fuse those into Ruby so that we don't have to wrap them into a Ruby like object and so certain things like Integer - no, Ruby Fixnums will be directly mapped onto Java Integers and things of that nature.
I think with the 1.2 series of JRuby they are going to plan to start on that work and it has just begun and we decided to take the test first approach to some extend where we are trying to write specs up front for how the Java integration layer behaves today, so we can make sure it will maintain some level or a high degree of compatibility, so that applications written before JRuby 1.2 will continue to work on JRuby 1.2. So there is the process of writing specs for those has begun and I think that there is starting to be refactoring effort that's going to go in parallel. I haven't been talking to the guys very closely so I am not totally up to speed on what their plan is, but they will probably get that information to you pretty soon.
8. One problem with code generation that you pointed out in your blog is that it fills up the permanent generation, [that was an issue with] the just in time compiler. Do you think that is going to be an issue?
Right. Yes, that's a good question. So the problem before was that it was a problem that we came across actually at the project I am working on where we have Rails application in a web server and you have multiple runtimes over the same Rails code. And we are compiling a lot of Ruby methods and I think, I suppose there is still the potential for that to happen depending on whether we can figure out a way to fake out the JVM and tell them not to hold on to code, but certainly there is little more speculative work, I know Charles is involved pretty heavily with John Rose and Da Vinci machine team and the JDK7 work that has been done in that area to try to improve the ability control how lightweight methods behave in the JVM so I think they probably are trying to straddle that work at the same time and see if there is some alternative way to provide a back route or a back port type of feature for that. I don't know how successful they will be in that but I guess that remains to be seen.
Yes. There is a limit right now which is a little artificial and maybe a little bit too low. Another tool we used to solve is that there is actually a shared method cache, a class cache between multiple runtimes. So the fact that we had to use multiple runtimes for Rails right now, we can boot strap them in a way that they all share a common cache for those class files.
Sure. JRuby Rack is set up to run with multiple runtimes out of the box and if you don't even have to do anything necessarily. I think people on their applications embedding applications, I am not sure if they use that feature but certainly it's a nice aspect of JRuby that it embeds so well and you can take advantage of it.
So I think the current thinking is to dovetail with Rubinius, Rubinius already has a somewhat established multi virtual machine, API and I think Charles' opinion is that there is no reason to try to reinvent the wheel, we already got somebody in the community who has something that works really really well. We may as well map on that and adopt that same strategy, that's a kind of pretty common theme throughout the development of JRuby and Rubinius serving that past year.
Yes. There is actually a lot of co-development on specs, we have one JRuby member team Vladimir, who does quite a bit of work on specs and there is also a couple of guys on Rubinius team doing a lot of work there as well so there is definitely a lot of shared collaboration that happens there and we are running all the Ruby specs on JRuby pretty regularly and the level of compatibility has really helped out and is gone up as a result and has helped us out quite a bit.
I think that it is still in the status of a side project. I think it's more of an educational process for Charles' and Tom as implementers to see what Rubinius APIs look like and what if it was mapped into JRuby would that help with estructuring the internals of JRuby in such a way to make it more efficient and I think their philosophy in the JRuby team has been one of playing well with the other implementations and with other efforts in the community and so that is another way to sort of support what other people are doing. And I think it's a hobby stage but if Rubinius gets well established more enough that some of the APIs in Rubinius that go down to a level of methods and compiled methods and that Smalltalk-ish approach to the way VM internals are modeled inside of the language. If that gets more traction then that's something that we'd like to expose in JRuby also.
As we hinted before the Java integration is one area that will receive a rewrite, that's one theme. The other theme is going to be 1.9 compatibility. And beyond that I don't know if there are any specific plans to do major features, I think the compiler improvements are going to be something that is ongoing. We found recently that the JRuby just in time compiler actually is a detriment to performance in a lot of cases, that the interpreter can often run things faster so we need to do some more investigation to figure out when it's appropriate to JIT methods into JVM by code and when it's not appropriate.
I don't remember the exact specifics but it comes up in the running of Rails applications particularly I think in areas like routing and controllers and views. I think JITing large Ruby methods turns out to be not very efficient. JITing things like ERB templates is also not very efficient, it's better to just let the interpreter use those also.
Yes, I haven't looked myself and I haven't talked to the guys to see if that's what is responsible for it. I think it's just more in the way the code is generated, more of verbose than it needs to be. And for whatever reason the compiler is generating code that turns out to be bulkier than what code it would actually run if you just go through the interpreter path.
That's probably one of the reasons too, I'm sure.
Yes, I suspect that is how it will work. I am not sure internally how they plan to do it, there is obviously some parser changes between 1.8 to 1.9. and of course the Ruby core team has the advantage of having separate branches for that work and somehow we are going to have and figure out how to support running two different parsers with the same runtime code base.
Yes, exactly. So I am not sure what the plans are for that, I am sure Tom has some scheme put up to be able to handle that whether it's a probably an expanded AST with support for the full set of AST both 1.9, Ruby 1.8 plus the additional nodes and features that 1.9 has. I haven't talked to him yet to see exactly how it's going to play up but it should be interesting.
I think the 1.9 development will be starting soon and the Chalres and Tom seem fairly confident that they can track changes pretty closely even though the 1.9 is not totally baked yet. And they have been pretty good about keeping up with those efforts in the past, I think it shouldn't be a big problem.
Yes so a few weeks ago when the Ruby security vulnerabilities came out, I thought it would be a prudent thing to upgrade Ruby on my server, so I went and I built the latest Ruby and at that time it was patch level 230 which it turns out a lot of people have problems with that, and I didn't have any problems maybe because it was running an older version of Rails or something. But I ran patch level 230 but then I started noticing memory leaks that the server would bogged down, and rather than try to further experiment with more patches to Ruby I decided "Well I should have done this a long time ago, I should be dog fooding and using the technologies that I myself have been working on" and so I decided it would be a good time to run JRuby on Rails. It was actually a fairly painless process, I already had Glassfsh installed on the server, I was doing some benchmarking stuff couple of months ago, so that was there, and I had a JRuby code base checked up so all I had to do is pull in all the bits that I had written and I had to do a little bit of tweaking in the blog code base because there were some older features, artifacts of running older versions of Rails on the blog code base that I had to tweak.
No, it's Typo from probably a couple of years ago now and I haven't been keeping it up [to date] and it has been working pretty well so pretty good in JRuby is pretty straight forward. I still use Apache as a front end so I had Apache monitoring a certain directly within a .htaccess files that says "Here is where the static files are", and then it was proxying to a Mongrel before and now instead of proxying to a Mongrel I just switched the port over and now it is proxying to glass fish instead. And it took me a couple of hours, it was pretty seamless overall and I haven't have to touch anything since then and the performance seams to be pretty equal. Typo actually does a pretty good job at generating static cache files so once a page gets generated it seems either way it gets rendered pretty quickly. I haven't noticed any problems at all since I switched. I am happy.
I guess I can't think of any specific project right now but I get a lot of satisfaction out of seeing reports from the people in the community they would be able to pull JRuby down and that it runs very well out of the box, it's very easy going. And then they pick up something like warbler and they find that they can just turn their Rails application into a war file without trouble, and so I guess it's mostly just the open source pieces that I put out there and seeing that other people are using them successfully and with very little trouble and seeing the uptake of Rails in the Java community start to grow slowly I hope that over the next year or so we start to see that grow even more.