boiling memoir

journey of one man

WARNING: Nokogiri Was Built Against LibXML Version 2.7.3

Upgraded to Mountain Lion and started getting the above warning when using nokogiri.

It is happening because OSX has a default libxml2 in /usr/lib/libxml2.2.dylib

But the libxml2 headers used during nokogiri compilation are the ones in /usr/include/libxml2. nb.I don’t use macport or homebrew.

So /usr/include/libxml2 is version 2.7.3 which you can see by looking inside libxml/xmlversion.h

To get rid of the warning in nokogiri I needed to get matching headers for libxml2 2.7.8, so I downloaded Extracted it somewhere in my home folder (where I kept all the source files), sudo mv /usr/include/libxml2 /usr/include/libxml2-2.7.3 then symlink my extracted libxml2-2.7.8/include to /usr/include/libxml2

Ruby on Rails & Sybase

This was my notes many years ago of getting Ruby on Rails to run on Sybase. It is no doubt out-of-date by now. But still an interesting read for me, kind of like reading an old diary.

I have been trying to learn how to get Rails to work with Sybase for a while because Sybase is predominantly the database at my work.

Since I am not exactly free nor allowed to spend chunks of my time working on this stuff at work I haven’t had much success. For some reason, there isn’t as much resource on getting Rails to work with Sybase compared to MySQL or PosgreSQL.

So every now and then I’d research a bit to see if anything new in the field comes up that might help. On one such research I found on Sybase Rails wiki It is the instructions for Suse 7.3, and during my research I learn that I can install Sybase on OS X so I thought it was worth to give the instructions a try.

Overall the process wasn’t too bad, I skipped step 4 & 5 (but later I had to setup SYBASE environment, something complained about it). Also was quite lucky the extconfig.rb (step 7) in Ruby Sybase Library already contains a commented out section for OS X configuration (it was written for Panther but it worked for me on Tiger). I can’t remember for sure if step 7 was when I was faced with the problem of missing libraries but either way I was able to find the missing library name and got the answer (I picked the Symbolic Links solution).

cd /usr/libsudo 
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybtcl.dylib libsybtcl.dylibsudo
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybdb.dylib libsybdb.dylibsudo 
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybintl.dylib libsybintl.dylibsudo 
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybct.dylib libsybct.dylibsudo 
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybcs.dylib libsybcs.dylibsudo 
ln -s /Applications/Sybase/System/OCS-12_5/lib/libsybcomn.dylib libsybcomn.dylib

After step 7 (create Makefile & compile by running make) I tested Ruby Sybase Library in the local folder by running sqlsample.rb against Sybase and it all worked so things were looking promising.

However step 8 expects step 7 to have created 4 files which are to be installed in system directory (any ruby load path). But since it had already passed the test I didn’t think too much of it and just copied the only 3 out of 4 files that I could find, created a new project (running on edge rails) configure database.yml to run against sybase adapter then test it using script/console. Unfortunately that wasn’t enough. What made it worse was that the error message was really not helpful because it said “database configuration specifies nonexistent sybase adapter”, by running console with –trace I found the line that raised the error and the condition that caused the error. I was still confused after I found the line because it was testing if the class has a method called sybase_connection, which I knew for sure existed in sybase_adapter.rb. After a while I finally noticed that sybase_adapter.rb starts a begin block then require ‘sybsql’ (which is one of the 3 files I installed) and that require statement is throwing an error which is rescued right at the end of the file and the catch block doesn’t do anything (no logging of any sort). So after I modified it to printed out the error, I finally found out the real reason why sybase adapter isn’t loaded properly.

The error turned out to be “unable to load sybct.o”. The error seems strange because I already tested the library with sqlsample.rb so something that was in the local library directory when running sqlsample.rb is also needed to be installed in system directory. A couple of trial and error the 4th file that is needed turns out to be sybct.bundle. After installing that file I finally got rails to run on Sybase, wahoo!!!

I grew a bit more comfortable about ActiveRecord during this experience, get to install Sybase locally (so I’ll get a chance to learn about Sybase admin functions) and get a little bit closer to getting Rails to work with Sybase at work :)

The ClearCase Effect

A while ago I had the pleasure of experiencing working with ClearCase, NOT!

I made a few notes on how it affected me and as far as I could tell, the team.

Not updating your own codebase often because

  • update is damn slow
  • risk of codebase not compiling after update as checked out/hijacked files are not updated

Lots of CruiseControl failures were due to

  • accidental checkin files before they are complete when refactoring or creating new files
  • newly created files not checked in

CruiseControl failures de-sensitised the team

  • people stop caring/responding to build failures making CI less useful
  • reduced team moral

The above issues are avoidable but:

  • it is not suppose to be this hard
  • workflow using ClearCase is not efficient and optimised for developers
  • what are the benefits with keep using ClearCase that prevented the team from moving away from it?

Also some general issues with ClearCase

  • it is not a tool that many people know and know it well to use it efficiently
  • it is not a tool to attract/retain staff
  • developers were just not happy using it

Grails, Spring-ws, SOAP & HTTP Request’s Content Type

If you ever have to use Grails to process a fucked up SOAP request with a content type of application/x-www-form-urlencoded then this post is for you.

p.s. eventually we will stop processing that kind of requests but for now we need it to work so client has time to fix their shit up

Problem with application/x-www-form-urlencoded requests & spring-ws’ message factory is that it does not like requests with that content type. Rightly so!

The message factory content type issue is obvious since the exception that it throws at you is pretty self-explanatory. The work-around is pretty easy, define your own messageFactory spring bean that is more lenient on the content type.

But after the content type is sorted you would face the second problem “Premature end of file”. It took me a while to figure out what is happening. In retrospect it is actually quite logical. The end of file is referring to the request’s input stream which has been consumed by Grails filters before it gets to the message factory. The following filters are responsible for parsing the request and routing, luckily they are also subclasses of OncePerRequestFilter which means you can easily bypass them to avoid input stream been consumed.

  1. grailsWebRequest
  2. urlMapping
  3. hiddenHttpMethod

How to Use Groovy Categories in Gsp’s

You use Groovy categories in a canonical way in gsp’s. i.e. by surrounding all your gsp code inside a call to

<% use(YourCategoryClass) { %>
<% } %>

But it gets troublesome quite soon, especially if the main gsp renders other partial templates.

Luckily there is a way to hook into the view rendering workflow. The trick is to provide your own implementation of View that invoke the call to use categories around the view.render method. To do that you also need to override the default jspViewResolver spring bean with your own implementation of ViewResolver which uses your own implementation of View. Lastly if you need dynamically decide what categories classes to use then you can pass it in the model attribute inside your controller.

The result will look something like this.

Convert GPathResult to String Without Tag0

In Groovy, you can use the follow code to convert node to XML String.

groovy.xml.XmlUtil.serialize(GPathResult node)

But sometimes the XML you end up with contains tag0 namespace all over
the elements. It happens because the doc contains default namespace
with empty prefix, so groovy uses a default prefix which is “tag0”.
The XML is still correct but it would be nice to not have to see that
crap. To do so you need to create a new closure with the node and
explicitly declare an empty string namespace. Then use
StreamingMarkupBuilder to convert the newly created closure to String.
The following code is how you would implement that logic.

Overwrite Inploy App Servers’ Restart Command

Inploy is a rails deployment solution. It comes with integration to restart 4 app servers:

  • mongrel
  • passenger
  • thin
  • unicorn

I needed a way to change how Inploy restarts passenger since our passenger’s restart file is at a different location.

I could’ve changed the command inside Inploy’s passenger.rb but I wanted to avoid that as there’s good chance that someone in the future won’t know to re-apply the change when they upgrade Inploy. So I needed a way to monkey patch Inploy’s passenger module. My first attempt was to create my version of the Passenger module and require the file in rails’ environment.rb. That was no good because Inploy’s update command does not seem to bootstrap the whole rails environment so my override simply wasn’t getting loaded.

I had to find another way in to load my module for the deployment process. It turns out the solution I was looking for is in rake. Since Inploy’s update is just a rake task, I could create a passenger.rake in Rails.root/lib/tasks and define my restart_server override inside my custom passenger.rake. Please let me know if there is a better / proper way to achieve what I needed. Otherwise hope this helps someone else.

My Shortcut to Open Any Gem in TextMate With 1 Command

Using the implementation from @peepcode’s blog on shell method missing as a base. I have added another action (code snippet below) to open a gem library in TextMate by typing in the name of the gem followed by “.mate”.

when /^[A-Za-z0-9_\-\/]+\.mate$/
  # Open the gem in textmate
  # @example
  #   haml.mate
  gem_to_open = command.first.gsub(/\.mate$/, '')
  run "gem which #{gem_to_open} | tail -1 | xargs dirname | sed -e's/$/\\/../' | xargs mate"

Download Sources Jar From Maven

We use Maven, when Maven downloads dependencies it doesn’t download sources, which I rely on when learn and debug programs….
I was expecting, for what seem a simple thing to me, a flag that I can add in maven’s settings files or an option to pass to mvn command…. but I couldn’t find the solution (or anything close to it). Don’t get me wrong, there are solutions out there, but I just feel it is too much hassle for the task. So I wrote a little script that go thru my repo and downloads any jar that doesn’t have its respective sources :p