 So, we are going to be talking about JVWay today and since some people have asked, it's not going to be as deeply technical as the one we did last year talking about method dispatch and optimizations and what not, we're going to be a little bit more about practical details, actually running applications, building stuff. So we will jump right into it now. I should see if my mic works. Yes. All right. I'm live. I'm on. And what happened to ... Oh, right. Okay. There we go. So, the agenda. You can just scan it with your eyes. We're going to hit all these as we go. Hopefully we'll have enough time to get through all this and have room for some questions at the end. So, there's a short story here with the pictures and we'll maybe leave it to the end to see if people can figure out the theme. Yes. See if you can figure out where all these pictures come from and what the common thread is. So, a quick question though. How many people are using JRuby right now? Cool. Okay. So, it's probably about half the room that's not using it and that's ideal. Those are probably the best people to be in here since some of the others are already kind of sold on some of the benefits. So we are the JRuby guys. I'm Charlie. And I'm Tom. And we've been working on JRuby for quite a while and now been at Sun Microsystems for about two years working full-time on JRuby. We do work from home in Minneapolis. There's not really a technical sun office up there. So we work from home and that home usually means at a coffee shop these days. So we get together a lot for that. And we've kind of become, well, I don't know if we're willing conference junkies, but we've got at least a conference every month that we present at and I think the most we've had at any given time was we each had three trips in a given month. We do three. It is too many and trying to balance that with getting stuff done is an interesting challenge. Okay, so a year on from JRuby last year, it's amazing how much has changed. Last year, we've just barely gotten the compiler finished and it wasn't to the point where it ran all the tests and it wasn't 100% correct. So it was done, but not really done. As we proceeded on, we did a series of release candidates for JRuby 1.1 in the following winter. And since then, we've done five maintenance releases to the 1.1 line. We are on 1.1.5 now and the numbers kind of amaze me when I started looking this up. So we fixed 113 actual user reported bugs in 1.1.5 and 1,500 user reported bugs since last year. Similarly, have 411 revisions in the repository in 1.1.5, which is about two months' worth of work and over 3,000 revisions since last year. So there's been a lot of work going on. To kind of put this in perspective, the JRuby repository just crossed 8,000 revisions. So three-eighths of the JRuby work has actually happened in the last year. So it's pretty funny too. A year ago when we were here, we were saying it's done. It's compatible, use it, and we've fixed 1,500 bugs since then. So it's a never-ending battle on that. But each year we say compatibility is more done than it was before. And it really is getting to the point now where almost everything should work. There's not a lot of outstanding JRuby compatibility issues left. So if last year it was medium well and stake parlance, now it's like shoe leather. Yes, exactly. It's starting to turn into a block of coal at this point. So we're getting very close to really, really done. Performance is very good right now. I'm not going to dive into this a lot, but performance in general. On microbenchmarks, JRuby is the fastest Ruby implementation. But microbenchmarks don't always translate to application performance. And so there's continuing work to figure out bottlenecks in our core libraries, bottlenecks in the way we run Ruby code. And it's going to always be improving. So we've got a lot of room there. I still have continents to explore. We still have continents of performance to explore, like some of the other implementations do. And 1.9 support we've now started to add. Because 1.86 is looking good, we're actually going to add 1.9 support. And I'll talk a bit more about that later. So the first thing we realized over the past year is that just trying to sell JRuby as, yeah, it's just Ruby and it's a great Ruby. And you can use it for Ruby. Doesn't really focus on why this is a good idea and why this is an important thing to remember. So we started talking a little bit more about what actually makes JRuby a great implementation. And it really comes down to the JDK hotspot. So hotspot is the optimizing virtual machine that's part of Open JDK, the open source Java development kit. And the number is like 500 man years. This is some sort of estimate that comes out of sun. But there is undoubtedly a lot of effort put into this thing. Legendary dynamic optimizations that it's able to do. The GC, other VMs look at the hotspot GC as a pinnacle of where garbage collection can get to if you really work on it for a decade. So being able to take advantage of those things means that we don't have to worry about writing that stuff. Hotspot also has an optimizing native compiler, just-in-time compiler. We can actually turn on flags that'll show all of the assembly code that hotspot actually turns Java into. And since we compile Ruby into JVM byte code, that's also getting jitted down to native code with optimizations at runtime. It's extremely stable. Whenever we find a segfault or a crash in the JVM, which I think has only happened two times in the past four or five years, we know it's automatically not our fault. It's the JVM's fault. And they will immediately prioritize and fix that. We've worked around a couple of those in cases, but it's so rare to actually have a crash in the JVM that it's almost non-existent. And it's generally from unusual byte code generation where things like the Java compiler doesn't normally generate code that looks like that. Right, right. So they've got a whole body of Java code that they're testing against, which is coming out of Java compilers. And then my compiler comes along and does all this crazy stuff for Ruby, and things happen and things change. But they immediately recognize it as a problem of the JVM and they fix it. The team works on the JVM separately. The other interesting thing about hotspot is that it's actually a dynamic VM under the covers. Everyone thinks about the JVM being, oh, it's the Java VM. It runs Java code. And that's totally untrue. The JVM is a virtual machine that runs JVM byte code. Any language that can pile down to JVM byte code can run on this VM. And because of that, under the covers, it has to optimize much more than it has to be able to optimize as it runs the same way that other Ruby implementations are going to have to do that sort of dynamic optimization. So by using the JVM, we've actually got probably one of the best dynamic language VMs under the covers already. And that's a really important point. And of course, it's also pervasive. Anybody that has a Mac here, I think there's probably a few of you, you have hotspot in the Apple JVM. And if you're running Linux, there's ports you can install. There's Debian packages, Red Hat packages. They're all over. And of course, there's trivial installations for Windows as well. And a lot of machines just come with it. And now that Java's open source, it will be on every Linux distribution. Right. Now, any platforms that OpenJDK didn't support a year ago, it's got support underway now. So it's going to be everywhere. So here is probably the most technical slide of the whole talk. This is kind of where JRuby fits together with the JVM and how all the pieces work together. So on the left side, we've got Ruby code coming in. And anything in red is Ruby. Anything in blue is Java or the JVM. So application code comes in, which is your app or Rails or whatever. Ruby standard library, we ship with just the normal Ruby standard library, which is all Ruby code. You can also pre-compile code into a .class file. And it's still just Ruby code, but it's Ruby compiled into byte code. So that all passes in through the runtime. It gets parsed or class loaded. And then we've got an interpreted mode where we actually walk the Ruby AST at runtime, pretty typical like Ruby 186. We've also got a byte code way of executing. So either your pre-compiled code will come in and we'll run it as JVM byte code. Or as it executes, we will find hot methods and turn those into JVM byte code eventually. Then they get the same optimizations that other JVM byte code does. And then from there, it calls into the core classes, calls into the JVM, and calls into other Java libraries. And that's the general layout of how things all fit together inside the JRuby implementation. Okay, so we started to work on Ruby 1.9 support in earnest now, and actually that's not true for some time now. We've been porting libraries over to 1.9. Sort of pecking away at it. Ruby 1.9's kind of been a moving target, so we've only done what seemed pretty stable. Only added the features that seemed like they were finished. So fibers, rational, complex. Right. 1.9 array methods, stuff like that. In the last couple of weeks, we started porting the actual 1.9 parser itself. And I'll take some blame that it didn't get done by today. That was the original goal. But it's really, really close. So. It's only taken what, about a week's worth of work? A solid week, yeah. A solid week. My car blew up during a trip, so it's kind of taken some time away from working on the parser. Mars and when he ported the Oniguruma engine actually did a lot of work towards supporting multinationalization. Right, for those of you that don't know, Oniguruma is the new regular expression engine that's included in Ruby 1.9. And it's the primary reason why character encoding and Unicode and other things are gonna work so much better under 1.9 than they do under 1.8. And so naturally, to have that sort of support, we needed an equivalent regular expression engine. And luckily, we had a JRuby community member that ported Oniguruma in about a month's worth of work. So that's done, and it's a huge, huge help for us. And so those bits are there, but we haven't hooked them up together yet. Geez, probably a year and a half ago, bytecode engine was made for running our bytecodes. And I don't think we're gonna go too much further with this for the time being. It's still there. The idea that we had was, if we actually could run YARV or Rubinius bytecode that it would be faster than running our AST and walking the tree, it turns out that now that we've got our tree walking optimized hotspots inlining almost all of that stuff. And our AST walking is actually faster than Ruby 1.9 in some cases. So it's unlikely that we're going to continue on the bytecode engine approach. However, if at some point there is a standard binary format for creating pre-compiled Ruby bytecode, we'll re-explore this and maybe build another, build an engine that can run that code directly. Never say never. Never say never. Probably the most interesting thing about JRuby is 1.9 supports this enabled as a runtime switch. And that just loads a few different classes and replaces a couple of others. And it's the same binary. Actually, I'll go, I'll drop out to the demo now so you can see what that actually looks like in practice. So I have two examples of Ruby 1.9 stuff. So here is a simple test of the new fiber functionality. It's kind of like micro-threading stuff. So creating a new fiber, doing some yielding, doing some resuming. And of course, this is only available under Ruby 1.9. So if I run this with just regular JRuby, we get no such file load, fiber. There is no such library in Ruby 1.8. And if we take a look, see JRuby is Ruby 1.86 compatible here. But like I said, we have 1.9 support in the same binary. We figure people are going to want to be able to play with this on and off. And not necessarily have two separate JRuby installs like you have to have two separate Ruby installs. So if we look at JRuby-help, there is just a 1.9 flag. 1.8 is default, obviously, because most people are still using 1.8. So if I do dash dash 1.9, and then version, now it's actually Ruby 1.9 compatible. Patch level 1.14. Patch level 1.14, obviously we don't have the right patch level stuff on here because that's not quite set in stone yet, but Ruby 1.9 compatible. And if I run the fiber tests now, they all pass. And perhaps a better example, this is just a library thing, right? The parser, Tom is a little modest about this. The parser is not quite done yet. Not all working, but it's working enough to support some of the basic features that were added as part of 1.9. So here you see this, NetBeans is not liking this because this version of NetBeans only understands 1.8 syntax. But here you can have rest args show up earlier in the argument list. Similarly down here, we've got the new stabby lambda syntax. And neither of these are gonna work if I run this under Ruby 1.9 or Ruby 1.8 mode. It doesn't even parse, because it doesn't know what that's all supposed to be. But we turn on Ruby 1.9 mode and, oops, I gotta switch over. So it's not working on trunk. I have a separate window for it. In my tree. In the in Tom's tree. So I'll run it with 1.9 in this one. One other unique requirement we have over the C implementation is that our AST gets used by all the Java IDEs for parsing. So that's one reason why NetBeans isn't showing that as valid code is because this parser hasn't been written yet for them to use it. Right, they actually use our parser. And so once we get this completed and we're satisfied with the Ruby 1.9 parser, NetBeans will also have full 1.9 support. And so will Eclipse and... So will Eclipse and everybody else that's using our parser too. So another advantage of having it available in the Java side of things. And so the last thing on this list is that we're planning on getting this done as a Christmas present, so. Right, so when 1.9.1 comes out around Christmas, the final version, hopefully we'll have a JRuby release at the same time with 1.9.1 support. So, crossing our fingers. Well, we're leaning on Marson to do all of the internationalization stuff for us. So hopefully that will happen by Christmas. Okay, so it's trivial to call Java from within Ruby. And if you have a Ruby library you like, great. You should use it, then it's portable across all the implementations. But sometimes there's a feature that's missing from the Ruby library. Sometimes you want another option. And there's literally millions of Java projects out there. So you should consider using it. Another thing is if you're actually in a business and they already have done a large body of Java work, why go and write a raster soap bridge to it when you can just directly call it? It's quick and dirty and fast. And Java libraries tend to be crossed platform more often than not. So my fingers were crossed when I said that, but it's usually true. So generally you get the benefit of all those libraries. You know, XML is a perfect example. Recently it was a big news that LibXML had been updated to run under Ruby. And it's great, it's great that LibXML works. There's probably 20 XML parsers on the JVM that have been working for years now. And you could just use those from within JRuby any time you want to. It's just Java code, you're just calling methods. So those sorts of things, there's always lots and lots of choices on the JVM, too many choices. But with Ruby, it makes it trivial to call any one of those libraries. So when we were at Java 1, we saw this nice talk about JMonkey Engine. It's a 3D scene graph library and I thought, ah, this would be some really cool eye candy. So it's OpenGL, Hardware Accelerated Scene Graph library and it's used commercially by several companies. A perfect example of something that, it's a huge benefit. Do you want to run this or should I? Yeah, you can start it. All right. You'll have to play it, too, though. Well, yeah. You have to be a second player, I think. This was originally like 800 lines of pretty messy demo Java code. So we'll run it first and then we'll show you what that code looks like, too. And part of the fun was actually rewriting this and seeing how much does it look like Java after we're done rewriting it in Ruby. All right, so it's gonna start up. So settings all look okay to me. So now the logic behind this is all written in Ruby code. And it's just calling into the JMonkey Engine library to do the rendering part of it. I'm playing one player. There might be a bug in some of the explosion code. Yeah, that's Tom's addition. You'll see that there's a little weird set of code in there when I'm showing it. And you notice that it's actually doing the texture map or the bump map on the hills that is affecting where the balls are. Check it out. When it goes over the water, you can actually see a reflection of the ball on the water surface, so it's cool. This is the stuff you can get with hardware acceleration. And as far as I know, I don't know if there's a scene graph library for Ruby. Does anyone know? I suppose you can call into C or C++ ones. I wanna try this one and see if it works. Full screen. Full screen. All sabotage the presentation here. No, didn't like it because of the projector stuff. But all right, what do you see? I mean, it's a library that's out there and people are using commercially that you can start building. You can build a game like this in Ruby really easily. So yeah, let's pop over to the code and I'll let you, so there's the main King Kong. So yeah, here's the main class. At the top, we can see there's a class called main. It's Ruby obviously, and it extends a Java class. So this is a Ruby class extending a Java class. It needs to implement two methods, basically a knit and update. You'll see that it's camel case. This is one of the few places where the Java kind of rears its head. But if we actually look at the body of the init method, you can see that we're just setting up some domain like objects and we're appending them to the written note of the scene graph. It doesn't really look like Java at all to me. Do I have any camel, oh, a couple camel case methods. I didn't underscore those. In Ruby, you can actually use underscore or camel case methods. And in the update method, which gets called every time that there's a frame update, we just do our stuff. We update the sky and water. If there's any UI, we'll move up and down. If we run into a paddle or one of the sidewalls, we'll bounce a particular way. Looks just like Ruby code. If we'll just look at the domain of the ball for a second. It is just Ruby code. Well, yeah, it is just Ruby code, but at some level it hits Java. Yes, so in determined level. We have a Ruby class ball, extends from a Java class called sphere. We have an accessor for velocity to control the ball's velocity. If we look at the bounce method, we just kind of affect the velocity. Again, it doesn't look like Java at all. And it was amazing how simple it was to translate this and how much more readable it was than the equivalent Java code. Right, and this is all Ruby code running at runtime. This is determining the direction, determining the velocity, all that stuff, and there was no noticeable performance slowdown from it. All right, so continuing on to another practical area. One of the big things that we've been touting with JRuby is that it's really, it's dead simple Rails deployment. And now we've also started to expand out to other ways of doing deployment and other web frameworks. Just last night, the Glassfish team, Glassfish is the son's app server, they released the new version of the Glassfish gem, and you can gem install Glassfish, and it'll pull it down. It's about a three or four megabyte gem, but it's essentially everything that you need to do a production deployment of Rails or Merb or whatever else in one gem and one command. Let's see, single process deployment, and of course we're native threaded in JRuby, so this one process can be your entire server across cores. You don't have to have multiple processes, you don't have to do any forking tricks, you don't have to be doing load balancing across a bunch of them, making sure that zombies don't run away and making sure you kill off dead processes, none of that stuff you have to do anymore. One process and it's deployed and running. And really it's like the simplest deployment literally possible, you install a gem and you run a command and it's done. So I'm gonna go out, I've got a couple sample apps here. It could be a tiny bit easier. Tiny bit easier. Script server. Oh, if it was the server script, I suppose Tom's pedantic about script server being the way. It's the only way. All right, so I've got a test app here, it's just a Rails app, I've also got a Merb app here, standard stuff. And I'd already installed it, but a gem install, glassfish, and you can pull it down, it's not very big. But what you get is this glassfish command. And you specify on this command, you can set up various parameters like what port it's gonna be on, et cetera, what environment you wanna run. But you pass the directory to your application and run it. And what this is going to do is it's going to start up the core of glassfish, just the part that's responsible for serving pages fast with a run of the JRuby instance inside of it. I'm running Rails 2.2 here and you can see that it detects that it's running Rails and so it does the Rails startup stuff. And it's now deployed the application at the root context on my local machine. So if we bring this up now, there's our app. And so you get all the typical details here, you know, running Java. I've got it hooked up to the JDBC version of the ActiveRecord MySQL. We used to always say, point out the Java part and say C, we're not faking it. Yes, we love that. So this is like three years on now when this was so novel before and now it's just, yeah, it's Java. Everybody knows it's running on top of JRuby. And I've just got one controller here that's, you know, trivial. It should be pointed out that neither one of us are Rails developers. Yes, so we'll not see a whole lot of Rails information here. You guys can do Rails stuff or Merb stuff or whatever and let us know how it goes. We just make it run well and make it deploy well. So like I said, it can also be done for a Merb app. And I think it works for like Sinatra and any other Rack-based stuff. So one command deployment again, Merb app. And in the interest of the time, I wanna actually go and hit this, but you'll see, ah, detected Merb application. So it knows what the application is, does a little bit of inspection and then it's done, it's deployed. And this is production server, this is done. There's no other fiddling around with this. You can put stuff in front of it if you really want to, to handle static files and whatnot, but this is a deployed production application. Can't get easier than that. And across cores again. So, okay, we'll drop back to these slides. We're doing good on time, I think. Well, there's some room for questions. Okay. Okay, so we've always said it would be the holy grail if Rails was multi-threaded. And this is because JRuby uses native threads. It would be nice to be able to make use of those native threads within Rails easily. Right, up until Rails 2.2, it prevented multiple requests from running through the same Rails instance at one time, because it just wasn't safe for it to do so. So the Rails folks were kind enough to actually make Rails 2.2 thread safe. And there's a special thread safe mode, and it's a big deal. If we looked down at the diagram, if we wanted to handle three concurrent requests, we'd actually have to start up three separate JRuby and Rails instances to handle each concurrent request. This is all still in the same JVM, the same process, but it was more memory. Like you would have with multiple Mongrels, we'd have multiple JRuby instances to handle those concurrency issues. So with multi-threaded mode, it just starts up a single instance and for each concurrent request, it just spawns a Ruby thread and handles the request. Pretty basic, and so there's a couple of benefits for this. First, since we only have one instance, we have more requests hitting the same code path. So hotspot warms up faster and things optimize faster. Right. And the more important one is reduced memory. So we did the lame test. We set that totally unrealistic Rails app that has one controller, one model, and one view and then we flung a bunch of requests at it with a concurrency of 10 and then we looked at the heap in thread safe mode and in a traditional Rails mode. And so I'll go over this graph in least to most interesting numbers. The least interesting is Glassfish, the yellow bar which is taking about 30 megs in each case. Right, essentially the same amount of memory. And then for the runtimes, well, you can see that on the multi-threaded mode, that small blue thing is about one tenth the size of 10 instances because we're only firing up one instance versus 10. You can imagine if we fired up 20 instances that blue bar would be twice as high. But the most interesting number to me is the application data. In the 10 instance mode, it's using about 3.3 megabytes per instance for application data. But if you go and look over at the multi-threaded mode, it's using about 0.5 megs for application data and that frankly surprised me. That could just be simply Rails 2.2 improvements. Yeah, for sure it could. And they've done a lot of work to clean that up. The thing that's very surprising too is that the Rails instance stuff is about the same size. Yeah. So there is a caveat. This is the size of the heap, or the amount of heap that's in use. Right. The JVM is generally going to allocate about twice as much heap as is in use. So you're gonna get numbers that are about two times this for a single simple application. And there's a little bit of overhead for the JVM itself to start up. But at this point with this kind of drop in memory, we can easily beat any deployment that needs multiple instances. And even single instances now we're down much more on par as far as memory consumption goes. So now you can run a JVM Rails application in a 256 meg slice, for example, and it'll actually work. And what did you do the other day? You went and played with some of the settings. There's a whole bunch of settings for how you can tweak the way that the heap is laid out and the way it's allocating memory. And you can shrink it down pretty good. So there's more research there, but it definitely was the holy grail for us to have one instance be able to run all of the requests on the system. And there's one other caveat worth mentioning. You can't lazily go and initialize a class variable without taking some care when you're doing it because now all these concurrent threads are trying to access your class at the same time. Right, so the Rails thread safety stuff is awesome and it really is going to be a sea changing event for Rails. A lot of the other frameworks realized long ago that not having the ability to run multiple requests at the same time was a problem. Merb especially has taken special care to make sure that things are concurrent from the beginning. So what we can expect with Rails 2.2 being thread safe is not that it's going to be perfect right now. There's going to be libraries that break some of your applications. If you're doing Rails work, they're probably going to have broken areas in them, but you have the opportunity to find those problems and fix them now. You didn't even have the opportunity to do that before and already some of the libraries like the MySQL driver have been fixed to allow better concurrency. So we're going to see a cascading effect from Rails being thread safe and all of the other libraries and applications will follow. From a memory perspective, it's going to be well worth the effort on any large scale app. Absolutely, absolutely. And I think it's probably worth mentioning that thread safety in Rails is going to help the green threaded implementations and the non parallel implementations just as much because if you only have one core, you should only need one instance in that case. And even if you have multiple cores, you're going to be able to reduce the number of Ruby processes you have to run because it's going to be spending time in IO and then it can do another request while it's doing that. Instead of spending time waiting for a rest request or waiting for a query or whatever, then it can be processing other requests at the same time. So thread safe Rails is a huge deal. A huge deal. There's no process context switching either. So you don't have to involve the process scheduler and stuff in your OS. Right, right. You're going to get a lot better performance out of that. Yeah, there's a question in front. How do you change the database to next screen since the database is YML? Yeah, all that I changed, I can actually show you what it looks like. It's really trivial. For all of the key adapter implementations, there is a JDBC version. So if there's ActiveRecord MySQL adapter, there's ActiveRecord JDBC MySQL adapter and there's a SQLite one and there's other databases and all that's really changed in the app itself, I just generate it dash D MySQL and then go into database.yaml and... We were hoping this would get fixed in Rails 2.2 that you could do JDBC MySQL with dash D. So I just add JDBC there and then install the appropriate ActiveRecord adapter and it's done and that's now using JDBC instead. There's a clever little hack that can use the database.yaml file, it gets run through ERB so you can actually do a platform check and rise up the JDBC part. In here you throw your if it's Ruby used MySQL, if it's JDBC you can test on both. So back to slides for a couple more here. Okay, so FFI was a recent thing that I think is it's really exciting that we now have this available. FFI stands for foreign function interface. It's a way to portably call C functions directly from Ruby code and bind them directly into Ruby code. So it's portable across implementations unlike C extensions that you may be familiar with like SQLite extensions, other stuff like that. The thing, what it turns out is that almost all of these extensions, a high percentage of extensions written for Ruby just wrap some C library and then maybe they add a little bit of nicety, they add some closure stuff and they add some other APIs on top of it but essentially they're just wrapping a C library. So why don't we just wire that in in a way that works across all implementations and write the magic around it in Ruby? And that's the idea behind FFI. And actually it started in Rubinius. Evan came up with the basic API for it and it's really clean, it's really nice. Show you an example in a minute. We liked it a lot and we saw the benefit of having this as a cross implementation C binding. So we implemented it in JRuby and included it in 114. Just last week I think it was Wayne Meisner, the guy who implemented FFI for us in JRuby implemented a CRuby extension to also do FFI. So now you can use this same syntax, same script, never write any C code and it will work across all three of these implementations, the CRuby versions, JRuby and Rubinius and be able to call out to C libraries. And it's gem install FFI for the Ruby one, like I say Rubinius and JRuby have it built in. So here is a really quick example, I'll walk through this and I'll show you a couple more in NetBeans. So here we require in the FFI library, we've opened up our module where we wanna store the C bindings for these functions. We extend the FFI library and from there we're calling FFI functions to do the binding of these different methods for us. We specify which library you wanna use, FFI underscore lib, and like it says here, C isn't generally necessary because all of these have the C library in but it could be FFI lib and curses, FFI lib, DL, whatever else you wanna call in. And then attach function provides the name of the function in the library, the name in Ruby we wanna bind it to which is optional, the argument types that we expect and there's a bunch of symbols that it recognizes and then the return value. So here we're expecting an unsigned int to be return, we use the symbol you int for the signature. And so then these functions are actually bound and at the bottom you see we're actually calling into posix.getpid, and this exact same code works across C Ruby versions, J Ruby and Rubinius. So any library that you can wire up in this way, you can use portably across all of the Ruby implementations. And more sophisticated C structs can be mapped. Right, I don't think I have a more complex syntax. You can also map in struct types. I don't have an example of that handy here. Here's an example where we're using more of an arbitrary pointer. This is calling out to Qsort, the Qsort function in the C library. And Qsort is interesting because it takes a callback. You pass in a function that it uses to do the comparison. So what would we use in the Ruby world to do callbacks? Obviously we'd pass it a block, right? So that's how Wayne and I were talking and we talked a little bit with Rubinius guys and this syntax we've got down here, once we bind, we've got a callback that we're defining, FFI callback, calling it QsortCMP, which we can use as a reference to that callback type from then on, takes two pointers and it returns an int. So down here you see that the Qsort function takes that callback type, QsortCMP, and that's all that's necessary. So in this code here we see we're calling libc.qsort with a block and the block receives two pointer instances, can examine them in whatever way is appropriate and then return an int out, FFI handles proxying all that back and forth and making sure that the callback is wired up correctly. So it's another really cool example. And let's see if there's also pty here. So here's a little bit more advanced example with more functions. This pty is doing exec and dupe and other stuff for file descriptors. Here's an example where we've got a buffer. We're specifying a buffer that we want to use for reading and writing memory back and forth. So it's an arbitrary size buffer that we pass to C functions. We create our buffer, it's doing, and of course you can define your own methods on this FFI module to provide your API. And this is the right way to do this. You shouldn't be writing a whole bunch of C code that does all of your block management and does all of your methods, your extra methods on top of the library. Just do the basic bindings and let Ruby be Ruby on top of that library. Then we all can use it and we can all share that library. So that's about it for FFI. And I hope everybody starts using this because it really is extremely exciting that we can now call into these C libraries and have it work in JRuby. We don't have to worry about can't build SQLite extensions because we don't support Ruby's API. Extra exciting since we don't support native C extensions. Yes, yes. So no more extensions, no more extensions. So then the final thing here, a number of people asked about various aspects of what? Oh, one more. Yes, just, I think this is the second to the last thing here. So a lot of people asked about the other aspects of Java. How can I use Ruby in different areas in the Java world? Especially people coming from the Java side that wanted some sort of equivalent. So here's a, we'll run through a couple of these. Servlets, first off is probably the most common one in this list that gets asked about. People wanna be able to just write a servlet in Ruby. The simple way to do that right now is to write it as a little rack application which is really trivial to do and use Warbler to deploy it. Warbler can deploy any rack-based application. That's the way you should do it right now. In the future, along with EE components, the second one here, implementing your own session beans and JMS beans and things like that, in Ruby. Glassfish, the Glassfish guys are working on having Ruby be a first-class language in the app server so that you can actually say I want to implement a session bean in just Ruby. Just Ruby alone. And Glassfish will handle instantiating JRuby and getting up and running and providing that as a session bean. Did anyone just shiver? So yes, so you'll be able to write EJBs in Ruby. Isn't that what everybody really has wanted all this time? It would have succeeded if only it had Ruby syntax. It's amazing that people ask for this, right? But it's out there, it's out there. Mobile and Embedded, lots of people keep asking us about mobile and embedded stuff. I think we get at least two or three questions a week from someone asking to run it on Android or Java ME. And the answer is that it's absolutely possible. On Android and the larger ME profiles, it's actually not gonna be terribly difficult to get it to work, because they are full Java implementations for some definition of Java. The problem is that nobody's really working on it right now. We would love to see someone start playing around with JRuby on Android and it would probably work great. It would probably work really well. But if you've got an interest in doing Android development or other ME platforms, just let us know and we'll find a way to get your code into a repository, get your commit rights, things like that. Patch is accepted. Patch is accepted and if you wanna just take over a whole project, that's even better. And then normal Java type definition so that I can write a Ruby script, compile it, and then have my Java code just call it as a normal Java type, construct it the same way, call methods directly on it. This is planned. The tricky thing here, and this is this kind of language theory stuff here, I will claim that Ruby does not have class declarations. Okay? There are no class declarations in Ruby. There are class instantiations. You instantiate a class and execute code against it, but you do not declare a class. And that makes it extremely difficult for us to compile it to a normal Java type because there is no type at compile time that we can create. So we've got various tricks that we're gonna use to try and basically make it look like a Java type, make it kind of feature compatible with the Groovy, a language that's a little bit more tightly integrated with Java. And I'm not sure exactly when we're gonna get to this, but it's like a JRuby 2.0 sort of feature. Having done a fair amount of scripting of Java from within Ruby, I haven't ever phoned a need to actually do this. I haven't either. And it seems to come up more than I would expect, but I suppose it's people that still wanna stay in their safe Java world and just write a little bit in Ruby. And that's perfectly valid. Okay, so now if people are interested in using JRuby and you're looking for a list of reasons why other people have chose JRuby, we kind of have this common laundry list of reasons people have given us. And this is basically just testimonials we've gotten from other folks. Java app servers are everywhere. So, you know, why install new server software when you can just bundle it up into a war file and send it? Right, and actually there's a lot of Rubyists who've come to us and said, I'm trying to get Ruby in the door at a lot of these organizations and they just refuse to install all of the stuff I want them to install. But they already have a Java server. So, it's all about the same thing. It's all about reducing barriers. Yes. Java libraries that Phil avoid, David earlier gave a good example during his talk of needing, oh crap. SNMP version three, which wasn't supported by the Ruby equivalent library, so it saved their butt for that project. And obviously the GUI library that's available for the JVM swing or SWT, there was also a SWT talk earlier for Glimmer. Those, there's no equivalent. There's no equivalent. It's a nice consistent cross-platform UI framework for Ruby. Code obfuscation, ahead of time compilation or in the case of ThoughtWorks, they actually hack JRuby a little bit to encrypt source code. Right, very easy to do that. Very easy to do. Running JRuby on Rails on an IBM mainframe calling to MS SQL server. Probably the weirdest combination we've ever heard, but you can do it. They actually did have someone doing that. Horrible, horrible combination of things. But hey, you know, whatever works. And speed. Right. Definitely. The thing is in our experimentation, we have, we're very hard on ourselves about whether performance is good enough. Almost everybody that we talk to that uses JRuby to run Rails or to run other applications, they say that far and away, it's faster than their old equivalent application they had in Ruby. And the fact that when you need really high performance code for mathematics or whatever, you can drop to Java instead of going calling out to C. Again, it makes it much easier to sell to get it into an organization. So before the final slide, how many people have figured out what these pictures are? Java users? No. Every picture we've had in here was taken from Charlie's camera on the plane for SkyMall. Out of the SkyMall catalog. Some of these are bizarre pictures that they have in there. But they seemed appropriate and I didn't have any pictures on hand, so we threw them in there. I especially like this guy here. Who knew you could buy a suicide device in SkyMall? Really, it's almost a terrifying picture. All right, so get involved. There's contact information for us and Twitter and we've got IAM if you want that too. We're on JRuby pretty much 24 hours a day. Somebody's there. The Wiki is probably the more interesting site to go to, but you can get JRuby from the main site and we've got, I think about five minutes for questions, so. Oh no, I started that like three or four minutes late, so. Okay, so we've got about two minutes for questions, so. Really good question. Yes, anybody? Yes. Is Glassfish automation for across nodes? I don't believe the clustering stuff is built into the gem right now, but people are running with the full Glassfish, running Rails, with clustering, and it works fine, works great. So that's definitely a feature request. If you want that in there or maybe it'd be a separate gem, you install Glassfish clustering and then you've got it automatically. It's not in there right now, but it could be. Yeah, in front. What kind of process? Like back on process. Oh, background process. Well, there's an ampersand that you can use to background it, or no-hup, or something like that. The typical demonization stuff that you use in Ruby to make it a background process doesn't work directly because it's depending on C calls and C libraries that we don't have, but I mean you can run the jQuery process in a separate, I don't know, what do people do for that when you start it up? Too bad Nick wasn't up here, but I think Nick is actually working on something to get better parity with some of the popular background process. Packages. Right, right. It's not as easy as running with Ruby because you need to be a little bit more explicit about, okay, I want to run this in the background and I want it to have, you know, not have a terminal and things like that, but it can be done. And people run Java servers in the background all over the place. Other questions? Yes? Just to point out, can you run the jrv, jrv in 1.9 mode? Not at the moment. Not quite, yeah. Yeah. But yeah, we will be able to. There's no reason that it would not work that way. Same sort of flag. I don't know, that's an interesting question. I don't know whether we include IRB 1.9 executable that would run it separately or if it'd be we'd add a flag to our version of IRB, something like that. Oh, you just add a flag. I mean it's all there and the other question that comes up and before anybody thinks of it is, can I use 1.8 syntax and have 1.9 libraries? And I'm like, oh man, I don't know, that's a slippery slope right there, but theoretically that sort of thing is possible. I just, I don't know if I want to do it. That's not cool there. I feel kind of dirty thinking about it, so. One, maybe one more question in the back there. How easy is it to write a library in jrv but use it in a Java app? It's not as easy as it could be. The primary thing you need to do to get a callable from the Java side is create a static Java interface that represents that service or that utility, that library, and implement that library or implement that interface in the Ruby code. From then on, that object can pass back and forth and look like that Java interface all the time. We don't have a one-to-one mapping from Ruby classes created at runtime to Java classes. So there's nothing for you to instantiate, nothing for you to compile against. But if you provide that interface or extend an existing class, then you can implement a service for Java from Ruby code very easily. Yeah, it's really quite easy. It's just not quite as much fun as I think people would expect it to be. I think people just want to have a compile phase and then it's ready. It can be called from Java, and that's the next step for us. And it looks like people are coming in for the next one, so we'll call this done. Thank you very much. Thanks.