Jruby、JDBC、Netezza

发布于 2024-11-10 00:21:13 字数 2472 浏览 0 评论 0原文

不管怎样,我有一个像这样的java程序,它完全可以工作。

1 import java.sql.*;
2 import org.netezza.*;

class Conn {
 public static void main (String args []) throws SQLException {
  6         try{Class.forName ("org.netezza.Driver");
  7         }
  8         catch (ClassNotFoundException e) {
  9             System.out.println("You made it to here");
 10             e.printStackTrace();
 11         }
 12
 13         Connection conn = DriverManager.getConnection("jdbc:netezza://server/dbname", "user", "pass");
 14
 15         Statement stmt = conn.createStatement();
 16         ResultSet rset = stmt.executeQuery("SELECT 'foo'");
 17         while (rset.next()){
 18             System.out.println(rset.getString(1));
 19         }
 20         stmt.close();
 21         conn.close();
 22     }
 23 }

然而,当我尝试遵循互联网上的每一个普通 JDBC + Jruby 教程时,我都会收到此代码中普遍存在的错误“NativeException:java.sql.SQLException:没有合适的驱动程序”。

  1 require 'java'
  2 require 'jruby'
  3 require 'nzjdbc.jar'
  4 #F = java.io.File
  5 #class_loader = JRuby.runtime.jruby_class_loader
  6 #class_loader.add_url(F.new('path').to_url)
  7 #class_loader.add_url(F.new('nzjdbc.jar').to_url)
  8
  9 include_class "java.sql.DriverManager"
 10 include_class "org.netezza.Driver"
 11
 12 p $CLASSPATH
 13 p $LOAD_PATH
 14
 15 server = 'server'
 16 databaseName = 'dbname'
 17 user = 'user'
 18 pass = 'pass'
 19
 20 p DRVRMAN = org.netezza.Driver.new
 21
 22 begin
 23     #clazz = Java::JavaClass.for_name("org.netezza.Driver")
 24     clazz = java.lang.Class.for_name("org.netezza.Driver", true, JRuby.runtime.jruby_class_loader)
 25     #java.lang.Thread.currentThread.setContextClassLoader(JRuby.runtime.jruby_class_loader)
 26     #java.sql.DriverManager.registerDriver(Java::OrgNetezza::Driver.new)
 27     url = "jdbc:netezza://" + server + "/" + databaseName
 28     p url
 29     conn = DriverManager.getConnection(url, user, pass)
 30     stmt = conn.create_statement
 31     rs = stmt.execute_query("SELECT 2 + 2")
 32
 33     while rs.next
 34         p [rs.get_int(1)]
 35     end
 36 ensure
 37     rs.close rescue nil
 38     stmt.close rescue nil
 39     conn.close rescue nil
 40 end

我已经尝试了所有我能找到的方法来解决这个问题,包括检查 activerecord-jdbc 和 dbi-jdbc 实现。这非常令人沮丧,我想除了类加载器、加载路径和类路径有问题之外,我真的不明白发生了什么。不管怎样,我希望有人能一步一步解释 DriverManager 如何在 Java 中注册驱动程序,以及为什么 java 代码完全成功,而 ruby​​ 代码(看起来等效)却不能帮助我减轻这些错误。

(此外,任何“安装 X gem”在这种情况下都不起作用,因为必须克服大量官僚主义才能允许任何新内容进入该系统)

So anyways I have a java program like this and it totally works.

1 import java.sql.*;
2 import org.netezza.*;

class Conn {
 public static void main (String args []) throws SQLException {
  6         try{Class.forName ("org.netezza.Driver");
  7         }
  8         catch (ClassNotFoundException e) {
  9             System.out.println("You made it to here");
 10             e.printStackTrace();
 11         }
 12
 13         Connection conn = DriverManager.getConnection("jdbc:netezza://server/dbname", "user", "pass");
 14
 15         Statement stmt = conn.createStatement();
 16         ResultSet rset = stmt.executeQuery("SELECT 'foo'");
 17         while (rset.next()){
 18             System.out.println(rset.getString(1));
 19         }
 20         stmt.close();
 21         conn.close();
 22     }
 23 }

However, when I attempt to follow what seems like every vanilla JDBC + Jruby tutorial on the internet I get the ubiquitous error "NativeException: java.sql.SQLException: No suitable driver" with this code.

  1 require 'java'
  2 require 'jruby'
  3 require 'nzjdbc.jar'
  4 #F = java.io.File
  5 #class_loader = JRuby.runtime.jruby_class_loader
  6 #class_loader.add_url(F.new('path').to_url)
  7 #class_loader.add_url(F.new('nzjdbc.jar').to_url)
  8
  9 include_class "java.sql.DriverManager"
 10 include_class "org.netezza.Driver"
 11
 12 p $CLASSPATH
 13 p $LOAD_PATH
 14
 15 server = 'server'
 16 databaseName = 'dbname'
 17 user = 'user'
 18 pass = 'pass'
 19
 20 p DRVRMAN = org.netezza.Driver.new
 21
 22 begin
 23     #clazz = Java::JavaClass.for_name("org.netezza.Driver")
 24     clazz = java.lang.Class.for_name("org.netezza.Driver", true, JRuby.runtime.jruby_class_loader)
 25     #java.lang.Thread.currentThread.setContextClassLoader(JRuby.runtime.jruby_class_loader)
 26     #java.sql.DriverManager.registerDriver(Java::OrgNetezza::Driver.new)
 27     url = "jdbc:netezza://" + server + "/" + databaseName
 28     p url
 29     conn = DriverManager.getConnection(url, user, pass)
 30     stmt = conn.create_statement
 31     rs = stmt.execute_query("SELECT 2 + 2")
 32
 33     while rs.next
 34         p [rs.get_int(1)]
 35     end
 36 ensure
 37     rs.close rescue nil
 38     stmt.close rescue nil
 39     conn.close rescue nil
 40 end

and I have tried what seems like everything I could find to fix this issue including checking out the activerecord-jdbc and dbi-jdbc implementations. Its very frustrating and I guess I don't really understand whats going on besides having an issue with teh classloader, load path and the Classpath. Anyways, I was hoping someone could explain step by step how the DriverManager registers drivers in Java and why the java code totally succeeds while the ruby code (which seems equivalent) does not as well as help me mitigate these errors.

(Also any "install X gem" won't work in this instance as a large deal of bureaucracy must be overcome for anything new to be allowed into this system)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

祁梦 2024-11-17 00:21:14

当其他所有方法都因类路径问题而失败时,我发现将 jar 放在 $JRUBY_HOME/lib 中总是有效的。

When all else fails with classpath issues, I've found that putting jars in $JRUBY_HOME/lib always works.

意犹 2024-11-17 00:21:13

我在使用 Apache CXF 时遇到过这种情况。我最喜欢的解决方案是

不要浪费时间让 jruby 代码工作
只需要一个java类就可以做到这一点
为你

,100% 保证有效。在你的情况下,你可以编译/jar你的Conn类并从jruby调用它,就像

Java::Conn.main()

你的jar可以放在jruby/lib中一样。

PS:我看到你已经尝试了很多方法来使其发挥作用。
也许 Nick Sieger 可以提供一些有关这些类加载问题的见解。

I have run into this scenario with Apache CXF. My favorite solution is to

not waste time making jruby code work
and simply have a java class do that
for you

, which is 100% guaranteed to work. In your case, you can compile/jar your Conn class and call it from jruby like

Java::Conn.main()

Your jar can be placed in jruby/lib.

PS: I see you have tried numerous ways to make it work.
Probably Nick Sieger can provide some insight into these class loading issues.

七堇年 2024-11-17 00:21:13

虽然它没有解决使用 nzjdbc.jar 的具体问题,但我可以告诉您,您拥有的代码将与 postgresql.jar 一起使用,因此您的问题必须特定于驱动程序的某些怪癖。我不确定 netezza 想要做什么,但是对于 postgresql 驱动程序, org.postgresql.Driver 有一个静态初始化块,它只调用 javax.sql.DriverManager.registerDriver(new org.postgresql.Driver()),所以只需加载该类就足以注册驱动程序。

While it doesn't address the specific issue of using your nzjdbc.jar, I can tell you that the code you have will work with postgresql.jar, so your issue must be specific to some quirk of your driver. I'm not sure what netezza is trying to do, but with the postgresql driver, org.postgresql.Driver has a static initialization block that simply calls javax.sql.DriverManager.registerDriver(new org.postgresql.Driver()), so simply loading that class is enough to get the driver registered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文