Rawr takes all of an application’s files and packages them up into an executable jar. The end result includes a copy of jruby-complete.jar such that, so long as you have Java installed, you can run this jar as you would any other executable jar file.
It’s very slick.
Rawr works on the assumption that your application is self-contained. That is, you should not be trying to load any gems. Indeed, Rawr makes an effort to adjust the contents of $LOAD_PATH so that you are only loading files from specific directories local to your application.
If you are used to using gems in you Ruby apps this can be a hurdle. However, there’s nothing magical about gems; they just (ordinarily) live in locations outside of your project tree, and Ruby provides a way for your program to discover their location.
Since locations outside of your project tree are a no-no with Rawr you need to move any gem files into your project tree.
This is easy. Use
gem unpack. By default this will locate the latest version of that gem that you have installed and create a folder in the current directory named for the gem and version number.
If you look at what’s in that folder you will (almost always) find at least a
lib subfolder as well as subfolders for tests, examples, and maybe a few other things. In almost all cases you will really only need what’s in the
Rawr doesn’t demand that you follow too many requirements for where you put your folders but there are some conventions.
Ruby libraries typically go into a subfolder of your project tree called
lib/ruby. I guess that technically this is a subfolder of a subfolder.
But note that while this is something of a convention you still have to tell Rawr about this path.
When you create a new Rawr project (i.e. you decide to use Rawr in some project you want to package up as a self-contained executable, and you generally do this by running
rawr install) you should have a file named
If you opted for the auto-generated file it should contain a number of configuration settings, any of which will be commented out.
One of these indicates the location of your Ruby source files.
@ c.source_dirs = [“src”, “lib/ruby”]@
This example shows another convention: Main application files are placed under
src while helper library files go under
lib/ruby, but in all cases you have to tell Rawr about this.
Rawr uses this information in order to know what files and folders are to be bundled up. It also takes the paths set in
c.source_dirs and stuffs them into
Rawr works by providing a
Main.java class that serves as the entry point for the executable jar. When you run the jar it calls into this
Main class, and the default code will look for a Ruby file called
main.rb someplace in the paths you set.
main.rb (that is, the one generated when you run
rawr install) will do assorted set-up things and load another auto-generated file,
manifest.rb. It is in this file where some additional
$LOAD_PATH alterations take place.
This may also a good place to set up any other folder paths you want to ensure are on the load path. You can also do this in
main.rb, but in any event you’ll want to set up these paths before your application code tries to load any other files (such as the ones from the gem you unpacked).
When you unpack a gem and place it into your rawr-ready project you may only need the contents of the gem’s
lib folder, but it can be useful to include the parent folder, the one that has the gem name and version. It makes it easier to quickly see just what you’re using.
For example, in your project tree:
build_configuration.rb you are likely setting
lib/ruby as a folder to bundle up; that means when you want to
require any (in this example)
restafarian files you’ll to have added this additional info to your load path. So, while
lib/ruby may be part of the load path, you would need to add
as well before calling
The downside is that this ties the gem version number to your code. If you update the gem and unpack this later version into your project you’ll need to update the path references.
I will confess that this may just be a “works for James” situation. However you decide to manage this just be sure that you’ve set up your configuration and any
$LOAD_PATH alterations to include the proper path to the files you will want to require.
If a gem you unpack decides to use another gem then you will need to unpack that gem as well and make sure it is part of your project. All code dependencies should be in your project. What you need to watch for, though, are gems that attempt to load a gem by explicitly invoking
rubygems. It’s dopey but sadly not unheard of.
Rawr should be sorting out the load path but as rubygems has become a built-in part of Ruby it is possible that an unexpected call to a gem might end up loading code that is not part of your project. Problem one is that you program might seem to work fine on your machine but fail when run on another machine. Problem two is that a different version of a gem might get loaded causing mysterious behavior.
While checking out a report of some trouble including third-party libraries I created a test program that had assorted directories and subdirectories under
lib/ruby. I ran
rawr:jar and then checked the results. There was no
src folder in the jar. All the files and folders from those directories were combined into the root of the jar. There is a
ruby folder there, but it’s empty.
If you have two files with the same name in both
lib/ruby only one comes out alive. This seems like a Bad Thing.
The goofy thing is that this may have been the behavior for quite some time. I haven’t yet gone through the code; it’s plausible that this combining of folders was intentional, but the presence of that empty
ruby directory suggests a bug, albeit one that apparently (at least in my use of Rawr of time) didn’t seem to break anything. However, I dug up some jars made a few years ago and it appears that this was not always the case.