 So the goal for today is to learn and know about the JRuby internals to maybe by the end of the day start working on your first JRuby bug. But JRuby 1.6 is going to be going into RC around December 10th-ish and hopefully by Christmas we'll have a final release of that. It has two big features. One we're going to finish 1.9 support and it's in fact even going to be mixed mode with a jet. So we'll have great performance and we're going to start docking Windows more. All these execution bugs that we've been fixing made us realize that we probably need to be at a Windows box more. Now also since last year things have been going well for JRuby. We had two JRuby comps. We had one attached to RubyConf last year and then our standalone conference in Columbus just a little over a month ago. And lots of folks are starting to take notice and start to actually adopt JRuby. So we're pretty happy how things have gone this past year. We spent over two years now working on this book with five people. So we're going to vlog it every chance we have. It is actually a great book. It covers pretty much every topic you could want to know about JRuby including some portions of today's talk on hacking. Or at least making data extensions. There's a URL, please buy it. It's not actually out in print form yet but you can get the electronic version now and then they'll mail you the print version. If you're actually in a hack in JRuby you actually need the source code. So we recommend getting it from GitHub. It's not our actual normative source for the source code. So it's like a half a second out of date. But it's better for you to actually clone from GitHub so that you can fork it and send it forward across this stuff like that. And all you need to actually build JRuby is Java. How many people are actually on Windows boxes here? So very few. You'll have to download Java. But for everyone who's on a Mac, Java is already on it. And if you install Xcode you'll get Ant. And if you're on Windows you'll have to download it again. But once you have those two you can just type Ant. You'll see a bunch of text churned by and you'll compile JRuby. Edit a file, change your line, type Ant and you just hack JRuby. So most people when they get started, probably 85% end up scratching their own itch. They'll go and file a bug on our bug system and then we want to fix it for a week and then they're like, I'll just fix it. And they do. So obviously if you file a bug it might be good motivation this afternoon for you to fix it. But when I started on the project I wasn't actually using JRuby for production. I just thought I'd teach myself Ruby by working with implementation. So I actually scoured bugs and just started trying to help based on the bugs I've reported. So that's the time when it started. And actually with our hope to have at least solid 1.9 support in 1.6 within about a month, that would be a great area to help out. So you can take a look at what specs we're passing, what bugs have been filed against 1.9. We've actually got a bug category for 1.9 bugs and that would be a great place for you to jump in and help us get it finished up. And don't have fear. Anytime you go and look at a new code base it's always a little scary but trust us after a day or two you'll love it. And Java is easy but we'll be talking about that a little bit. So I wanted to mention this. This is an announcement that just came out today. A lot of folks have asked us repeatedly, endlessly, about what we think the Java deprecation on macOS 10 is going to affect Java. Is this the end? Is it all over? Java is dying now finally? Well no, no. I think that's a little bit overstated. And in fact this announcement now, Apple has announced their intention to contribute to OpenJDK 7 for Java 7 to have it solid and work just as nice as the Java they have now on macOS. And they also said that Java SE 6 will continue to be in future releases at least through line. So it's not going anywhere and again you're not going to have to worry about having Java on mac. Alright, so the first thing a lot of people do to try and figure out something they want to work on if they want to just dive in or if they've got problems is using some of the various tools and tweaks and configs that we have in Java to investigate problems. And I wanted to start off by talking about some of the basic config flags. I'm not sure we've ever actually had these on a slide but useful stuff to have. So of course dash H will show you basically everything I have here. But one of the first ones that you might have to deal with as far as tuning JRuby is adjusting the maximum minimum size of the heap adjusting some of the JVM settings. Anything that you can pass to whatever JVM you're running on you can just append to a dash J flag and it'll actually pass it straight through to the JVM so you can make all the tuning adjustments that you need that way. There's also Java Ops which we'll pass on directly to the JVM as well. There's also some internal properties in JRuby that can tweak JIT settings that can tweak whether we're allowing native code to run, things of that nature. Dash H properties will show all those. I've got a couple examples on the next slide. And then there's a few JRuby runtime flags that are common enough. We've added special shortcuts like dash X minus C to turn off the JIT. It's a good way to investigate whether a compatibility problem might be a JIT related issue or an interpreter related issue. Then there's a few others. Dash X plus O will turn objects based on. It's normally off in JRuby or it doesn't have a full complement of features. And again, all of these can also be passed in through JRuby Ops as an environment variable. So as far as tweaking the execution of JRuby, of course there's the dash F19 flag and probably for the foreseeable future that would be the flag to turn on 19. If you want to run in 19 mode by default with JRuby 1.6, you can just put that in JRuby Ops and it would be set up and used it all the time. A few interesting properties. Sometimes there's an issue with the native library. Maybe it's causing something to crash. Maybe you want to see if it's... make sure it's going to run in a more strict environment that doesn't allow native code. You can turn native enabled to false. Some settings for JIT, depending on what your tuning characteristics for your application are, you'll be able to adjust that up and down, change the amount of calls that are required for a piece of code to compile into JRuby and byte code and so on. And of course, like I said, there's hundreds of JBM options that are also execution tuning. You could probably write an entire book just on hotspot and all of its flags. A few more just for logging and tracking information about what JRuby is doing internally. You can turn on various levels of JIT logging. The first one will actually show you what methods are being compiled. We're successfully compiled. The second will show you the methods that failed to compile. So if you have, say, a performance problem and perhaps the JIT's failing or perhaps the method isn't jittable by what we have in the current compiler, you'd be able to see that and then know that maybe your code needs to change or maybe something needs to be fixed in JRuby. You can also have JIT dumping turned on in 1.6, which every time it compiles a method, it'll actually dump out all of the JBM byte code for it and you can use that to investigate problems as well. There is also a dash-dash byte code flag, which takes whatever the immediate script or dash-e line is and shows you what it's going to be compiled to right before it executes. Okay, so the other half of finding problems is just taking advantage of the tools on the JBM. JBM's been around for 15 years and during that time the state of tools has just gotten better and better. As a result, the JBM has pretty much by far the best set of tools, depending on which implementation you're on, of any managed runtime that I know of. And we inherit all of that. So all of those tools work just fine with JRuby. Sometimes they're very Java-friendly, but they may not know specifics about Ruby, but they do an excellent job of profiling, memory monitoring, all the things that you really want to have for an application to remain stable and to be able to keep an eye on it. It all works great with JRuby. Profiling, debugging, memory inspections, of course, and lots of different options. So it's not even just one tool, there's dozens of options that all have their own special characteristics. One thing I want to show real quick before we get into the hacking and internals stuff is JVisualBM. We've shown this a little bit in the past, but it still seems to be a tool that people don't realize is actually there. If you have Hotspot or OpenJDK installed, it comes with VisualBM. Command is JVisualBM. It starts up a graphical console that will allow you to basically monitor any JVM process, including JRuby instances, for CPU, memory profiling, and so on. So you get a display kind of like this, and you can see what CPU is doing, monitor individual JVM processes, CPU usage. You'll also have the graph on it that says whether it's spending a lot of time in GC. You can monitor the state of the heap, how many objects are being created, when the garbage collection is firing. If you see a nice sawtoothing system like this, you probably have a good system. If it's continuing to go up, or the peaks always seem to get a little bit higher every time, probably some sort of memory that you need to worry about. There's also a possibility of heap dumps and browsing the object heap. I'll actually show this live in a second. Okay, here we go. So this is always more fun to show live. So I have a command I ran here, constructed a class foo, and then 10,000 times a pending foo into an array. I'm also passing a special flag here to JRuby that actually makes the foo class turn into a Java class right before construction, so that it'll show up in normal heap profiling and memory profiling tools. So now here is actually a live view of what objects are in the system. And of course, there's classes and strings. Pretty typical to see lots of those up on the top of the profile. Lots of character arrays with all the strings that are there. But you can actually see there's this Ruby.foo. This is the class that was generated in JVM bytecode for the foo class. And right over here we see we've got 100,000 of those instances. So you can use flags like this and any of the JVM tools to just dive right in and figure out what sort of objects are available, what might be leaking. And several of them actually go farther than this and show you where things are being allocated and do leak detection and say, okay, you've got a big box of objects sitting here. Maybe you don't tend that. So lots of great tools. And JVM is probably the first one that I go to as far as doing some memory inspection or some amount of profiling too. We've got a built-in profiler. The other, the Java options sometimes are a little cumbersome to work with and we know a lot of people who wish to work on a command line. So JRuby155 plus also has a dash-dash profile flag that is Ruby specific. So you get some output like this. Here's running the Richard's Benchmark and you can see the schedule method is up on top taking up the most time and it goes on down from there with the other Ruby options. So both the nice graphical fancy GUI tools and a lot of command line tools that are available from us and from the JVM. And like I mentioned there's also a lot of other pretty tools. JARKit's probably one of the nicer commercial profiling setups. JInsight is a commercial profiler that actually has JRuby specifics in it so it can track objects and Ruby method calls along with the Java stuff. But Clip's memory analyzer is my go-to tool for investigating leaks. And that's actually a free one that you can download and give it a heap dump and it'll tell you where leaks are and it'll let you walk through the objects and make them much easier to investigate memory issues. All right, so on to extending JRuby, the interesting stuff. So there's really two ways that we recommend that people do this. The first one is generally just write Ruby code. You can call any Java library and pretty much just pretend like it's Ruby. And JRuby's core is actually 100% introspectable as well. So if you want to investigate problems from IRB and poke around JRuby's internals, that's possible too. I'll show an example of that in a moment. The other way would be to write Java and we'll talk a little bit about what the actual structure of Java extensions are, how they fit into the system and how you can start writing them today. So Java integration, there's really only a few key things requiring Java, you can pull in some extra jar which could be an arbitrary Java library, import the classes and then pretend it's Ruby. It ought to work and feel just like it's Ruby for almost every case. If it doesn't, there's something that we're doing wrong. So you can use any libraries that are out there and a quick example of this is actually kind of from Yoko's talk yesterday. We've shown lots of Java integration examples and there's plenty online so I just wanted to show a couple quick ones. Here we're actually taking JRuby's scripting container which is our embedding API if you're going to call into JRuby from Java and importing it into JRuby and then calling it to start another JRuby instance. So you can do things like this, actually spin up JRuby instances within JRuby instances and do it all entirely from Ruby. Now the wilder stuff is when you're pulling the JRuby library or require JRuby you can see here we've got a string which the class is string, it's got 80-some methods but if you use this JRuby.reference what it actually does is take that Ruby string which looks like a normal Ruby string and says here's what the Java view of that object is. All the Java methods are there. You can see those 982 methods on here. Some of those are aliases of others but basically everything that's defined on our Ruby string class in Java is now accessible and you can start poking around the internals of JRuby itself. Now a more entertaining example is the dreaded object become. Here actually implemented entirely in Ruby because we can go into the internals of JRuby from Ruby code and start tweaking things. So here I'm adding a become that changes the metaclass, changes the metaclass for a particular object. So we have class foo, we have a class bar and we actually change foo into a bar. All from Ruby. It's so wrong. But it shows you that you can't actually get at this stuff and JRuby is probably the most introspectable of any of the Ruby implementations simply because everything is just a Java object at some level and it's all available from Ruby code very easily. So the parallels and pitfalls of doing Java integration based extensions. There is some overhead when you call Ruby into Java and when objects come back from Java into Ruby. String is an especially difficult case because Java strings are all UTF-16 character arrays. We have to convert Ruby strings up into UTF-16. When they come back to Ruby we convert them back down into UTF-8 or whatever your current encoding is. So that can be a problem. You can avoid some of that by precaching the coerced strings but it'll eventually start to bite you. You're doing a lot of strings and a lot of fine-grained calls across that boundary. There is also overhead just from the fact that we're wrapping other objects. Every Java object that comes into Ruby needs to get wrapped with a little pseudo-Ruby object wrapper and those wrapper objects since we want to be able to do instance variables and singletonizing of Java objects, etc. those actually are held in a separate weak structure. So that can end up adding extra overhead just because we want to maintain the identity of the objects. There's, of course, overhead from using reflection. JRuby primarily uses Java's reflection APIs to call into Java from Ruby. That adds a little bit of overhead as well. And, of course, there's always little dusty, unoptimized corners of JRuby. We've improved release on release lots and lots of Java integration stuff in the performance of calling from Ruby to Java but it's still always a little bit of work to be done. We want to use Java to do extension. Is this where you take an hour or what? No, this is like in order of it. Oh, right. Okay, so now, after you play around with doing it from Ruby, you may want to actually get some of the performance typing whatever guarantees of writing in Java. And why would you want to do this? Or at least, why would you rather do this in Java than in C? And when you look at it, really, Java is a much closer fit to implementing Ruby than C is. It's not GC, so you're not doing memory management, you're not doing pointer logic. It's single inheritance language. It's VM based. We have SecFault in the JVM and we can do that. What causes those SecFaults? It's when we call out to C. It's always the C thing because of rolling up stuff. So writing in Java is going to be a much cleaner experience, at the very least, for hacking on JRuby. So can we get our hands raised for how many people know Java? Sweet. So this is going to be more like 30 second ads then. Okay. So we want to do a little like Java thing, not really teaching the language, but teaching the structure more. So like I said, it's single inheritance language. Object is at the top of the hierarchy, just like in Ruby. There are primitives also, so it's not quite a pure object or any language. But largely this is done for performance reasons. You want to be able to guarantee that you're going to have primitive level performance than having everything be an object or any of the JVM's going to be. It will optimize it for you. So you've got signatures for all methods. You just provide the return type, argument names and argument types. And that varies from language to language, but generally in Java that's what you do. You can have multiple methods of the same names. You've got overloading. You use interfaces for multiple inheritance. So rather than object multiple inheritance, you have interface multiple inheritance. Interfaces are basically just a bag of the method signatures and they're largely cleaner to depend on interface types than they depend on the concrete type. So you can swap out where the implementation is underneath. The compile phase results all the types ahead of time. So classes are closed, but the JVM is totally amenable to loading additional code at runtime, which lets you get around some of that staticness. And of course object casting is one of the runtime type operations. Actually type checked at runtime. Jolli is not Ruby, and we recognize that it's not as nice of a target as Ruby might be, but it's a hell of a lot closer to Ruby than C is. So it's really not that bad to use Java to extend JRuby or to hack on JRuby in turn. Okay? Oh yeah, explain that. Okay, so we're going to talk a little bit about simple Java extension. It's called weakling. It's a gem that's out there. You can gem install weakling or go to mycountpedius on GitHub and find a weakling project. It's kind of a nice simple example of a weakling extension in job. Weakling is a weak reference library. Weak reference is an object reference that does not prevent that object from being collected. So you can use it for weak collections or for lazy operations like that. What this adds over Ruby's weak rep is a reference queue. A reference queue is basically a VM structure you create and you pass it in when you create your weak rep, and whenever that object gets collected and the weak rep gets pushed onto this queue, and then every time you... So if you want to do a weak collection, you can say, okay, whenever the objects in this weak collection disappear, put it in the queue, then I'll clean up the collection and get those empty weak reps out of there. It's much more difficult to implement weak collections without something like a reference queue. It's something that really is missing in regular Ruby. And there are some people that are going to implement this for CRuby as well. So now, why did I do this? Well, first of all, I wanted to add this issue with ID2ref. ID2ref is an internal function in object space that has turned into an external API a lot of people use. ID2ref basically takes the object IB and gives you the object reference that goes along with that. Unfortunately, it is entirely broken for using four weak rep implementations because that ID is essentially just a pointer location and since Ruby tries to reuse the same locations in memory, there is a potential that for some amount of if you don't catch it at the right time that ID may not just point to, not point to the old object it may point to a new one that was put in its place and now you've actually got a completely different object with that address than you expected to have. So ID2ref is not something anybody should ever be using, okay? That's my rule number one about memory and objects and IDs and Ruby don't use ID2ref. Memorized weak rep also uses Delegate which is at least in 1.8 a terribly slow library in 1.9 it's improved somewhat and we have a modified version of it that's improved too and collections like I say are very hard without reference queues so we needed to add that. Java provides native stuff for this also. There's no reason that we need to use the sort of hacky version of weak reps that's in standard C Ruby when we have solid VM level weak reps and reference queues and so we just wrap that and went from there. So now again, why Java? We wanted to avoid the additional Ruby Java integration overhead. We wanted to just be at the Java level and have clear performance guarantees about how it's going to run. Avoid reflection and have it feel a lot faster so it could be as solid as possible when you're using it for something like a weak collection. All right. So this is the first Java code that we've seen so far in the talk. It's responsible for bootstrapping the Weepin library. It just needs to implement one interface to do that. We'll walk through the actual loading sequence though. When you actually call require weakling keep on saying weak rep it ends up growing down to load service require which is a Java method. The interior load service require uses a heuristic to go and discover this particular class in a jar. It's a little out of scope today to explain it but it's a pretty simple heuristic and then it executes basic load. Now basic load has to go in bootstrap the actual library and you can see that it's constructing an instance of RefQ library and it's calling load on it. If it's able to load it, it returns true if it can, it returns false. That makes sense, right? I think it horribly went wrong and it will throw an exception. So let's burrow down into the RefQ library class. The first thing we'll look at is load because that's where all the bootstrapping is really happening. The first thing you'll notice is all references to runtime and rev. This is a class or JRuby Ruby. It's our main context class for an individual Ruby runtime. We can actually run multiple Ruby instances in a single JVM. In fact, this is how we implement listeners in Rails when we're not in thread save mode. And of course, we run multiple Rails apps in the same JVM. It's really not a very difficult thing. JRuby is just another object in the JVM. And like a typical context object it basically holds a hard reference to anything that actually matters. The class hierarchy and by extension all the live objects in the system. In, out, air, streams, finalizers, everything pretty much. But the reason as someone who hacks on JRuby you're going to see this class a lot is because we have a billion methods on it for retrieving and creating objects. So if you want to get a reference to nil just call runtime getting nil. You want to create a new fixed num call new fixed num and if it's been cached it'll return a cached copy. But there's lots of useful methods on JRuby the class versus the language. So if we actually look at the load method now the first thing we do is we require weak rep. This is so that we can get access to the rep error class in weak rep so it tries to go and be compatible with weak rep in such a way that you can swap this out and your calling code still basically would be the same. This library was written to work with existing versions of JRuby at the time which meant that we wanted this to load as an extension but still fit into the same API the same structure of the standard Ruby weak rep library. So it pulls in that weak rep library and essentially just replaces some of the classes. Next we go and ask the runtime to have a weak rep module. In this case it's a new module so it constructs that new module by the name weakling. To get out of here next we define a class called weak rep whose super class is object it has a weak rep allocator which I'll talk about in just a minute and it's defined underneath the weakling module so weakling rep queue is more the same. So if we actually look at the weak rep class the first thing you'll see is oh weak rep extends Ruby object and so you'd naturally think that that was that relationship in Ruby as well but it's not quite true from two slides ago we showed this defined class under method this is where all the Ruby relationships are happening we have a set of methods for establishing every Ruby relationship you have as Java methods but we actually have weak rep extend Ruby object as a Java implementation convenience so now if weak rep wants to actually do dynamic dispatch Ruby object implements a call method method but now it has access to all those methods and that additional state it's just an implementation convenience it's kind of one of the more confusing aspects when you start hacking on J Ruby is the fact that there are these two hierarchies you can think of the Ruby hierarchy as the dynamic dispatch hierarchy and the Java hierarchy has the static dispatch hierarchy and then we need to put those two together and we get Ruby objects and Ruby's structure and if you're confused everyone gets confused by this for the first couple days so one line I didn't mention in the log method was for weak rep we called define annotated methods and then passed in a reference to a class what this does is it scours the class for at J Ruby method annotations which specify all the Ruby methods that are defined in this weak rep object for type and then this is how we actually bind the Ruby name to Java type signatures so if you've ever done a C extension or a knit method when it goes and creates the classes and then you see define this method pointing at this function find that method and so on we don't have those calls we just have this nice syntax for saying this Java method bind it so it can be seen from Ruby the arguments that you pass are important if you see weak things initialize method on weak rep an object and accepts an optional few argument if you actually look at the initialize method in Java we actually specify primitive array of args so we elected to go and receive the arguments figure out if we have the right and set up the right default value about allocation remember back in load we specified that there's a weak rep allocator there's a Java code in its entirety let's just walk through the allocation sequence so when you actually call a weak rep that new that in turn calls allocate allocate then goes and asks for what the allocator is and there it is so it executes the allocate method which then constructs a new instance of the Java weak rep class and if we actually look at that constructor it's actually not doing a lot on the superclass's constructor but it also has a rep field so it is actually initializing the rep field to null so it's setting up internal states so you could, if you had another class you could see that you could initialize values and actually if you look into Ruby object or Ruby basic object you'll see that eventually this class that's passed in gets set into a meta class field into the object so largely for internal state that doesn't come in from initialize so it's a fun journey start up at Ruby class and just find the constructors all the way down it's a real best trap so this is actually the initializing method that would be seen from Ruby so after allocation happens then new calls initialize which then executes this code that rep field that I said was nulled out now gets replaced with reference type where the first argument passed in is actually the object that you want to have a weak wrap to and we return to L because that's what you're supposed to do with initialize so in fact if you check out weakling search code you'll see that we didn't actually use a primitive array of arguments we actually have it split out as two separate Java signatures so this is actually quite convenient by virtue of actually having two different initialize methods in Java now if you go and call weakwrap.new with one argument obviously it calls the first one call it two it calls the second one but what's even better is if you call it a zero or a four it just throws the appropriate error so we now have been able to get rid of this extra arity checking from our code and more importantly we're no longer boxing arguments so we're not creating a primitive array and then populating that array every time we make the call so things actually run a little bit faster this is actually some of the nice magic that we get from using these annotations to bind all the methods at binding time it goes and inspects the signature of each of those and says oh are they going to thread context passed in do they want to receive a block do they have one argument, two arguments variable arguments and then it just makes it all and the effect of this is that when you write in Java write the Java extension it actually doesn't even have to do any arity checking so you go straight through if you're passing two arguments it knows straight in it takes two arguments goes all the way there it makes things that end up running a little bit faster than having to do an extra Boolean check to see whether you've got the right number of arguments or not there's a few additional things you can do Charlie's talking about that auto wiring sometimes it's convenient to actually have another internal classical thread context this gives you access to things like the call stack or backtrace information and stuff like that in this case we're actually using it for get run time but for any bound jruby method you can just put this as the first argument we just magically hook it up and provide you the thread context likewise if you have a signature that might require a block you can just add a block variable at the very end and it will just pass the right thing to it so the auto wiring of jruby method really cleaned up our code a lot actually one thing you'll notice here we're calling block is given without doing any null checking or anything jruby for blocks uses a null object to have it so if it is not a block that was passed in from the user or if no block was passed in this will just return false it'll be the null block that we pass around no block argument being that's passed into your method can never be null you know if we have an insert in the actual populator code to throw it if we're manually calling the method without a block but if it calls from ruby and you pass it with no block you're guaranteed it will be an object of some kind so we just talked about bootstrapping on the code and how methods are bound let's actually look at some code inside the method here's the get method we just talked about that so you'll ask the Java weak reference to get an object and that object will get returned if it's been collected then it'll actually just return null and if it does return null we'll throw an exception otherwise we return the object so this is pretty easy to understand but it doesn't actually do anything with types it doesn't do any coercion another quick note on the annotation there you notice that the name is get and the Java method is named get as well if the name of the Java method is going to be the one you want to bind into ruby you can omit that but if it's a ruby method name like with a question mark or a bang that doesn't fit ruby you can add that into the name argument for the annotation itself we graph the lives in an example of that by the way the question mark is not a valid identifier character in Java so we put this underscore p for a predicate and then it pulls the question mark I don't like transitions okay I could have went forward on slide how funny is that okay if you want to go and create new instances I mentioned this before but there's a method for every single core type on that class so you want to create a boolean new boolean it's as easy as that type coercion methods and most of them are named the exact same thing as an MRI so if you have to see implementation numbed along you'll look very familiar to you and it obviously behaves exactly the same we also have a bunch of convenience mechanisms on ruby object itself that allows you to ask it to convert to integer and then it'll actually do a dynamic dispatch to two int if you actually want to do dynamic dispatch we have a whole series of called method overloads the top one is a no R version where we're just calling two foo but if you actually have arguments you can just add those arguments on to the end of that chain and we you have it up to an area of 5 but I think it's all so far you can pass any number of arguments into that it'll pass as long and if you have to call something with a block you can just pass a block to the last parameter lastly you can always just evaluate ruby code itself by calling it val-scriplet on runtime and it'll return what you expect alright so we're almost done here now we understand that Java is not necessarily the greatest language to implement a lot of this stuff in and that's one of the reasons that I came up with Mira Mira is essentially a language that it uses ruby syntax that looks and tastes like ruby but it's just a syntax for writing Java code a little bit nicer syntax and cleaner and as a result you can write something that looks like ruby and have some of the benefits of writing ruby but you get bare metal performance guarantees like writing Java and kind of think that this might be the future of Java extensions that we might expect more and more people to use Mira to write these extensions rather than writing them in plain old Java so I'll show you a quick example of what that looks like here's our editor redcard ok so which is written in jruby as well by the way so here we have the same thing what implemented in Mira now Mira doesn't quite support this annotation syntax yet but this is essentially what it will be very shortly here we have the initialize method we have our get method we have the initialize down so initialize is actually used both for the constructor here the regular initialize but you can see that this actually ends up looking and feeling a whole lot more like ruby the structure of things is much simpler you only ever have to declare the argument types the rest of it is going to all be figured out here we've got a field turns into a regular Java field and again it just infers the type from what you're assigning to it almost done and again week ref alive and so on a nicer way probably in the future we think most people will be doing for jruby extensions especially if you've got a preference for ruby syntax and some of the nice features of ruby so that's about it timed out pretty well so there's a twitter account for all of us you can also find our emails pretty easily online send us an email jury.org there's my blog I blog fairly often we've also got links from jury.org to the other developer blogs we have the book of course and let us know what you think and I guess we have some time for questions so who wants to go first one way in the back use other java libraries pull in other java libraries and call them is that based with? yeah absolutely mira essentially is just like a replacement for java c it's just a language that compiles essentially into java so you import java classes you have all the same capabilities to call into java absolutely normal and it actually turns into just normal java code and in fact the mira compiler has a java flag that outputs java source instead of jv and bytecode so it's essentially just a syntax maybe a source to source or a source to bytecode translator that takes ruby syntax and makes java code happen so it's not ruby but it's a much nicer way to write java we were saying this yesterday on mira is sort of the copy script of java that's a good help yes here the java source does require jruby the jruby the mira compiler is written in ruby it's about 10,000 lines of ruby code so if you want to hack on mira please do mira.org so it actually requires jruby at that point but the resulting class files have absolutely no external dependencies other than what you wanted with libraries you pulled in and that's again trying to be a one-to-one replacement for java-c source goes in class files go out you walk away with the class files and you're done with your dependencies at that point yeah the reify class is optional whether we can leave it on all the time ideally we're going to do some testing with this but ideally in one six hopefully that will be on all the time and so all ruby objects that you construct will just have a java equivalent and show up normally in the heap if that doesn't work because of code loading, class loading issues, collisions and what not we may just leave it as a flag that you can turn on but it most likely it will be safe I've run it with rails and jams and other stuff it seems like it's pretty safe for most libraries and most applications but it remains to be seen whether we'll have it on by default in one six what have we done 11, 10 I think so so I think that's about it you can grab us afterwards and we'll probably hang out in the hall for a little bit thanks very much