Posted by Nick Sieger
Tue, 06 Apr 2010 17:11:17 GMT
It’s past due time to “carry the 1” over and roll over to a 1.0 version of Warbler. This time around, the changes in the codebase are significant enough that I hope you’ll find many past usability issues resolved.
Assemble in-place
The biggest change is that Warbler now creates a war file in place, without an intermediate copy-to-assemble step. Warbler does this using the rubyzip
gem, or alternatively using a small Java extension when run under JRuby 1.5 or greater. This should reduce processing and confusion due to the extra copy, which can sometimes get out of sync. The downside is that Warbler cannot be used easily for exploded directory development, though you can always create the war file and unpack it to a staging area.
Simpler extension
Warbler also underwent an internal refactoring that should make extending it much easier. Here’s how you add Warbler tasks to your Rakefile
:
require 'warbler'
Warbler::Task.new
In versions prior to 1.0, if there were deploy steps that created new files that didn’t exist at the time the Rakefile
was loaded (such as what the asset:packager:build_all
task does in the asset_packager plugin), it was tricky to get Warbler to recognize them. No longer -- now the expected Rake configuration should do the trick.
require 'warbler'
Warbler::Task.new
task :war => "asset:packager:build_all"
Bundler support
Another exciting development in the Ruby development world is Bundler, and Warbler 1.0 supports packaging your bundled gems with it. Warbler even creates a .bundle/environment.rb
file inside the war file that loads the gems from relative paths to where Warbler puts the gems in the war file.
More configuration
There are a number of new configuration options, so check out the new configuration and see if any are useful to you.
config.gem_home
allows you to control the path inside the war file where Warbler will pack your application’s gems. For use with older versions of Bundler or other custom gem vendoring schemes.
config.webinf_files
is a file list that can contain multiple files, XML or otherwise. If the files named in this list have .erb
extensions, they will be expanded in the same manner as web.xml
.
Rails 3 support
JRuby-Rack, the servlet adapter component bundled by Warbler, also received a version bump, and there are no longer any Java libraries included in the Warbler gem, so the two components can be versioned independently. With the release of both Warbler 1.0 and JRuby-Rack 0.9.7, Rails 3 applications can be warbled and deployed seamlessly, often without any additional configuration.
Please continue to send feedback to the JRuby mailing list or the Warbler bug tracker. Enjoy!
Tags jruby, warbler | 2 comments
Posted by Nick Sieger
Thu, 27 Aug 2009 20:12:00 GMT
So, after a long, busy summer, I’m finally back onto support of the various bits for JRuby web application development (meaning Warbler and JRuby-Rack). I’m pleased to announce the 0.9.5 release of JRuby-Rack and the 0.9.14 release of Warbler! All of this brought to you courtesy of Engine Yard, my new employer!
Both of these are long-overdue releases. Here’s the low-down on each:
JRuby-Rack 0.9.5
For the full history, see the 0.9.5 entry in the History.txt file.
One bad bug in particular prevented you from running Rack-powered Rails 2.3 out of the box at all because JRuby-Rack bundled an older version of Rack than needed by Rails. This has been fixed for good by not forcing JRuby-Rack’s bundled copy of Rack on your application; any version of Rack you include (either via gems or vendor’ed in Rails or your application) will take precedence.
Another major upgrade is the introduction of rewindable requests. The Rack spec dictates that the request IO object be rewindable and that server/handler writers (such as myself) need to buffer the input. You’d think that Java application servers would do this for you, but, as is the case with Java so often, servers perform the bare minimum amount of work and leave the grunt work to the application developer. So JRuby-Rack takes care of the input buffering for you. The first 64k of input data are buffered entirely in memory; above that the request body is dumped into a temp file. (64k is a default and is configurable. If you have a better suggestion for a default, let me know.)
Finally, this release brings back Java Servlet-based sessions for use with the Rack-based session mechanism. For those of you experimenting with hybrid Rails/Java applications and want to share session data between them, you’ll want this. Servlet sessions are not the default; you need to turn them on by setting ActionController::Base.session_store = :java_servlet_store
.
Warbler 0.9.14
Warbler’s main change this release is to unbundle JRuby. When you install Warbler as a gem, you’ll now get a dependent gem called jruby-jars
installed for you. We’ll be releasing a new version of this gem with every release of JRuby, and you’ll be able to upgrade JRuby versions without having to update Warbler.
JRuby-Rack is still bundled with Warbler for now (0.9.14 comes with JRuby-Rack 0.9.5 of course), but the jar file is not that big and the two projects tend to be released around the same time. By Warbler 1.0 I hope to have a mechanism to unbundle all jar files so that Warbler is just a lightweight Rake library with enough smarts to fetch the binaries your application needs.
Future
The projects seem to be headed for a 1.0 release soon. For these releases, I hope to ensure that they are both ready to take advantage of Rails 3 out of the box. One of the ways is to use Bundler in Warbler to manage gems. Hopefully as Rails 3 and other applications start to standardize Bundler manifests, it means less custom configuration for Warbler.
Since the core of JRuby-Rack seems to be stabilizing, the next promising step is to explore more ways to integrate with existing Java code and Java applications. This should dovetail nicely with JRuby’s plan for better Java integration in the upcoming JRuby 1.4 release. For example, Christian Seiler explained how he’s using JRuby-Rack to integrate JMS while running an in-memory ActiveMQ server for his site blissmessage.com. These kinds of ease-of-use scenarios where you can start a single process with all of your application needs: web server, message queue, timer for periodic tasks etc. present a great way to jumpstart a project. I’d like to see some of these APIs standardize so that we can transition from all-in-one development servers up to scalable production clusters where app, message queue, and other servers are separated and standalone.
The fellows over at Google have been busy this summer with the appengine-jruby project, and there are opportunities for tuning that experience as well.
Of course, your suggestions are welcome too. I’d appreciate it if you’d drop me a line if you’re doing something novel with these tools, so I can help shape future directions around people like you who are Getting Things Done with them!
(Postlude: Both these projects need a logo. If you can mock something up, I’d love to see some ideas!)
Tags engineyard, jruby, rack, warbler | 1 comment
Posted by Nick Sieger
Fri, 19 Dec 2008 13:46:33 GMT
I finally got around to releasing the next version of Warbler. I try to keep pace with JRuby releases but 1.1.5 had some bugs that I wanted to wait out (in particular, one with Rubygems assuming Etc
is always available).
New in this release is better automatic gem detection for both Rails and Merb. In particular, Warbler will use the contents of Merb’s config/dependencies.rb
file. As an added bonus, only runtime dependencies are loaded. This detection is done by running the Rails environment
or the Merb merb_env
Rake task. Usually, loading the application environment requires a database connection. If you don’t want this behavior, you can manually specify dependent gems in config/warble.rb
and turn off the framework detection with Warbler.framework_detection = false
. See the documentation for details.
Warbler 0.9.12
- Allow framework auto-detection to be disabled. Set
Warbler.framework_detection = false
at the top of config/warble.rb or uncomment the line from a newly generated config.
- Add configuration option to set manifest file (thanks Tommy McGuire)
- Mitigate RubyGems 1.3 compatibility issue (thanks Jens Norrgrann)
- Add experimental
war:exploded
task. This allows you to deploy your application in an exploded mode, thus allowing continual development without re-warring and re-deploying. Feedback is appreciated if you try this feature; it may not work in all application servers and for applications other than Rails.
- Handle Rails gem dependencies better (thanks Laszlo Bacsi)
- Auto-detect Merb dependencies (Merb >= 1.0 only). Please give feedback if you try Warbler with a Merb 1.0 app.
- Ignore gem development dependencies
- Upgrade to JRuby 1.1.6 and JRuby-Rack 0.9.3
Tags jruby, rails, warbler | no comments
Posted by Nick Sieger
Thu, 10 Jul 2008 05:10:27 GMT
The other day several people chimed in wondering how I set up this blog with JRuby and Glassfish. One of the reasons I didn’t include the details in the post is that it’s not really much different than any JRuby/Glassfish/Warbler deployment, but in case you don’t know what that looks like, here are the basics.
Preconditions (Java)
I’m running on a Joyent Accelerator, which runs OpenSolaris, which has JDK 6 installed by default. If you’re running on some flavor of Linux, hopefully there’s a package available for you to install, otherwise you may have to download a self-extracting binary.
This step is actually straightforward; not at all as problematic as you might expect of a piece of Java technology! In the parent directory where you want Glassfish to be installed (substituting the name of the Glassfish jar you downloaded as appropriate):
java -Xmx256m -jar glassfish-installer-v2ur2-b04-sunos_x86.jar
cd glassfish
chmod -R +x lib/ant/bin
./lib/ant/bin/ant -f setup.xml
Start Glassfish.
./bin/asadmin start-domain
You may want to add GLASSFISH/bin
to your path so that you can run the Glassfish asadmin
command from anywhere.
On Solaris, SMF is the subsystem that is used to ensure services are started at boot time (among other things). Glassfish works nicely with SMF. On other systems, there may be /etc/rc.d
init scripts out there, or you can roll your own (asadmin start-domain
and asadmin stop-domain
).
Install JRuby
Download JRuby and unpack it somewhere. I recommend adding JRUBY_HOME/bin
to the end of your path, so it doesn’t clash with Matz-Ruby.
Install Warbler and activerecord-jdbcmysql-adapter
In addition to Warbler, I’m using the activerecord-jdbcmysql-adapter to connect to the blog’s database. Both can be installed with Rubygems:
jruby -S gem install warbler activerecord-jdbcmysql-adapter
With Rails 2 and up, the application’s config/database.yml
file should be updated for adapter: jdbcmysql
:
<% jdbc = defined?(JRUBY_VERSION) ? 'jdbc' : '' %>
development:
adapter: <%= jdbc %>mysql
encoding: utf8
database: testapp_development
username: root
password:
socket: /tmp/mysql.sock
# same for test/production...
Otherwise, you need to jump through some extra environment.rb configuration hoops.
Configure Warbler
Warbler needs to be told about any gems that your application uses. To generate a Warbler configuration file:
jruby -S warble config
The file is generated at config/warble.rb
. In it, modify the following sections:
config.gems = ["activerecord-jdbcmysql-adapter"]
...
config.webxml.jruby.min.runtimes = 2
config.webxml.jruby.max.runtimes = 4
Build and deploy the .war
jruby -S warble
asadmin deploy --contextroot / blog.war
(--contextroot /
makes the application rooted at /
in the server, rather than at /blog
which would be the default.)
At this point, the blog application is up and running on port 8080. I had previously been running the blog with an Apache/.htaccess-based setup reverse-proxying to mongrel, so all I had to do was change the port. I haven’t touched it since.
But is this right for you?
Chances are, this setup is overkill for a simple blog. If you’re going to try it, I’d recommend at minimum running on a VPS with at least 1G of memory. But once you get the core pieces in place, updating and re-deploying the application is really just as simple as the last two commands. It’s mundane and boring in its simplicity. But boring is good when you don’t want to worry about having to keep Mongrel running, or max out the memory in your server and make it unstable.
Tags jruby, rack, rails, warbler | 5 comments
Posted by Nick Sieger
Tue, 04 Sep 2007 02:48:40 GMT
This week I was working on integrating the latest JRuby 1.0.1 and Goldspike 1.3 releases into our environment, when my frustration hit a fever pitch.
See, I had always thought that the .war packaging side of Goldspike was a little clunky and
un-ruby-like, but I didn’t see a clear path to fixing it. I had heard little complaints about it here
and there: the little configuration DSL didn’t give you enough control or wasn’t documented well
enough; the fact that it downloads libraries from the internet during assembly (convenient, but not
safe or reproducible for production deployments).
Also, in my own opinion it took the wrong approach to packaging Rails in a .war file. It puts the
Rails application directory structure into the root of the .war file where any web server or Java
application server might mistakenly serve up your code as static content. The Java .war file spec has
this special directory called WEB-INF
expressly for the purpose of hiding that stuff away, so why
not use it?
And then, suddenly Goldspike was packaging up my entire Rails application directory, .svn directories
and everything. So I set out to fix this once and for all.
And so I present Warbler. A little bird who chirpily steps up to the task of assembling your
Rails application into a Java Web Archive (.war). Here, get it:
gem install warbler
And then, in the top directory of your Rails application,
warble
Those two steps are all it takes to make a .war file, including your application and recent versions
of JRuby and Goldspike, that’s deployable to your favorite Java application server.
There are a number of points about Warbler worth mentioning.
Does one thing, well
Warbler only packages, and doesn’t care about anything else, like how to dispatch servlet requests to
Rails. This will allow for more runtime servlet binding mechanisms to take advantage of Warbler in
the future.
Fast and lightweight
50% less code than the Goldspike packaging plugin, yet does the job quickly and efficiently.
Sane defaults
Warbler only packages code that you need to run the application, omitting database migrations and
tests. If your application is self-sufficient (no external dependencies), then the out-of-the-box
configuration will probably work for you. Public HTML/images/javascript/stylesheets go in the root of
the webapp, where Java webservers expect them to be.
Documented, flexible configuration
Need to customize your configuration? Run warble config
and edit config/warble.rb
. All the
options are there, commented and documented.
Need to change out the bundled JRuby/Goldspike versions? warble pluginize
makes a copy of Warbler
in the vendor/plugins
area of your application, allowing you to change the .jar files in the
vendor/plugins/warbler-0.9/lib
directory. Warbler then makes his nest in your project’s list of
rake tasks (as rake -T | grep war
shows)
rake war # Create trunk.war
rake war:app # Copy all application files into the .war
rake war:clean # Clean up the .war file and the staging area
rake war:gems # Unpack all gems into WEB-INF/gems
rake war:jar # Run the jar command to create the .war
rake war:java_libs # Copy all java libraries into the .war
rake war:public # Copy all public HTML files to the root of the .war
rake war:webxml # Generate a web.xml file for the webapp
Warbler even omits himself in the .war file produced when running in plugin mode, since you won’t
need him at runtime. It’s the little details that matter.
Give him a try and let me know if it makes your life deploying Rails applications to JRuby on Java appservers easier!
Tags jruby, rails, warbler | 13 comments