Forum: JRuby Rails on JRuby - different behavior in console and server?

Posted by Chris McCann (Guest)
on 2013-01-03 21:43
(Received via mailing list)
I'm using JRuby 1.7.1 with a Rails 3.2.9 application.  The application 
uses
Java code in a JAR file which is loaded via a 'require' statement.

When I execute some JRuby code that uses the Java classes in the rails
console things work fine.  However, when I execute that same JRuby code 
via
a Rails controller action running with "rails s" I get an error related 
to
trying to dynamically load an HSQLDB JDBC driver.

The relevant portion of the stacktrace:

Cannot create JDBC driver of class '' for connect URL
'jdbc:hsqldb:file:/private/var/folders/ww/__zw8nvj6blfn0tfgvs1gs240000gq/T/1357181247259-0/data/'
java.sql.SQLException: No suitable driver
    at java.sql.DriverManager.getDriver(DriverManager.java:264)
    at
org.apache.commons.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1437)
    at
org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
    at
org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)

Looking at the DriverManager.java source it seems that this could be a
ClassLoader issue, but I'm unsure as to what the differences are in the
Java environment when executing this code in the rails console versus 
the
rails server (which is using the Puma webserver) which might cause this
behavior.

Can anyone enlighten me on this or point me to some docs that describe 
the
differences between console and server?  Any suggestions for
troubleshooting would be much appreciated as well.

Thanks,

Chris
Posted by Anthony Juckel (Guest)
on 2013-01-03 22:22
(Received via mailing list)
What version of AR-JDBC (activerecord-jdbc-adapter and jdbc-hsqldb) are 
you
using?  We've had some "noise" in the recent releases, which may be the
culprit.
Posted by Chris McCann (Guest)
on 2013-01-03 22:25
(Received via mailing list)
Anthony,

I'm not doing any ActiveRecord stuff in the JRuby code presently, so I
don't have either of those gems installed.  The HSQLDB stuff is 
happening
way down in the Java code that I'm loading from the JAR.

Do you think adding the AR-JDBC and HSQLDB gems would make a difference
when I run under the server process?  As I said, the code works 
perfectly
when I invoke it from the console.

Cheers,

Chris
Posted by Benjamin Browning (Guest)
on 2013-01-03 23:06
(Received via mailing list)
Generally you can't rely on DriverManager to find driver classes in a 
server process. The problem is an issue related to dynamic classloaders 
and DriverManager, where DriverManager can't find any SQL drivers that 
aren't present on the JVM's boot classpath. It's best to just directly 
instantiate the relevant driver class versus using DriverManager to find 
things. This is how all the major JRuby database libraries do things as 
well - some first attempt to use DriverManager and fall back on direct 
instantiation and some just skip DriverManager entirely.

If you really want to use DriverManager, you'll have to ensure that the 
HSQLDB driver is on the JVM's classpath when it boots.

Ben
Posted by Chris McCann (Guest)
on 2013-01-03 23:20
(Received via mailing list)
Ben,

I think you're spot on with this analysis.  There is some code that
dynamically loads a "legacy" version of the HSQLDB driver as part of a
data-migration process.  I don't think that driver is on the boot 
classpath
and is only loaded if needed to do the migration.

So is there a difference between the JVM's boot classpath between 
running
"rails console" and running "rails server"?  I would love to test this
theory somehow.

I very much appreciate your help!

Chris
Posted by Chris McCann (Guest)
on 2013-01-03 23:47
(Received via mailing list)
Ben,

One other thought.  I saw this SO post:
http://stackoverflow.com/questions/11548035/jruby-...

I thought I'd try the same, but looking into it I found, I think, that 
the
HSQLDB driver is actually called org.hsqldb.jdbcDriver

And with the driver name starting in lowercase I couldn't use 
java_import
to try to add it to the classpath.  This isn't an inner class name, so 
is
there a workaround to get JRuby to gracefully handle jdbcDriver?

Chris
Posted by Chris McCann (Guest)
on 2013-01-04 00:30
(Received via mailing list)
I was able to actually get the driver loaded by using the technique in 
the
Stack Overflow post listed below.  The trick was using the Java for_name
call since JRuby wasn't happy with the lowercase jdbcDriver name that
HSQLDB uses.

The code executes properly in both rails server and console now.

Thanks for your help!

Chris
Posted by Benjamin Browning (Guest)
on 2013-01-04 00:52
(Received via mailing list)
Great - glad you it working. I don't really know the details of Puma to 
know why this specific trick works, but if you were to deploy this 
application to a Java-based server such as Tomcat, Trinidad, or 
TorqueBox you'd still hit a classloading issue with DriverManager and 
need to instantiate the drivers directly or add them to the JVM's boot 
classpath.

Ben
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.