Jruby,JDBC,Netezza

问题描述

| 所以无论如何,我有一个像这样的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:No适当的驱动程序”。
  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”在这种情况下均不起作用,因为必须克服大量的官僚主义才能使任何新内容进入该系统)     

解决方法

我已经在Apache CXF中遇到了这种情况。我最喜欢的解决方案是   不浪费时间使jruby代码工作   并简单地有一个Java类来做到这一点   为了你 ,这100%保证可以正常工作。就您而言,您可以编译/打包您的Conn类,然后从jruby调用它,例如
Java::Conn.main()
您的jar可以放在jruby / lib中。 PS:我看到您尝试了许多方法来使其工作。 尼克·西格(Nick Sieger)可能可以提供有关这些类加载问题的一些见解。     ,尽管它不能解决使用nzjdbc.jar的特定问题,但我可以告诉您,您拥有的代码将与postgresql.jar一起使用,因此您的问题必须特定于驱动程序的某些问题。我不确定netezza打算做什么,但是对于PostgreSQL驱动程序,org.postgresql.Driver有一个静态初始化块,该块仅调用javax.sql.DriverManager.registerDriver(new org.postgresql.Driver()),因此,只需加载该类就足以使驱动程序注册。     ,当其他所有问题都因类路径问题而失败时,我发现将jar放在$ JRUBY_HOME / lib中始终有效。