 Thanks very much for coming. Hope you have a great day at RubyCon so far. My name's Nick. I'm talking about Warbler today. And the whole idea behind Warbler, for those of you who are not very familiar with the concept, is what I'm going to do with it is really bring a new audience to the world of Ruby. So allow those of you who are developing applications new possibilities for a way to build those applications and how to deploy them. And bring those applications to new people and new places and new environments. So, you know, I didn't take your applications to new places. And make it easy in the process. So, in a little bit I'll get into what that really means. I will say with some caveats that if you're the kind of person who likes to have high control of their applications or if you're developing a web application, you control the servers, maybe you're a fan of the DevOps sort of mode where you have all the maps, your disposal, you control your servers, you know what goes on them, you know how they're configured. And you don't have to throw, you don't have to work with anyone else. You don't have to throw your work over the wall. Someone else, you just content with me on your own, deploying your servers, and then maintain them under your own control. But I'll probably say with pretty certainty that Warbler is not going to be for you. So Warbler is really about taking your applications, packaging them up into a unit that allows you to take them somewhere else and run them as easily as possible with the minimum amount of dependency and hassle on the other side. And so how we do this is we take advantage of the ubiquity of the Java virtual machine and its ability to be cross-platform. Now you say, well, okay, Java virtual machine, that's a pretty big dependency. And I'll give you that. And you'll say it also might feel like a little bit heavyweight and you can't always rely on it. And what about the cross-platform part of the JDM? What about right once run anywhere? Wasn't right once run everywhere supposed to be right once debug everywhere? Well, that may be the case. I've actually found it my experience as a Java developer for ten years that I can pretty faithfully write code on one operating system and deploy it into a Java virtual machine running on a different operating system and expect programs with these round and pretty similar characteristics. Maybe not performance characteristics, that's of course a different story, but operating characteristics and behaviors certainly are very consistent across platforms. So this makes a great, great option. And I'll just contrast this to the Ruby option where if you really want to try to do cross-platform Ruby, you're really talking about installing a C-compact on every machine where you want to use Ruby. And to me, that just kind of feels like repaving a row at every time you want to go somewhere. So, you know, the Ruby is great when you have control over the environment and you can afford to have a C-compiler running on your production systems. But if you don't want that, then the JVN and Warbler could be for you. So let's run through a few possible uses that you might consider using Warbler for. The first one was sort of the original reason that I wrote it. And that's if you want to write a portable web application. So you have a Rails application. You run Warbler against your application and it creates what in Java problems is called a Warpile, which basically is a file with a bunch of, with all of your application files in it. I'll show you a little bit more about the structure of that later. And Java has this Warpile standard that most Java applications that are containers can accept a Warpile and you just put it in, you tell the server where this file is and it opens it up and sets up all the files and boosts the application for you. And this is pretty standard across most Java servers. So it's actually a really nice thing. There are a lot of enterprise organizations that run them strictly by having their development or QA or release management team build a Warpile and that Warpile gets handed off to the operations team where they actually maintain and run the application. So that's actually a pretty standard operating model outside of the DevOps space that a lot of you might be used to. Another area is you can do cross platform rubies really easily. Again, I'm taking advantage of Java in this case. The swinging UI toolkit that's actually built into the JDK works reasonably well for a lot of kinds of things. The knocks against the swing are that it doesn't look as native to the platform as you'd like in that many of the case, but if you're looking for ubiquity and cross platform, you're probably not as concerned about the look and feel of a particular platform. If you were, you probably take the time necessary to investigate native GUI applications for that platform. But with really good ease, you can write a few tens of lines of JDK and boot up the UI really quickly. Just about anywhere where there's a Java virtual machine and Warpile will allow you to create a self-contained Java that you can use anywhere that's JDK. Another option that Warpile can help you with is distributing your application without source code. This is actually a pretty novel one I think in the Ruby community. There have been maybe a couple of attempts on Warpile to create a source code application mechanism. JDRuby actually comes with one built in that works pretty well. I can show it off to you later in a demo. What happens is we can compile a Ruby file, RubyScript, down to a Java class file, and we'll put the Java class files in the application archive instead of your Ruby scripts. And then your scripts get out of the archive and you don't have to ship them and the application will still work. And the reason why that works is because the class files that get generated by JDRuby are fairly opaque in the way that they translate to bytecode. And so even though some of you are familiar with Java, say, well, you have a Java class file, you can also decompile that to Java source, right? Well, that may be true, but as I can show you later if you're interested, decompiling a Ruby script compiled by JDRuby into a class file back to Java gives you very little resemblance to the original script. So as I hinted before with the web application example, if you don't have much control over your deployment environment, this is really going to be an ideal situation for you because when you're doing this, what you probably want to do is actually simplify deployment so that the person that you're telling to actually deploy the app has as few instructions as possible. So generating a war file in time to put it booted in a Java application server, handing them a Java file and say, run this, you know, run this Java file into a Java virtual machine, you know, minimize the number of steps that it takes to get them running, don't make them install this gem and that gem and run this build stuff, make it as quick as possible. And that's really what the world is about here as well. Another option which happens to come along with JRuby sort of for free is that we actually do have a good window support as well. Both by virtue of the JDM, there's cross-platform window support and work that we've actually done ourselves to provide a good operating environment for Windows. We still do have glitches down then. We even have show-stopper bugs that promise to release a second point release on the same day like we just had the other day with JRuby 155. Those things happen, but we are committed to the Windows platform and we think that JRuby is a great option for developing and running Ruby applications in Windows environment. So the reason this all got started is sort of because of a square peg round hole and a problem. We wanted to... It seemed natural working in a Java environment but we wanted to take a Rails application and build it into a war file which is what the Java application servers take. And so we started to think about how that actually works. And if you look at a Rails application directory structure, you don't need to worry about reading the labels, you probably recognize the structure just by visual contours going. You look at a Rails application structure and one of the things that sticks out with Rails is you run your application in a directory and all the code in your application sits below the directory and a bunch of different folders in the directory. Except for one special directory and of course that's public where all of your static assets live. Now when you flip that out around to the war file side, you usually have a war file like this where you have all of your static assets sitting in the top level of the archive file. And instead inside the war file there's a name that I can mention called WebINF that Java war files use and this is where your application code lives and part of the standard specification for war files is that Java application servers should never serve any content out of that directory. So if you have code living there, you can be sure that you're not leaking your code out to the outside world. And obviously if you're going to put your code in an archive you need to have some kind of structure like this. And so you have this sort of structure to work. And so after a little bit of deliberation and playing around with this, I kind of came up with this sort of structure here where we're basically swapping different parts of the application around from the directory structure over to the war file. And what you see here with the green boxes is the application code of course goes into that special WebINF directory I was talking about. And your static assets, images, JavaScripts and style sheets originally when I started working on this back in the late Rails one early Rails two days this was a little bit more problematic because Rails had this hard coded notion of where your static assets should be. You know I said Rails root slash public, well that's where it is. Well there's no public directory in any of this structure over here. So over time I had to kind of submit patches to Rails to kind of distract that heck out of the way. I think that we're pretty well set with this structure I can tell Rails up front the public directory is actually up here and the application code is here and more or less works. So I'll show a little bit more about the Web stuff later when I get into demos. So if you want to get started it's really simple where was it to jump and install it in a normal fashion and then it gives you a war file command and you will go inside of your project and run that and it creates a war file for you. That's it. Done. Go home. Of course there's more to it than that I'll get to that. I want to point out too that you can actually run more of it from C Ruby I actually do have it on my roadmap to test it with Ruby 1.9 You can run it with C Ruby it's not preferred because if you're doing any more extensive Ruby development with J Ruby you're probably going to run across a J Ruby specific gem and it's going to be difficult to trick Warbler into clicking the right gem to put in your application when you're running it with a different Ruby. So for now if you're doing bigger applications obviously it's Warbler from within J Ruby if you want to play around with it and just do small scripts you can certainly run it with C Ruby just fine. So how does Warbler find out what to put in your files? Of course the first mechanism you can use is Butler you can detect the gem file in your project and boot up Butler and tell it to iterate all the dependencies in the project you can make sure those gems get copied into the archive So for this works great for Rails 3 projects or other projects where you start using Butler for older projects that don't use Butler there is a way around that I'll talk about that in a second if you're doing a regular and non-web style project where it's just going to be a jar file with some Ruby code standard Ruby application structure where you have some executable in the bin directory and you have some report paths and some files and you may have some dependencies as well and basically if you have a .gemspec file in your current directory we'll load that up get all of this information out there and use that to build the application So if your application doesn't fall into either you can still try Warbler and maybe it'll work better it doesn't always get it right but if it doesn't we have a configuration mechanism so you run this config config command which gives you a nice Warbler template and if you open that and look it up it's just a regular Ruby code much like you see in Rails lots of other places where you have configuration using some sort of a config object and this file is actually relatively big all the options available to you are fully documented in the comments for that file you can of course delete whatever you don't need but that's a good place to start and you can do pretty much everything you need within this file if you need to go beyond the defaults for what the Warbler could do Another application of Warbler that's interesting is to embed it in a rank file so rather than using the standalone Warbler command you can actually just integrate Warbler as part of your rank code process and Warbler was originally architected so this is actually really easy to do I just have a Warbler task class and you can create an instance of that somewhere in your rank file and it will define some tasks and you can actually take this a little bit further if you want to build in multiple different configurations inside the same build you can actually declare multiple Warbler tasks and just give them different names give them different config objects and then pass in the parameters that you see there I want to go into just a little bit about the internals of Warbler and how it's kind of evolved up for us today the new release that's coming out soon has a structure that's sort of like this you just saw the task object in code and there's also the config object you saw an example of that there's also a class called jar which is as you would expect and jar is actually pretty easy to just use standalone as a nice little wrapper around the zip APIs you can just create a jar like this and jar has a file's attribute it's actually a hash of all the entries inside of the archive and so the keys to the hash are the paths inside the archive and the values can be a couple different things they can be nil which means just create a directory entry for that label for that key it can be an IO object for example a string object you could use or you could just give it a string which represents a file name and that file name can be absolute and point to somewhere else that doesn't have to be even living in your current project and actually take advantage of this inside Warbler that packages gems so when you run Warbel and it starts looking for gems to include in the archive it will just pick up all the files from the gems right out of your gem directory without having to copy them anywhere so that works pretty nice so create gives you that jar file and if you look at the contents of that jar you see the entries that were put in there as a result you see the script actually created three entries but there's actually four here whenever you create an entry with multiple slash separated paths and consider those directors as well and make insurers that there are directory entries all along the way so I'm going to jump back here so going back to the structure or intro structure of Warbler a new feature that I built for the new release is this concept of traits and I did this to sort of separate out the logic between web applications versus regular applications and also to split up the logic amongst the different kinds of things that you might find in your project that would figure Warbler and tell how to build what it builds so you see along the right side of the screen here Warbler, Jar, Bundler, gem spec, Rails, Rack so it will look inside of your project and look for things like the presence of a config environment RV file or a config.ru file or a gem file or a gem spec file and it will automatically add these traits into your configuration and apply them in the building of the file so another thing that came in a recent version of Warbler is something I'm calling features which is sort of a way to tag on extra behavior that kind of processes the work file the contents of the work file mutates it before it actually creates the archive and so you see here the command Warbler executable compiled or is actually a valid Warbler command and what it does is it creates a work file that is executable means I'll show you what that means in a minute and compiled means it does what I told you about before we're out of this case the scripts by combining the class files and only putting the class files into the archive for you and so this idea of features is a way to say well you know here's a common pattern of transforming certain aspects of the files and we want to do that repeatedly and level it up into an extra task that can be used and then it also gives you a nice command line for saying Warbler will create me a compiled Warbler as opposed to a plain Warbler and depending on how people start to use this as word gets out more about this I'm hoping that this can kind of turn into a type of plugin system that we can maybe discover other people's features and you can pull those in and use those as part of the Warbuilding process or the Jarbuilding process so I actually have a big slate of demos here and I still got quite a bit of time but I think I'm probably using most of it up doing demos this is really where they're already thrown and I'll show you kind of what's happening inside of Warbler so the first thing I want to do is do some connectivity and since the Wi-Fi is so bad here I actually brought a little Airport Express with me and it's plugged in down here below the desk so you should be able to find it's just an Airport Express so it probably has a lot of connections involved in the room but if a few of you want to try to connect up look for this SSID and your wireless networks connectivity you can download this jar file that I've rebuilt for the purposes of this demo and that may take a couple minutes but I'm going to do a different demo first so I'll get back to this demo in a minute so what I have here is I have a copy of RedMine from a relatively recent revision of GitHub and RedMine unfortunately out of the box does not wargle cleanly, does not pick up all things you need so you could either set up a config file which should be really easy to do but instead in this case you have RedMine and you simply have one revision which introduced a bundler gem file for this RedMine application so we can actually look at that so this is the gem file that I created for RedMine which is actually pretty straightforward so what I can do is I can say wargle I can just run the wargle by itself and that will give me a warp file in a few seconds some errors here with some extra artifacts inside RedMine that I haven't bothered to look into but it's actually not fatal so you can ignore those so that's creating a warp file and that's it so if you look at RedMine.war it's actually a little bit beefy it's about 18 or 19 megs and this is because we're bundling all the dependencies in including JRuby itself so inside this warp file you can see there's a fair number of jars in here there's some jars for the Jwbc gem jars for bouncing castle there's a MySQL Jwbc driver in here as well as the JRuby core libraries themselves and all that gets put in either by detecting the gems that the project needs or just by virtue of that we need to include JRuby in there to make it completely standalone so another interesting thing we can do instead of just creating the warp files is to show you executable war and now what we've done with executable war is we're embedding a little Java web server inside the warp file and we can actually start it so I can say just to show you that I'm not picking up any files out of the RedMine application I'll just copy that warp file to slash TMP I'll just slide this video over there and turn off RBM so that I'm not picking up the gems that are installed for RedMine and I'll just simply run Java minus jar RedMine.war so it says it's running and we go to Winstone as your app server Winstone, yeah I'll talk about that in a minute I chose Winstone initially because I stole the idea for this technique from the Hudson Continuous Integration so it has a similar thing where it'll embed Winstone inside the Hudson War file so you can run it in this manner and so I just went with that I'm not minimally intrusive and it was easier to get embedded quickly because it has a command line for that already but I'm looking at some other servers in the future so in C, RedMine is running I have this instance of RedMine for you to talk to my SQL as you know because it's a driver and I've already got a database running there I can actually see some of the data coming out of the database here and so what would you do with this sort of thing well this is kind of nice you have a web application and a single warp file you could create a small one maybe you want to push it out to a bunch of desktops and right there you could embed the you could embed the database location, you can pass it already in the warp file as well and if you're not too concerned about security maybe you have some sort of an internal maybe you want to build an internal web app that Git can use to talk to a database but you don't you don't want to have a central place to deploy for whatever reason maybe I'm being a little bit a little bit too too hand wavy with the use case here but I think you get the idea you can take this file and give it to anyone else in your company whether Java or Virtual Machine is built and they can give it to RedMine running on that machine for the whole so that's RedMine next demo ok so now we're getting to the piano demo so what I have is has anybody been able to download the piano dropout did you actually start it did it pop up ok yeah of course ok cool so let me just just to show you that there's no Java in this project run that man no Java anywhere in here um I can run Warbill in here edit it in oops this is sorry not the right direction so here's my ring piano project you can see there's a gem spec file there they're creating a ring piano jar and again it's a little bit big I mean most of that 8 plus meg bulk is just the JRV jars that are embedded in there um so we can start this up um a lot of in a lot of places I think both on Windows and Mac you can actually double click a jar file and it will just launch itself you can also run it on the command line like this Java minus jar jar file just like I did with RedMine needs MIDI oh yeah it does need MIDI alright so you can see here I actually have a couple windows and before the talk I was able to give my friend Jay won't be able to get this going as well and you can see we've actually got a couple different people hooked up here so um what this little ring the reason why this application is called ring piano is because it's actually using Rinda and it's creating a Rinda ring server on a local network on my little airport and in the ring server we register a tuple space which is going to be a tuple space to hold notes on the piano and so this when you press buttons on this little interface it will put the note on your quest note on note off your quest into the tuple space and then elsewhere there will be a process or a thread that's trying to pull those note on note off commands out of tuple space and use them so Jay you want to go ahead and click a couple things and I can play very nice to this side too I should probably unplug the volume because it's a little bit of a tongue the volume of my computer is overwhelming Jay's we're both playing notes and then we're both we're both hitting keys and then we're also playing notes on each other's computer it's kind of getting bouncing back and forth through the tuple space so um you know if we had a better network and a better UDP broadcast kind of heartbeat signaling to get a whole bunch of computers in the room hooked up and we'll be playing music together and the point of this is that um you know fell over there and Jay as well simply downloaded a pre-built version of this jar file off of my computer like I showed you there before there were no other um dependencies, no other stuff to take other than to download that jar file just one of these so that's sort of demonstrating the cross-platform UI aspect so we can actually I'll just take this opportunity to show you the compiled stuff now so this will do the compilation and if we look at this now so you can see here is the here's the actual layout of the jar file you can see the jre libraries are embedded up here um there's actually I actually put a special file in the jar file called main.rb that just says to load up the executable within directory and then of course that's here and then here's where the actual application code lives um and now if we go down here we see um we've got some rd files in here but actually go in and look at those they don't have any actual code in them they just say load the class file instead and jre we can do that jre can actually load a class file as described instead of a rd file so now if we actually decompile one of these class files um this is what the resulting java code actually looks like so as you kind of scroll down here you can see a whole bunch of godly code here so you can actually decompile anything that just has like raw jbm instructions dumped out here um so you do see some things like you know you'll see method names for example but uh very little else to give you any indication of what was actually going on in the original script so as I was doing this I found that I could actually run run warbler and warbler itself into a jar file so I actually made a task for that in warbler's rig file but I can actually create use warbler to create a jar file itself I'll just copy so now I see I have a warbler jar here so I can actually say java minus jar warbler blah blah blah um and actually run warbler itself out of a jar file to then create a ring piano jar file recursion for the wind for the wind and then the thing about the samoura well you know what else can we do we can actually use a lot of make a lot of other movie utilities into executable jar files successfully done this for rake rake works fine actually you can do this for rails as well so what I did is uh if you look at the actual rails gem I thought it doesn't have very much in it right it just had this this uh the rails script in a vindor 3d and a gem spec file so if I run a warbler here this will actually create a rails 300 oops okay well let's see if I can actually there's one more demo I can do here I'm not sure why the rails almost isn't working but I was able to do the same thing with rails and actually bundled rails up into a jar file it's not actually that interesting because then basically all you can do with that rails jar is use it to create a fresh rails application but then once you go into the rails application you still have to start using your development tools bundler and install the gem and everything I don't think you can actually continue to develop with rails in the jar file to expose it somebody really wants to do that one thing I was going to try to do here since I think I still have a couple minutes is um I'll just create a little rack application I know I have a lot of work in settings alright so here's my I can do this and actually do I can do the same thing before with java minus jar and this will start at one stone again and we can go over here and uh okay let's do this type something oh looks like a syntax error yeah I missed an extra bracket square bracket in my config ru but you see it's actually detecting the config ru and saying okay that looks like a rack application or it could be some not terrible value and it thunders that up and gets it going for you so the thing I was going to show you before was um now that I have my environment set up properly by the world here um I was picking up another version so I'll actually create a rails jar and say java minus jar rails or else a new oops that's not going to work because I'm not connected to the internet but it will work if I didn't include a template okay you get the idea so let's go back to the slides for a couple minutes alright so I just showed you a variety of demos hopefully some of them are compelling to you as ways that you could actually build and distribute new applications that was the whole idea of the talk but what's next, what else can we do here um it's largely up to you but I do have a couple ideas of things I could do to make this more interesting going forward um first one is to since you'll notice that the start of the jar files and the work files was a little bit slow and that's because uh well first of all starting application of the java was a little bit slow in general but add to that the fact that you have to unpack a bunch of stuff out of the jar file before you can run so I'm thinking well you actually want to distribute these as little utilities and actually be able to use them repeatedly and not be overwhelmed by the start up of unpacking everything all the time before they run um we could actually maybe make a little local cache on this where stuff gets unpacked and we make sure that um we track the versions or check sums of things that you're unpacking and make sure that that stuff is present we won't actually do the unpack stuff we'll just set up those jar files that you can just run and maybe that will be a way to make repeated uses of these utilities a little bit more pleasant in terms of the start of time um as I mentioned a little bit earlier I think it'd be nice to actually try some other web servers as well. Winstone one's been around for a while in Java and it's not really maintained anymore it seems to work pretty well but maybe using something like Jetty which is also another Java web server that's a good embedding embeddable web server as well which has the advantage of being maintained currently and it would be a better option or something to play with another thing to look at is there was a summer code project this year um I forget the fellow's name but he worked on a project called Ruby Archive and the point of Ruby Archive was to make um kind of do a similar similar thing where you have zip archives with Ruby 1000 and you can transparently require them load them and run them from within the archives and so he did some work there to find some stands around that I'd like to see if there's some synergies there I can maybe support Ruby Archive or maybe he can support some of what I'm doing that sort of thing another idea I've had for a while which I think would be really cool to do is say you've got a Rails application that you make a warp file out of but a lot of people ask well what do you do about the migrations then you have a warp file you still need to run the migrations somehow and I usually give some protective set of steps like okay well you need to unpack the warp file manually and then when the rate de-migrates it makes people throw up in their mouth a little bit so I think you know okay we can fix that and I think wouldn't be cool to be able to say okay well I've got a warp file and allow me to use rate on the warp file itself and I can just pass my rate command line along with the gentleman kind of like this and that would probably still have to unpack some things but this would allow you to hand your ops people a warp file and say okay well before you deploy this just run this one command line and it will migrate your database or maybe run some other big tasks for you and of course as I mentioned your feedback would be appreciated if you think this stuff is cool please check it out and let me know what kinds of ideas you have for at least this kind of thing and send me your box and I just released a beta 1 of Warlord 1.3 which has all this stuff in it that I just showed you so you can install that now I hope to have a 1.3 final log within a week or so just lead up to RubyPatch and getting things working, providing me from fixing bugs and doing a few pieces of polish before I get everything to full release out so do check that out and thanks for coming I think that pretty much wraps up what I have here I do have some engineering stickers up here if you're interested in one of those we can stop up if you've got one thanks a lot