Hi Jeremy (and everyone else),
I encountered a problem with Sequel connecting to a JDBC data source in a Rails
application running under JRuby using the Tomcat application server. The
curious thing about the error is that it didn't/doesn't appear when starting
Rails using 'script/console'. Here's the trace for your enjoyment:
org.jruby.rack.RackInitializationException: NativeException:
java.sql.SQLException: No suitable driver found for
jdbc:postgresql://localhost:5432/console?user=SOMEUSER&password=SOMEPASS
from java/sql/DriverManager.java:207:in `getConnection'
from /Users/donm/projects/sequel/lib/sequel/adapters/jdbc.rb:168:in
`connect'
from /Users/donm/projects/sequel/lib/sequel/database.rb:91:in
`initialize'
from /Users/donm/projects/sequel/lib/sequel/connection_pool.rb:91:in
`call'
from /Users/donm/projects/sequel/lib/sequel/connection_pool.rb:91:in
`make_new'
from
/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:126:in
`make_new'
from
/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:112:in
`available'
from
/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:102:in
`acquire'
... 29 levels...
from
file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/vendor/rack-1.1.0/rack/builder.rb:46:in
`initialize'
from <script>:2:in `new'
from <script>:2
at
org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:172)
at
org.jruby.rack.DefaultRackApplicationFactory.getApplication(DefaultRackApplicationFactory.java:51)
at
org.jruby.rack.SharedRackApplicationFactory.init(SharedRackApplicationFactory.java:27)
at
org.jruby.rack.RackServletContextListener.contextInitialized(RackServletContextListener.java:40)
at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3898)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:4393)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at
org.apache.catalina.core.StandardService.start(StandardService.java:516)
at
org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:250)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:433)
at org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:297)
at
org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:41)
at
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:290)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:109)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:61)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
at
org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:136)
at
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:153)
at
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:290)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:109)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:61)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
at org.jruby.ast.RootNode.interpret(RootNode.java:129)
at org.jruby.Ruby.loadFile(Ruby.java:2419)
at org.jruby.runtime.load.ExternalScript.load(ExternalScript.java:64)
at org.jruby.runtime.load.LoadService.load(LoadService.java:249)
at org.jruby.RubyKernel.load(RubyKernel.java:932)
at
org.jruby.RubyKernel$s_method_0_1$RUBYFRAMEDINVOKER$load.call(org/jruby/RubyKernel$s_method_0_1$RUBYFRAMEDINVOKER$load.gen)
at
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:180)
at
org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:176)
at
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:310)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
at
Users.donm.$_dot_rvm.gems.jruby_minus_1_dot_4_dot_0.bin.trinidad.__file__(trinidad:19)
at
Users.donm.$_dot_rvm.gems.jruby_minus_1_dot_4_dot_0.bin.trinidad.load(trinidad)
at org.jruby.Ruby.runScript(Ruby.java:628)
at org.jruby.Ruby.runNormally(Ruby.java:550)
at org.jruby.Ruby.runFromMain(Ruby.java:396)
at org.jruby.Main.run(Main.java:272)
at org.jruby.Main.run(Main.java:117)
at org.jruby.Main.main(Main.java:97)
Caused by: org.jruby.exceptions.RaiseException: NativeException:
java.sql.SQLException: No suitable driver found for
jdbc:postgresql://localhost:5432/console?user=SOMEUSER&password=SOMEPASS
at
Kernel.raise(/Users/donm/projects/sequel/lib/sequel/connection_pool.rb:94)
at
Sequel::ConnectionPool.make_new(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:126)
at
Sequel::ThreadedConnectionPool.make_new(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:112)
at
Sequel::ThreadedConnectionPool.available(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:102)
at
Sequel::ThreadedConnectionPool.acquire(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:146)
at
Sequel::ThreadedConnectionPool.sync(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:146)
at
Sequel::ThreadedConnectionPool.sync(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:101)
at
Sequel::ThreadedConnectionPool.acquire(/Users/donm/projects/sequel/lib/sequel/connection_pool/threaded.rb:74)
at
Sequel::ThreadedConnectionPool.hold(/Users/donm/projects/sequel/lib/sequel/database.rb:553)
at
Sequel::Database.synchronize(/Users/donm/projects/sequel/lib/sequel/adapters/shared/postgres.rb:336)
at
Sequel::Postgres::DatabaseMethods.server_version(/Users/donm/projects/sequel/lib/sequel/adapters/shared/postgres.rb:803)
at
Sequel::Postgres::DatasetMethods.server_version(/Users/donm/projects/sequel/lib/sequel/adapters/shared/postgres.rb:783)
at
Sequel::Postgres::DatasetMethods.select_clause_methods(/Users/donm/projects/sequel/lib/sequel/dataset/sql.rb:537)
at
Sequel::Dataset.clause_sql(/Users/donm/projects/sequel/lib/sequel/dataset/sql.rb:143)
at
Sequel::Dataset.select_sql(/Users/donm/projects/sequel/lib/sequel/dataset/actions.rb:94)
at
Sequel::Dataset.each(/Users/donm/projects/sequel/lib/sequel/dataset/actions.rb:240)
at
Enumerable.map(/Users/donm/projects/sequel/lib/sequel/dataset/actions.rb:240)
at
Sequel::Dataset.map(/Users/donm/projects/sequel/lib/sequel/adapters/shared/postgres.rb:373)
at
Sequel::Postgres::DatabaseMethods.tables(/Users/donm/projects/console/config/initializers/sequel_new.rb:26)
at
(unknown).(unknown)(/Users/donm/projects/console/config/initializers/sequel_new.rb:147)
at
Kernel.load(/Users/donm/projects/console/vendor/rails/activesupport/lib/active_support/dependencies.rb:147)
at
ActiveSupport::Dependencies::Loadable.load_with_new_constant_marking(/Users/donm/projects/console/vendor/rails/railties/lib/initializer.rb:622)
at
Rails::Initializer.load_application_initializers(/Users/donm/projects/console/vendor/rails/railties/lib/initializer.rb:621)
at
Array.each(/Users/donm/projects/console/vendor/rails/railties/lib/initializer.rb:621)
at
Rails::Initializer.load_application_initializers(/Users/donm/projects/console/vendor/rails/railties/lib/initializer.rb:176)
at
Rails::Initializer.process(/Users/donm/projects/console/vendor/rails/railties/lib/initializer.rb:113)
at
#<Class:01x170fbe75>.run(/Users/donm/projects/console/config/environment.rb:15)
at
(unknown).(unknown)(/Users/donm/projects/console/config/environment.rb:44)
at
Kernel.load(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/jruby/rack/rails.rb:44)
at
JRuby::Rack::RailsBooter::Rails2Environment.load_environment(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/jruby/rack/rails.rb:38)
at
JRuby::Rack::RailsBooter::Rails2Environment.to_app(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/jruby/rack/rails.rb:186)
at #<Class:01x26ebdfff>.new(<script>:2)
at
(unknown).(unknown)(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/vendor/rack-1.1.0/rack/builder.rb:46)
at
Kernel.instance_eval(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/vendor/rack-1.1.0/rack/builder.rb:46)
at
Kernel.instance_eval(file:/Users/donm/.rvm/gems/jruby-1.4.0/gems/jruby-rack-0.9.7/lib/jruby-rack-0.9.7.jar!/vendor/rack-1.1.0/rack/builder.rb:46)
at Rack::Builder.initialize(<script>:2)
at (unknown).new(<script>:2)
at (unknown).(unknown)(:1)
Like I said, everything goes swimmingly when running Rails normally (i.e. no
Tomcat). On a side note, I'm using Trinidad for testing which is similar to the
glassfish gem in that it gives me a Tomcat environment without needing to set
it all up. As I was trying to figure out this problem, it occurred to me that
ActiveRecord was having no problem connecting to the same database - so I went
digging through activerecord-jdbc-adapter on GitHub, and I found this:
def connection(url, user, pass)
Jdbc::DriverManager.getConnection(url, user, pass)
rescue
# bypass DriverManager to get around problem with dynamically loaded jdbc
drivers
props = java.util.Properties.new
props.setProperty("user", user)
props.setProperty("password", pass)
create.connect(url, props)
end
(Link to this portion of the adapter on GitHub:
http://github.com/nicksieger/activerecord-jdbc-adapter/blob/master/lib/active_record/connection_adapters/jdbc_adapter.rb#L253)
Looks like Tomcat/Trinidad is an environment where DriverManager isn't working
as expected. I took a stab at putting this into Sequel and here is the topic
branch for the fix: http://github.com/elskwid/sequel/tree/jdbc_fix
A quick explanation of what I did:
* Added an attr_reader for the driver as we'll need to call the connect
method on it.
* Since the driver is "returned" from the database setup procs I just grabbed
it from there
* I used some of the code from the activerecord jdbc adapter
I have no idea how I would add tests for this type of thing, so I didn't put
any in. If you have any thoughts, I will gladly work with them.
When I was poking around, I noticed the use of the opts variable in the connect
method (in Sequel) [1] On line 167 I see this:
args.concat([opts[:user], opts[:password]]) if opts[:user] && opts[:password]
But I don't see the opts being passed into the connect method.
def connect(server)
Perhaps something is missing? Anyway, I added the code that uses these options
but left it commented out as I didn't actually have an opts variable to access.
Take a look and let me know if I need to do anything more. Oh, I can make a
pull request too, if you like, and thanks for all the great work on Sequel!
Don
[1]
http://github.com/jeremyevans/sequel/blob/master/lib/sequel/adapters/jdbc.rb#L162
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sequel-talk?hl=en.