Sunday, January 22, 2012

Database migrations with deployed JRuby WAR files

In my previous post Compiling Rails project for distribution in a WAR file with JRuby, I explained how to build a  WAR file from a Rails project to distribute on to systems that have a Java app server like Tomcat or Glassfish.  If you're running this in production, you're probably going to want to run database migrations after the WAR file is deployed.  Unfortunately this is not as straightforward as you might expect.  But it's not too difficult.  To run database migrations, you must first create a file in your project, config/warbler.rb with the following contents:

Then, add a file named script/db_migrate with the following contents:

Now, on the production system, after the WAR file has been deployed, from the root directory of your web app, run the command:

If you're running in 1.9 mode, add --1.9 before the -S. This assumes that you have a jruby executable in your path somewhere on the server. There should be a way to run the JRuby that is bundled in the WAR file, but I have not spent enough time looking in to it to figure out how. Has anyone had success with this?

Tuesday, January 17, 2012

Compiling Rails project for distribution in a WAR file with JRuby

I recently started using JRuby for a Rails project and overall the experience has been excellent.  Using RVM, you can just switch to jruby to build a new project (rvm use jruby), and just about everything will work the same.  One of the big features of JRuby is that you can bundle your entire app, including JRuby itself, in to a WAR file that Java servers like Tomcat and Glassfish can serve up, so your app can be distributed on to servers that only have Java.

After you have JRuby installed, simply install the gem warbler.  You'll then get a command line tool, warble, to generate war files from your project.  Simply run warble from your project's directory, and a war file will be produced.  It's as easy as that!

Another great feature is that the Ruby code can be compiled down to Java class files, so your source code is not visible.  This is great for distributing on to a server where other companies will have access that you don't want seeing your source code.  However, this is not working for me.  Warbler should support this, just run "warble compiled war" from the command line in your projects directory instead of "warble".  This will produce a war file with both .rb and .class files.  The .rb files however are simply stubs that require the .class file, none of your code is in there.  But, for me, it's not generating .class files on all of my controllers.  I've entered an issue for this at https://github.com/jruby/warbler/issues/72.


I will be making another post on how to do database migrations on the server you're deploying to.

Wednesday, January 4, 2012

Rails 3.1 "Could not find a JavaScript runtime" error

I just got my first Rails 3.1 on JRuby project created.  However I keep getting the error "Could not find a JavaScript runtime ..." when trying to do pretty much anything with it.  After digging in to this some, it turns out that with the addition of CoffeeScript in 3.1, Rails needs to run Javascript code natively.  A gem called execjs was added to Rails to allow this.  EXCEPT, execjs itself needs something else to actually evaluate the Javascript.    See https://github.com/sstephenson/execjs for a list.  If you're running in Mac or Windows, you're good, there are system libraries to do it.  But if you're in Linux, unless you have node.js installed, it won't work.

Let me repeat that.  Rails 3.1 apps by default will NOT work in Linux, unless you have node.js installed.  This is absolutely ridiculous... guess what Rails team, a lot of people are developing in Linux and not Mac.  I understand how stuff not working in Windows is released, but Linux??

So to get things to work you'll need to add one of the gems listed on the execjs page.  If you're running the MRI Ruby, just add:

to your Gemfile.  I've read a lot of complaints about therubyracer.  But it appears to be the most popular.  If you're running JRuby like me, add:

to your Gemfile.  I've verified that this works correctly.

FOLLOW UP 1/13/2012:
See my comments.  I have made a fix to Rails to put the appropriate gem in the Gemfile if you are in Linux, and issued pull requests to the Rails core to incorporate this code.  They have made some comments on it, hopefully it will be pulled in to Rails soon.

Thursday, December 22, 2011

Fixing FBML Facebook apps that use Facebooker

If you've written an FBML Facebook app using the Facebooker (not Facebooker2) library for Ruby on Rails, I'm sure you've noticed by now that it's not working any more. In early to mid November, Facebook changed the way they send requests to all canvas apps (FBML and iFrame). Previously, Facebook would send a bunch of parameters called fb_sig_... where each parameter represented something, like the ID of the user. Then there was an fb_sig parameter which you could use with your secret key to validate that the request came from Facebook. The Facebooker plugin/gem is coded to use this.

In early/mid November they switched to using a single parameter, signed_request. This contains all of the info encoded as JSON, along with a validation signature. They no longer use a "session" to grant access, access is now granted with an OAuth2 key.

Unfortunately if you're still using the original Facebooker library like me, you've got some work on your hands to get your app back to a working state. I'll describe everything I did to get my app working again here.

Install Facebooker2 as a plugin
Development on the Facebooker plugin stopped long ago, the original maintainer started a new Facebooker2 plugin/gem. Unfortunately Facebooker2 doesn't have support for all of the FBML capabilities. There are some similarities between the two but overall Facebooker2 was designed to be MUCH simpler and easier to use, and it definitely is. To put Facebooker2 in your project:
  1. Download Facebooker2 to your vendor/plugins directory
  2. Install the mogli and ruby-hmac gems (how you do this depends on your Rails version, either install it on to the system, specify it as a required gem in your environment.rb file, etc.)
  3. Download the original Facebooker gem/plugin to your lib folder (or just copy it from your vendor folder if you put the code in your project previously).
  4. Edit your config/facebooker.yml file, and change secret_key to secret for your environments.
  5. Edit config/facebooker.yml, and add an app_id property to each environment for your App ID (which can be viewed from the Facebook app page for your app).
  6. Create a file config/initializers/facebooker2.rb and put a single line of code in it:


Modify your ApplicationController
Now that you've got Facebooker2 installed, you'll have to modify your code to use it instead of Facebooker. Modify your ApplicationController to include this code:

Now that you've got this in place, you'll have to edit the rest of your code.

Client and User
Instead of using facebook_session and facebook_session_secured, you'll want to call the methods current_facebook_user and current_facebook_client. current_facebook_user will return a Mogli::User object. Here is some code showing some of the common things you may want to do:


Facebooker Helpers
To include all of the FBML helpers that the Facebooker library includes, add the following code to your application_helper.rb:


You'll also need to make a few changes to the Facebooker helper file. Edit lib/facebooker.../lib/facebooker/rails/helpers.rb and add the following:


Views
If you have named your view files .fbml.erb, you'll need to rename them to just .erb. The .fbml type isn't registered with Facebooker2.

Publishing Stories
Facebooker had this whole publisher syntax to post stories to the users wall. None of this is necessary any more. If you wish to publish stories to a users wall, as long as the user has granted the offline_access permission to your app, do the following:


OK I think that's all there is to it. I have my Facebook app working with these changes.

The Future of FBML
You probably know that Facebook is completely abandoning FBML on June 1, 2012. Converting your app as I described here gives you some time to convert your app's views over to iframe instead of FBML. However, don't be surprised if stuff stops working before then. For instance, I can't get my app to display with https. I'm doing everything correctly but Facebook appears to not support this. Hopefully this blog post will give you some breathing time before June.

Saturday, December 3, 2011

Verifying Facebook's signed_request in Ruby

Facebook's signed_request parameter can be quite complicated to parse in Ruby. Facebook's examples are of course entirely in PHP. signed_request is their new way of delivering data to your app instead of individual fb_sig_ parameters for everything. Here is the code to properly verify the signed_request parameter, and return a hash with all of the data from the request. Just call parse_signed_request passing the received params from the HTTP request, and your app's secret key (issued by Facebook). An exception will be thrown if verification fails, otherwise, you'll get a hash of the data back.

Friday, November 11, 2011

Better way to format code for blog posts

Back when I made my post Formatting Ruby and HTML code for blog posting, I missed out on on much better way to post code. I just recently found the SyntaxHighlighter project. This makes posting code snippets on blogs so much easier, no need to run your code through a script to convert it. Simply paste the code you wish to post as is into a special script HTML tag.

To use SyntaxHighlighter, go in to your blog settings, click Design, then click Edit HTML. In the box below, right before the </head> tag, insert the following code:

<link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"></link>
<link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"></link>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shAutoloader.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js" type="text/javascript">
</script>

<script type="text/javascript">
//<![CDATA[
SyntaxHighlighter.all();
//]]>
</script>

This will load the default code highlighting for Javascript, XML, and Ruby. SyntaxHighlighter has 30 different languages, you'll have to add support for these manually. I'll explain this later.

Now to actually put a code snippet in your blog post, click the Edit HTML section. Add the following where you want your code snippet to show up. In this example I'll use Javascript:

<script class="brush: js" type="syntaxhighlighter">
<![CDATA[
  // Put your code here, an example is below.

  function foo()
  {
      if (counter <= 10)
          return;
      // it works!
  }
]]>
</script>
Here is what it will look like on your blog:


So just put a script tag like above with a type of syntaxhighlighter. The class is important. brush: js tells it to use Javascript syntax highlighting. If we wanted XML/HTML, simply put the class as brush: xml. For Ruby, put brush: ruby as the class.

To use other language syntax highlighting, you'll have to add a script tag for the language. The src is the same, /pub/sh/current/scripts/shBrushxxx.js. Some common types are Python, Java, Scala, Cpp, CSharp, Css, Plain, Sql, etc. Download SyntaxHighlighter to see the full list.

A few things to note. If you are heavily using this, you should download the files and put them on your own server. Alex Gorbatchev is hosting the files on his server out of kindness, so if you want to heavily use it, either donate to him so he can pay his server bills or put them on your own server.

Also, I couldn't get the examples on the official site using the autoloader to work for me. That's why I've added specific script tags for each brush in my examples.

A big thanks to Alex for writing SyntaxHighlighter!

Sunday, October 23, 2011

New blog for Scala and Lift

I've started learning the language Scala and the web framework built with it, Lift.  I've set up a blog for this, Brent's Scala and Lift Posts.

I'm going to hold off on making any final judgments until I've written some real things in both.  But so far I'm really liking Scala and Lift. If you haven't looked in to them, I would recommend you at least give Scala a quick look over.  Even if you don't ever intend to use it for your main web app, it can be great for back end processing jobs, as concurrency is built in to the language.  And, if like me you work on some projects that can only be distributed to customer's systems that only run the JVM, Scala is built right on top of Java.  Sometimes JRuby will allow you to distribute on to the JVM, but you don't always get the newest and best running JRuby.