tags:

views:

299

answers:

2

I'm trying to write a script that is executed with the jruby-complete.jar like so:

java -cp derby.jar; -Djdbc.drivers=org.apache.derby.jdbc.EmbeddedDriver -jar jruby-complete.jar -S my_script.rb

I'm using JVM 1.6.0_11 and JRuby 1.4.

In my jruby script I attempt to connect to the database like this.

connection = Java::com.sql.DriverManager.getConnection("jdbc:derby:path_to_my_DB")

This throws a java.sql.SQLException: "No suitable driver found" exception.

I've tried manually loading the driver into the class loader using Class.forName which gives me the same error.

It looks like to me that the class loader being used by the DriverManager is not the same as the current thread's. I've tried setting the current thread's class loader using:

JThread = java.lang.Thread 
...
class_loader = JavaLang::URLClassLoader.new(  
  [JavaLang::URL.new("jar:file:/derby.jar!/")].to_java(
    JavaLang::URL),JRuby.runtime.jruby_class_loader)      

JThread.currentThread().setContextClassLoader(class_loader )

But this doesn't help.

Any ideas?

A: 

First, make sure your driver jar is not corrupted (this made me waste a couple of days one time).

Second, read this about JRuby/Java classloade: JRuby Wiki

Third (because I haven't played with "jruby-complete") try this simple script and then see if you can adapt as you need.

require 'java'
require 'C:\ruby\db-derby-10.5.3.0-bin\lib\derby.jar'  # adjust for your machine
include_class "java.sql.DriverManager"
derby = org.apache.derby.jdbc.EmbeddedDriver.new
connection = DriverManager.getConnection("jdbc:derby:derbyDB;create=true")
Rob
Thanks for the suggestions Rob. Your advice works if using a local install of JRuby, but it fails when using the jruby-complete.jar. The class loader situation gets a lot hairier when using jruby-complete.
Samuel Holloway
Did you try the require/include class technique (instead of using Java::JavaLang::URLClassLoader) ?
Rob
+1  A: 

OK I downloaded jruby-complete.jar and had a go....

This seems to work for me:

java -classpath c:\ruby\db-derby-10.5.3.0-bin\lib\derby.jar;jruby-complete-1.4.0.jar org.jruby.Main -S derby.rb

When using the -jar switch, the -classpath option is ignored (maybe the CLASSPATH shell var is too). But on the above line, we put both required jars on the class path and pass the class name to execute (i.e. org.jruby.Main). The script being passed in is as per my other answer.

Another option (which I have not tried) would be to alter the jruby-complete.jar manifest file to specify as classpath, as described here: Adding Classes to the JAR File's Classpath

Rob
I just tried the "edit the MANIFEST.MF" file technique and that worked to. Copy the MANIFEST.MF file out of the archive. Add the following line: Class-Path: derby.jarDelete the old MANIFEST.MF fiel from the archive. Add your edited file back in with jar.exe ufm jruby-complete-1.4.0.jar MANIFEST.MFThen you can run as follows: java -jar jruby-complete-1.4.0.jar -S derby.rb
Rob
That works great Rob. Thank you so much. This issue really drove me nuts! :)
Samuel Holloway