1

とにかく、私はこのような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 でドライバを登録する方法と、Ruby コード (同等のように見える) がこれらのエラーを軽減するのに役立たないのに Java コードが完全に成功する理由を、誰かが段階的に説明できることを望んでいました。

(また、このシステムに新しいものを許可するには、大量の官僚主義を克服しなければならないため、この場合、「X gem のインストール」は機能しません)

4

3 に答える 3

1

私は Apache CXF でこのシナリオに遭遇しました。私のお気に入りの解決策は

jrubyコードを機能させるのに時間を無駄にするのではなく、単にJavaクラスにそれをさせてください

、これは 100% 動作することが保証されています。あなたの場合、Connクラスをコンパイル/jarして、jrubyから呼び出すことができます

Java::Conn.main()

jar は jruby/lib に配置できます。

PS: 機能させるためにさまざまな方法を試しているようです。おそらく、 Nick Siegerがこれらのクラスのロードの問題について洞察を提供してくれるでしょう。

于 2011-05-30T02:14:44.287 に答える
0

他のすべてがクラスパスの問題で失敗した場合、$ JRUBY_HOME/libにjarを配置することは常に機能することがわかりました。

于 2011-05-29T11:51:05.947 に答える
0

nzjdbc.jar の使用に関する特定の問題には対処していませんが、コードは postgresql.jar で動作するため、問題はドライバーの癖に固有のものである必要があります。netezza が何をしようとしているのかはわかりませんが、postgresql ドライバーでは、org.postgresql.Driver には javax.sql.DriverManager.registerDriver(new org.postgresql.Driver()) を呼び出すだけの静的初期化ブロックがあるため、そのクラスをロードするだけで、ドライバーを登録できます。

于 2011-05-26T05:25:25.697 に答える