Tuesday, April 19, 2011

ActiveRecord JDBC adapter multiple database bug

My rails application need to two database simultaneously, one is db2 and the other is SQL server. Unfortunately I got an error called "undefined method `identity=' for". After googling, there is a bug reported here https://github.com/nicksieger/activerecord-jdbc-adapter/issues/25.

After tracing JDBC adapter source, I found the reason for my case: the class method column_types in arjdbc/jdbc/column.rb

@column_types ||= ::ArJdbc.constants.map{|c|
::ArJdbc.const_get c }.select{ |c|
c.respond_to? :column_selector }.map{|c|
c.column_selector }.inject({}) { |h,val|
h[val[0]] = val[1]; h }

Both MsSQL and DB2 are lazy loaded. When you have multiple databases, once @column_types is instantiated for db2, it will never be changed. But it is possible that MsSQL module is not loaded yet and so its column_selector is never called.

def self.column_selector
[/sqlserver|tds|Microsoft SQL/i, lambda {|cfg,col| col.extend(::ArJdbc::MsSQL::Column)}]

column_selector extends JdbcColumn with MsSQL version Column, and it defines :identity. If it is not called, "undefined method 'identity='" will be thrown.

The simple way I found to fix this issue: put the following in config/application.rb

# overcome activerecord-jdbc-adapter bug "undefined method 'identity='"
# for multiple databases by preloading the driver
if defined?(ArJdbc::Version::VERSION)
require 'arjdbc/db2'
require 'arjdbc/mssql'

Rails filters for Ajax pages

1. layout/application generate the application frame, jquery tabs
2. for each tab, the content is loaded by ajax call
3. the response of an ajax call is just a segment of html or json data
4. Need an easy way to send a request to the server just like ajax call so that I can debug the issue without load the whole page.


1. Routing .js or .html
2. ajax always asks for .js

SOLUTION 2: Filter

Rails 3 SSO using JRuby, Tomcat, and Waffle

Friday, April 15, 2011

Get JRE 6 zip

You can only find JRE installation exe file from Oracle.com. But you can extract the zip file from it.

* Download JRE installation exe file
* Launch the installation, but stop when the first dialog is shown
* Go to C:\Users\yourname\AppData\LocalLow\Sun\Java\jre1.6.0_24
* Open Data1.cab in WinRAR
* You will find core.zip.

Friday, April 8, 2011

Warbler configuration

Warbler is so simple and powerful to package all files you need for a Rails application into a war. However, you may want to customize how warbler packages the war file because you may not want to deploy a tens mega-bytes war file every time and you Rails application is very small. I just thinner my 36MB war file to 1MB by removing all slow-changed dependent jars and gems. Of course, doing so you have to have some additional steps to maintain the dependencies.

1. Three jars in WEB-INF/lib, jruby-core, jruby-rack and jruby-stdlib, use 12MB
2. All rails dependent gems may use 6MB

And all the above files are not changed too frequently.

1. How to exclude all dependent gems in war

config.gem_dependencies = false

2. How to exclude jruby jars

config.java_libs = []


Monday, April 4, 2011

SyntaxHighlighter hints

SyntaxHighlighter provides a simple method to highlight the code:


But this method is actually hooked with body's onload() event. When I use some ajax call and want to format the page dynamically, this method won't work. It is actually easy to fix that: use highlight method directly.


And default font size of SyntaxHighlighter is too small. Found this page by googling


it works, but there is an issue that the line numbers in gutter won't match the lines. You can fix this use the same font-size as below:

.syntaxhighlighter a,
.syntaxhighlighter div,
.syntaxhighlighter code,
.syntaxhighlighter table,
.syntaxhighlighter table td,
.syntaxhighlighter table tr,
.syntaxhighlighter table tbody,
.syntaxhighlighter table thead,
.syntaxhighlighter table caption,
.syntaxhighlighter textarea {
font-size: 1.01em;

.syntaxhighlighter table td.gutter .line {
text-align: right !important;
padding: 0 0.5em 0 1em !important;
font-size: 1.01em;