jruby / activerecord-jdbc-adapter

JRuby's ActiveRecord adapter using JDBC.
BSD 2-Clause "Simplified" License
462 stars 387 forks source link

SQLite3 No suitable driver #1130

Open ccmywish opened 1 year ago

ccmywish commented 1 year ago

Hi,

I'm trying this script, but it failed. I've referred to many scripts:

  1. https://github.com/flum1025/jruby_sqlite3/blob/3c8f677b97592a81f2f4fdf38d7241f64391faf6/lib/jruby_sqlite3/jruby_sqlite3.rb#L15
  2. https://github.com/jeremyevans/sequel/blob/41e621fe1051441cf61d009bb76e3f7f7411f3b8/lib/sequel/adapters/jdbc/sqlite.rb#LL3C54-L3C54
  3. https://github.com/jruby/jruby/wiki/JDBC
    
    require 'jdbc/sqlite3'

Jdbc::SQLite3.load_driver Java::org.sqlite.JDBC

url = "jdbc:sqlite:test.db" con = java.sql.DriverManager.get_connection url

=> No suitable driver found for jdbc:sqlite3:test.db (Java::JavaSql::SQLException)



Even the https://rubygems.org/gems/jdbc-sqlite3 description said we only need `Jdbc::SQLite3.load_driver` to load the driver.

What am I missing? (I'm not interested using `sequel` or `active_record` now, I just want to try the driver directly). Thanks in advance!
enebo commented 1 year ago

@ccmywish Your script runs for me. I printed out $: to show what loaded:

require 'jdbc/sqlite3'

Jdbc::SQLite3.load_driver
Java::org.sqlite.JDBC

url = "jdbc:sqlite:test.db"
con = java.sql.DriverManager.get_connection url

statement = con.create_statement
statement.execute("create table people (id int PRIMARY_KEY)")

p $:
~/work/jruby-9.3/bin/jruby -v ../../snippets/jd.rb 
jruby 9.3.10.0-SNAPSHOT (2.6.8) 2023-01-27 e7daec594f OpenJDK 64-Bit Server VM 25.242-b08 on 1.8.0_242-b08 +jit [x86_64-linux]
["/home/enebo/work/jruby-9.3/lib/ruby/gems/shared/gems/did_you_mean-1.3.0/lib", "/home/enebo/work/jruby-9.3/lib/ruby/gems/shared/gems/jdbc-sqlite3-3.32.3.3/lib", "/home/enebo/work/jruby-9.3/lib/ruby/2.6/site_ruby", "/home/enebo/work/jruby-9.3/lib/ruby/stdlib"]

I also ran this with 9.4. I am using Linux (FC 35). The basic error is also one akin to what you would see in Java itself. If the JDBC driver for sqlite3 is not loaded into your classpath then it will give you a similar error. load_driver just tries to load the .jar file in jdbc-sqlite3.

What OS+Java are you using?

ccmywish commented 1 year ago

Hi @enebo, Thanks for your help!

I'm using JRuby on Windows.

jruby 9.4.1.0 (3.1.0) 2023-02-07 237d5fa5f4 OpenJDK 64-Bit Server VM 21-ea+12-971 on 21-ea+12-971 +jit [x86_64-mswin32]

I've changed the script a little to inspect internals:

puts require 'jdbc/sqlite3'   #=> true

Jdbc::SQLite3.load_driver
Java::org.sqlite.JDBC

url = "jdbc:sqlite:test.db"

p $:
# [
# "C:/PeaceWorkSpace/peace-home/rubylib", 
# "C:/Ruby-on-Windows/rbenv/share", 
# "C:/Ruby-on-Windows/jruby-9.4.1.0/lib/ruby/gems/shared/gems/jdbc-sqlite3-3.32.3.3/lib",   # I've checked this dir, it includes `sqlite-jdbc-3.32.3.3.jar` and `jdbc` directory
# "C:/Ruby-on-Windows/jruby-9.4.1.0/lib/ruby/3.1/site_ruby", 
# "C:/Ruby-on-Windows/jruby-9.4.1.0/lib/ruby/stdlib"
# ]

con = java.sql.DriverManager.get_connection url
#=> No suitable driver found for jdbc:sqlite3:test.db (Java::JavaSql::SQLException)

You can see, JRuby is still complaining about the driver not found. However, I can run this simpler script (via Sequel) successfully:

require 'sequel'
url = "jdbc:sqlite:test.db"
Sequel.connect(url)     # Works fine, writes a "test.db" file on the disk.

This is why I think it's the cause of my own initialization part using raw jdbc-sqlite3.

enebo commented 1 year ago

@ccmywish Interesting. So sequel is using the same gem internally but somehow loading it. I will see if I see anything on Windows but tracing through sequel execution maybe will uncover something? Not sure.

enebo commented 1 year ago

@ccmywish I tried on windows and it is not loading for me either. The jar file is loading so it doubly confusing.

bimax commented 1 year ago

Hi there,

I also see this issue with: activerecord (6.1.7.3) activerecord-jdbc-adapter (61.2 java) activerecord-jdbcsqlite3-adapter (61.2 java) jdbc-sqlite3 (3.28.0)

What I am trying to do is to make a connection from Puppet7 custom function to sqlite3 database. As long as Puppet7 is JRuby, I think I need to use JDBC adapters for Active record.

So I have Puppet7 server installed and can execure 'irb' in puppetserver environment:

irb(main):001:0> require 'jdbc/sqlite3'
=> true
irb(main):002:0> Jdbc::SQLite3.load_driver
=> true
irb(main):003:0> java.sql.DriverManager.registerDriver(org.sqlite.JDBC)
=> nil
irb(main):004:0> database_path ="/infra-db/sqlite.db"
=> "/infra-db/sqlite.db"
irb(main):005:0> connection = java.sql.DriverManager.getConnection("jdbc:sqlite:#{database_path}")
Traceback (most recent call last):
       16: from RUBY.<main>(uri:classloader:/META-INF/jruby.home/lib/ruby/gems/shared/gems/irb-1.0.0/exe/irb:11)
       15: from org.jruby.RubyKernel$INVOKER$s$rbCatch.call(org/jruby/RubyKernel$INVOKER$s$rbCatch.gen)
       14: from org.jruby.RubyKernel.catch(org/jruby/RubyKernel.java:1237)
       13: from org.jruby.RubyKernel$INVOKER$s$rbCatch.call(org/jruby/RubyKernel$INVOKER$s$rbCatch.gen)
       12: from org.jruby.RubyKernel.catch(org/jruby/RubyKernel.java:1237)
       11: from org.jruby.RubyKernel$INVOKER$s$0$0$loop.call(org/jruby/RubyKernel$INVOKER$s$0$0$loop.gen)
       10: from org.jruby.RubyKernel.loop(org/jruby/RubyKernel.java:1507)
        9: from org.jruby.RubyKernel$INVOKER$s$0$3$eval.call(org/jruby/RubyKernel$INVOKER$s$0$3$eval.gen)
        8: from org.jruby.RubyKernel.eval(org/jruby/RubyKernel.java:1091)
        7: from org.jruby.RubyKernel.evalCommon(org/jruby/RubyKernel.java:1129)
        6: from RUBY.evaluate((irb):5)
        5: from org.jruby.javasupport.JavaMethod.invokeStaticDirect(org/jruby/javasupport/JavaMethod.java:369)
        4: from org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:457)
        3: from java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498)
        2: from java.sql.DriverManager.getConnection(java/sql/DriverManager.java:270)
        1: from java.sql.DriverManager.getConnection(java/sql/DriverManager.java:689)
Java::JavaSql::SQLException (No suitable driver found for jdbc:sqlite:/infra-db/sqlite.db)
bimax commented 1 year ago

Forgot to mention I am on Centos7 :-)

dbackeus commented 9 months ago

Can reproduce the snippet posted in the PR description on MacOS 4.1.1 using jruby 9.4.5.0 (3.1.4) 2023-11-02 1abae2700f OpenJDK 64-Bit Server VM 18.0.1+10 on 18.0.1+10 +jit [arm64-darwin]