Impressum / Imprint

Saxon government's press releases now powered by JRuby on Rails

Posted on April 07, 2008

Medienservice Sachsen Last week, the Medienservice, the platform via which the saxon government publishes its press releases to journalists and to the public, has been relaunched. It now runs on a cluster of JBoss servers that are part of the official saxon e-government platform. While the public web frontend might look like just another Blog-like application to you, I assure you that the stuff that happens in the background is anything but simple - there’s a lot of stuff going on like deferred publishing, publishing press releases only to subscribed journalists, and sending out press releases in four different formats including PDF and XML, to only name a few.

As far as I know this is the first public german JRuby on Rails application - one more reason for me to be proud of being part of the team at webit! that built this baby.

Grails project begging for attention

Posted on January 14, 2008

Sorry, but I can’t think of any other reason why Graeme Rocher might write such crap.

Among the points he makes when trying to convince his readers why they should choose Grails over Rails, there are at most two or three which are somewhat reasonable, namely those dealing with integrating your application with external J2EE based services. I completely agree that these are valid points when comparing Grails running inside a fully-fledged J2EE container to Rails running in, say, Mongrel. But since Rails runs fine in a J2EE environment as well, that’s an unfair and misleading comparison.

Using container-managed database connections via JNDI in a JRuby on Rails web app is no problem at all, neither is using Quartz to schedule Rails background jobs, just to name a few examples. I don’t see anything stopping people from using the whole range of J2EE container features in their JRuby/Rails applications once they need to do so.

The whole ‘Grails is more enterprisey than Rails’ argumentation falls apart once you stop comparing apples to oranges, and slap JRuby + Rails onto that damn app server.

Grails 1.0 coming out within the month

Uh cool, yeah. Until now I thought statements like this were more a specialty of closed source vendors trying to convince their potential clients not to check out the competition. Looks like they can’t wait to finally attach that decision maker friendly 1.0 label to Grails ;-)

Anyway, I feel we’re all going to have an interesting time in the future watching how the competition between JRuby/Rails and Groovy/Grails goes on. After all, competition tends to lead to better products in the end.

Job scheduling with JRuby and Rails

Posted on January 12, 2008

As promised earlier, here’s the first of several articles I’m planning to write about running Rails on JRuby. Originially I wanted to start this little series with some kind of ‘getting started with JRuby on Rails’ guide. Since I didn’t find the time (or, say, motivation) to write one for weeks now, I decided to skip right through to some more advanced topics. So for this post, I’m assuming you already got your hello world JRuby on Rails project up and running and deployed to the application server of your choice. If this is not the case, have a look in the Wiki for documentation about getting started. It’s also worth following the various relevant blogs, as well as the jruby and jruby-extras mailing lists.

Ok, this post is titled Job scheduling with JRuby and Rails for a reason, so let’s get started with this now.

While Rails itself nowadays runs quite flawless inside application servers like JBoss or Glassfish, the usual way to handle background job (push it to some external daemon) doesn’t fit a J2EE application server environment particularly well. Besides the fact that I couldn’t think of an easy way to get BackgrounDrb running from my application’s WAR file, it simply doesn’t feel right to have any extra daemons like BackgrounDRb running besides that fat application server.

As it turns out, there are several ways to do better.

The GoldSpike solution

The kind folks from the jruby-extras team provide two servlets, RailsTaskServlet, and RailsPeriodicalTaskServlet as part of the GoldSpike plugin. These servlets can be used to run arbitrary Ruby code inside the context of your Rails application either once or periodically every n seconds. To schedule a job running YourJobClass.do_stuff every minute, you would place the following declaration into your web.xml:

<servlet>
  <servlet-name>periodicalTask</servlet-name>
  <servlet-class>org.jruby.webapp.RailsPeriodicalTaskServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
  <init-param>
    <param-name>interval</param-name>
    <param-value>60</param-value>
    <param-name>script</param-name>
    <param-value>YourJobClass.do_stuff</param-value>
  </init-param>
</servlet>

Oh the joy of XML configuration files ;-)

While this works great, I had to run a job not every some seconds, but once a week on a defined day and time. Besides that, declaring a separate servlet for each single background job seems like overkill. Back from my Java days I knew that the Quartz library provided exactly what I needed - support for cron patterns. So the challenge was to get Quartz run my Ruby script inside the context of my application.

The rails_quartz plugin

Our target platform was JBoss, which already includes the Quartz library. I’m not sure about other app servers, if yours doesn’t have this already, just download quartz and put the jar including any dependencies somewhere in your application so it ends up inside the WEB-INF/lib folder of your WAR file. With Warbler, which is my preferred way to package JRuby on Rails applications, RAILS_ROOT/lib is good place, since it will pick up any jars from there automatically.

How does it work?

The plugin provides a ContextListener, which, when declared in web.xml, looks for any job declarations and tells the Quartz Scheduler about them. Here’s an example web.xml snippet scheduling a job to run every friday at 10 am:

<context-param>
  <param-name>yourJobCommand</param-name>
  <param-value>YourJobClass.do_stuff</param-value>
</context-param>
<context-param>
  <param-name>yourJobCronPattern</param-name>
  <param-value>0 0 10 ? * 6</param-value>
</context-param>

<listener>
  <listener-class>org.jruby.webapp.quartz.QuartzContextListener</listener-class>
</listener>

As you see, I use context parameters to configure the command to run, and the cron pattern to use. You can declare any number of jobs you want, just stick to the naming scheme for the parameters: <jobName>Command and <jobName>CronPattern so the listener can find out which pattern belongs to which job.

You can get the plugin here: https://projects.jkraemer.net/svn/plugins/jruby/quartz_rails/ . As always, any feedback is welcome.

Strange Mongrel 1.1 error (solved)

Posted on January 07, 2008

Right after updating Mongrel, gem_plugin and some other (probably unrelated) gems today, Mongrel didn’t like me any more, refusing to start up any Rail s application. Instead, I got this nice message complaining about a missing init.rb in the activerdf gem:

** Rails loaded.
** Loading any Rails specific GemPlugins
Exiting
/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in 'gem_original_require': no such file to load -- /usr/lib/ruby/gems/1.8/gems/activerdf-1.6.1/lib/activerdf/init.rb (MissingSourceFile)

It took me a while to find the fix on rubyforge via google, so maybe this helps somebody else having the same problem.

acts_as_ferret 0.4.3

Posted on November 18, 2007

Long time since the last release (not counting the short-lived 0.4.2 …), and I guess most people already use trunk anyway, but for the faint of heart, here’s the new stable version of your favourite Rails fulltext search plugin.

As always, get it via svn from svn://projects.jkraemer.net/acts_as_ferret/tags/stable/acts_as_ferret. More installation information can be found on the acts_as_ferret Trac site.

No big news feature-wise, I already wrote about the more important features when I added them to trunk:

Going through the timeline looking for some cool feature I didn’t already write about I found several smaller things worth mentioning:

Dynamic document specific boosts

This comes in handy if you want to have search results automatically ranked by a criteria which is different for each record, e.g. the popularity of an article in your shop:


class Article
  acts_as_ferret :boost => :popularity
  def popularity
    # return dynamic boost value for this document
  end
end

You may also apply the dynamic boost to a specific field (or even different boosts to different fields), so it only is applied when a hit occurs in the boosted field. This way you can choose at query time if you want to have the boosting applied or not. Just query either the boosted fields, or the normal ones:


class Article
  acts_as_ferret :fields => { 
                             :title               => {}, 
                             :boosted_title => { :boost => :rating } 
                         }
  def rating
    # return rating of this article
  end

  # value for the boosted title field
  def boosted_title
    title
  end
end

New and better start/stop scripts

The DRb server now has a unified start/stop script and it ships with scripts for using the it as a Windows system service. Thanks to Peter Jones and Herryanto Siatono for contributing these.

Also the acts_as_ferret gem now has got an installer that will install the server script and sample config into your Rails project:


$ gem install acts_as_ferret
$ rails test
$ cd test/
$ aaf_install
$ script/ferret_server -e production start

And your DRb server is up and running. Easy, isn’t it?

No more :remote => true

Last but not least, aaf now is a bit more clever and goes into remote mode automatically if the DRb server is configured for the current environment. If for whatever reason you don’t want that, use :remote => false.

How I learned to stop worrying and love JRuby on Rails

Posted on October 31, 2007

As I wrote earlier, I got pretty excited about JRuby and especially about the idea of running Rails on top of it at RailsConf Europe. By pure coincidence we had just had started a project at webit! at this time which had to be deployed to the customer’s J2EE infrastructure. I didn’t really follow the JRuby development before, and therefore greatly underestimated its level of maturity. So, looking for a Rails-like way to build this application, I decided to go with the Groovy-based Grails framework.

At first Grails looks and feels much like Rails, however if you look closer and actually try to build a real application with it, the differences start showing up. Don’t get me wrong, when compared to the more traditional J2EE ways to build web applications (my experiences in this field range from plain Servlets to Struts and Spring), Grails is a huge step into into the right direction. Unfortunately for me, coming from Rails, it just didn’t feel right or complete in many places. Partly this is for sure because Grails, despite its name, is not just a Rails clone, but does things in its own way in many places. Without going into much more detail here, things often weren’t working the way I expected, and documentation was often outdated or missing.

Another issue with Grails for me was Hibernate, its persistence layer of choice. I simply can’t get used to the way Hibernate works. In my opinion it abstracts way too much from the database with its own query language and all its object oriented query building glory. Also it seemed to queue up sql statements and execute them at will at some later time, which I found irritating to say the least. I really don’t understand why Hibernate is the persistence framework of choice in so many J2EE projects. On the other hand it fits the ugly picture of the bloated J2EE web application quite well ;-)

To summarize this rant, don’t underestimate the learning curve of Grails, which will be even steeper when you aren’t already used to Hibernate. I think Rails people having to do J2EE development are just not the target audience of Grails. But it might be a good fit for J2EE developers who either already have their Hibernate models in place or at least have the will to invest some serious time in learning Hibernate.

After all, as you might already have guessed, I decided to start from scratch with JRuby and Rails after RailsConf Europe. And it really felt like coming home from a long and exhausting trip. Despite the lost time in the beginning we met our deadline and had a really great time solving problems the Rails way and deploying to JBoss every now and then. Right now I’m in the middle of my second JRuby on Rails project, same customer, same target platform. I plan to write some more articles about our experiences with JRuby, so stay tuned.

Railsconf Europe Roundup

Posted on September 20, 2007

With more than 3 days full of Rails and fun and meeting cool people from all around the world behind me, here’s what I took home from Railsconf Europe:

Sun and ThoughtWorks are really pushing JRuby

JRuby has been covered in 4 talks by speakers from both Sun and ThoughtWorks, who also were among the diamond sponsors of the conference.

It really looks like JRuby is ready for real life usage in J2EE environments, effectively bringing Rails into the so-called enterprise through the backdoor. Or, as Ola Bini put it,

JRuby is just another Java library.

Pretty impressed I immediately tried this stuff out - and it really works :-) Time to ditch Grails and have some fun with my favourite language instead.

Selenium

Till Vollmer’s presentation of the browser-based testing tool Selenium was quite impressive. I definitely have to try this out.

Webistrano

At Rejectconf which was organized by the Berlin Rails User Group, Jonathan Weiss gave a short introduction to Webistrano, which is a web-based frontend to Capistrano. Great way to get designers and editors without a local Ruby/Capistrano installation involved in the development process.

Report #12

Besides telling us that it’s time to put the party hats and James Dean jackets aside for a while, and instead get some real work done (and of course have fun) with Rails, DHH introduced report #12, which basically is a list of well-tested patches that have been approved by at least 3 other people. This formalization of the peer-review process is a really good thing as it takes some of the work load away from the core team and makes it easier for people to contribute.

Rails developers are happier

We all knew this, but it’s good even Sun’s Craig R. McClanahan noted in his inspiring talk that he never saw that many friendly and happy people at JavaOne, as he saw at Railsconf Europe. He also admitted that going back to Java after having worked with Rails is not that pleasant. Just to remind you - he’s working at the company whose ticker symbol is JAVA

All in all it was a great event, and even with Dr Nic speaking at the same time my own talk was pretty well attended,

Raise your hand please if you're using Ferret

Posted on September 09, 2007

Working on acts_as_ferret for more than one and a half year now, I’m really interested in why and how people are using it in their applications. Also, a list of Ferret-powered projects will be a good starting point for people who are still looking for a search solution for their Rails app.

So if you’re using Ferret, please drop me a line, comment here, or even add your application to the Powered by Ferret page over at the Ferret project’s Trac. Ideally you would also post some facts like index size, your production environment or even performance numbers. Personally I’d also like to know if you’re using acts_as_ferret, or, if that’s not the case, why you decided to go with pure Ferret.

I’ll also mention some sites that make use of Ferret in my talk at Railsconf Europe next week. So if you’re looking for some publicity, what are you waiting for?

Faster indexing with acts_as_ferret

Posted on September 02, 2007

Does your application operate on large chunks of records that are indexed by acts_as_ferret? If the answer is yes, then this is for you:

By combining two brand new features of acts_as_ferret you may now speed up batch operations like this: First, disable acts_as_ferret indexing for the model class in question. Then do your updates, but be sure to remember the primary keys of the modified records. After that, re-enable acts_as_ferret and index all modified or created records at once:

Model.disable_ferret
# create or modify records here, collect ids in id_array
Model.enable_ferret
Model.bulk_index(id_array)

You may also use the block syntax to have aaf be re-enabled automatically:

id_array = []
Model.disable_ferret do
  # create or modify records here, collect ids in id_array
end
Model.bulk_index(id_array)

Pagination goodness

Posted on August 27, 2007

Finally implementing pagination for your acts_as_ferret search results is as easy as it should be (at least if you’re using aaf trunk, everybody else will have to wait for the soon-to-be-released 0.4.2):


@results = Model.find_with_ferret params[:query], :page => params[:page], 
                                                  :per_page => 10

Acts_as_ferret’s SearchResults class now gives you all you need to implement a helper rendering your pagination links:


@results.page           # => current page
@results.page_count     # => total number of pages
@results.previous_page  # => index of previous page or nil if on the first page
@results.next_page      # => index of next page or nil if on the last page

Best of all, this even works when you combine your query with ActiveRecord conditions.

Hint: really lazy people install the will_paginate plugin and use it’s will_paginate helper method to get their pagination links for free!

acts_as_ferret 0.4.1

Posted on July 17, 2007

Besides several small tweaks and fixes, this release introduces index versioning to the DRb server. Now everytime you call MyModel.rebuild_index, a new index is built in the background. During that process the original index is still in place, so ideally nobody will notice. Once the rebuild is done, acts_as_ferret will switch over and use the new index.

Disclaimer: until now any modifications done to model instances while the rebuild runs will go into the old index, so you’ll have to keep track of these yourself.

MySQL users with a large number of records might as well notice a speed increase with index rebuilds, thanks to this clever exploitation of several MySQL specifics.

Btw, if you’re looking for some capistrano recipes for managing your ferret server, have a look at the palmtree project.

Rails-Konferenz 2007

Posted on June 26, 2007

is over. It’s been a great day full of interesting talks and interesting people.

Pictures from the conference are here, there and there.

Here’s my (german) talk about Ferret and acts_as_ferret. It’s done with S5, you can reach the outline (which has more text) by moving the mouse to the lower right and clicking Ø.

Update: Slides from the conference are available as PDF now, too.

Next is RailsConf Europe.

Capistrano saved my day

Posted on May 15, 2007

The upcoming Capistrano 2.0 adds some very handy features to this already great tool.

Here’s how to deploy your shiny new Rails app to a web server without access to your subversion repository:

# config/deploy.rb
# deploy by copying a tarball to the remote host
set :deploy_via, :copy

# use export instead of checkout when building the archive 
# (this happens on your local machine now):
set :copy_strategy, :export

# uncomment to use zip instead of tar:
# set :copy_compression, :zip

In my experience the ‘argh, no svn’ scenario occurs more often than not when dealing with client’s web servers. Often firewalls prevent connections from the server to outside servers, and/or there is no subversion installed on the machine. For me this new feature alone justifies the upgrade.

Random Notes

Posted on May 14, 2007
  • Acts_as_ferret’s DRb server now handles index rebuilds nicely. Every rebuild will create an entirely new index. While reindexing runs your application will continue to use the old index. That should bring us a huge step towards the next release of aaf.

  • Online chat site Lingr is using acts_as_ferret to provide it’s users with full text search across everything that ever has been said there. They built a neat analyzer to handle multilingual content (including non-latin languages like Chinese or Japanese) in both documents and queries which should be open sourced soon.

  • Last but not least, I’ll talk about Ferret and acts_as_ferret at Rails-Konferenz.

Europe on Rails

Posted on May 08, 2007

So many Rails conferences, the dates already start overlapping :-)


Rails-Konferenz taking place June 22nd in Frankfurt/Main, Germany.


The first Czech Ruby on Rails conference in Ostrava, Czech Republic.


Of course, RailsConf Europe, September 17-19 in Berlin, Germany.