2012-10-19 3 views
5

Ich habe den folgenden Java-Code. Zweck dieses Codes ist es, eine Verbindung zu einer entfernten MySQL-Datenbank ProductionDb herzustellen (eine Datenquelle, die in meiner Datei /etc/odbc.ini definiert ist).Java-ODBC-Datenquelle (undefiniertes Symbol: SQLAllocEnv)

import java.sql.*; 
import java.util.*; 
import java.io.*; 

public class Test { 

    public static void main(String[] args) { 

     try { 
      Connection conn = null; 
      PreparedStatement s = null; 
      String driver = "sun.jdbc.odbc.JdbcOdbcDriver"; 

      Class.forName(driver).newInstance(); 
      conn = DriverManager.getConnection("jdbc:odbc:ProductionDb"); 

     } catch (Exception ex) { 
      System.out.println(ex.getMessage()); 
     } 
    } 

} 

Die /etc/odbc.ini Datei ist:

$ cat /etc/odbc.ini 
[ProductionDb] 
Driver = /usr/lib/odbc/libmyodbc.so 
Description = Production Database 
Server = [ hidden ] 
Port = 3306 
User = [ hidden ] 
Password = [ hidden ] 
Database = ProductionDb 

By the way - ich bin mit Java 7 und Ubuntu:

$java -version 
    java version "1.7.0_09" 
    Java(TM) SE Runtime Environment (build 1.7.0_09-b05) 
    Java HotSpot(TM) 64-Bit Server VM (build 23.5-b02, mixed mode) 

$lsb_release -a 
    No LSB modules are available. 
    Distributor ID: Ubuntu 
    Description: Ubuntu 11.04 
    Release: 11.04 
    Codename: natty 

Wenn ich versuche, mein Programm zu laufen Ich erhalte den folgenden Fehler:

$java Test 
java: symbol lookup error: /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so: undefined symbol: SQLAllocEnv 

D weiß jemand, warum ich diesen Fehler bekomme? Was ist hier falsch?

PS Übrigens ich sudo lief apt-get unixodbc-dev installieren, sudo apt-get libmyodbc und sudo apt-get install :-) libmysql-java installieren

UPDATE:

Ich habe auch die in einer der folgenden Antworten (von Benny Hill) vorgeschlagene Idee ausprobiert: die /etc/odbcinst.ini sowie /etc/odbc.ini zu verwenden. Funktioniert immer noch nicht und ich bekomme die gleiche Fehlermeldung.

$ cat /etc/odbc.ini 
    [ProductionDb] 
    Driver = MySQL Driver 
    Description = Production Database 
    Server = [ hidden ] 
    Port = 3306 
    User = [ hidden ] 
    Password = [ hidden ] 
    Database = ProductionDb 

$ cat /etc/odbcinst.ini 
    [MySQL Driver] 
    Driver = /usr/lib/odbc/libmyodbc.so 

ZUSÄTZLICHE ANMERKUNG:

kann ich diese ODBC-Datenquelle verwenden, erfolgreich von der R Programmiersprache.

> library(odbc) 
> con = odbcConnect("ProductionDb") 
> con 
RODBC Connection 1 
Details: 
    case=nochange 
    DSN=ProductionDb 
+6

Gibt es einen Grund, warum Sie keinen MySQL JDBC-Treiber verwenden? – beny23

+0

Hatten Sie die Möglichkeit, dies zu überprüfen, um festzustellen, ob Ihr JDBC/ODBC-Treiber versucht, die falsche .so-Datei zu verwenden? –

+0

Noch nicht ..habe beschäftigt ..hang an :-) Ruhe und Prost! – MadSeb

Antwort

2

Klingt wie eine fehlende oder nicht übereinstimmen Bibliothek. Versuchen Sie, die ldd-Verarbeitung zu debuggen.

Prüfen Sie zunächst, was

$ ldd /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so 

sagt, nicht alle aufgelisteten Abhängigkeiten bestehen?

Dann versuchen Sie LD_DEBUG und starten Sie Ihr Java-Programm erneut, um den Loader debuggen zu sehen.

$ export LD_DEBUG=all 
$ java Test 
6

Der Fehler ist das Ergebnis libJdbcOdbc.so sucht die Funktion „SQLAllocEnv“ in einer anderen .so und findet es nicht. Der Debug-Vorgang besteht darin, den Befehl ldd /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so auszuführen. Das zeigt Ihnen eine Liste der verknüpften .so-Objekte und deren Speicherort.

Im Allgemeinen sollten sie in/usr/lib sein, aber wenn Sie selbst eine Software kompiliert haben, können Sie feststellen, dass sich einige dieser Bibliotheken in/usr/local/lib oder an einem anderen Ort befinden. Wenn Sie etwas haben, das in/usr/local/lib auftaucht, ist das möglich, was Ihr Problem verursacht. Um das zu testen, benennen Sie die Bibliothek in/usr/local/lib in etwas anderes um (sudo mv /usr/local/lib/mylib.so /usr/local/lib/mylib.so.SAVE).

Jetzt führen Sie Ihr Programm und sehen, ob Sie immer noch den gleichen Fehler erhalten. Wenn das dein Problem behebt, dann großartig! Wenn nicht, lassen Sie uns wissen, wenn Sie die gleiche Fehlermeldung erhalten oder wenn Sie eine neue erhalten.

Ich würde erwarten, dass Ihre odbc.ini Datei wie folgt aussehen:

[primary] 
Description    = primary 
Driver     = iSeries Access ODBC Driver 
System     = XXX.XXX.XXX.XXX 
UserID     = XXXXXXXXXX 
Password    = XXXXXXXXXX 
Naming     = 0 
DefaultLibraries  = QGPL 
Database    = XXXXXXXXXX 
ConnectionType   = 0 
CommitMode    = 2 
ExtendedDynamic   = 0 
DefaultPkgLibrary  = QGPL 
DefaultPackage   = A/DEFAULT(IBM),2,0,1,0,512 
AllowDataCompression = 1 
LibraryView    = 0 
AllowUnsupportedChar = 0 
ForceTranslation  = 0 
Trace     = 0 

Und Ihre odbcinst.ini Datei wie folgt aussehen:

[iSeries Access ODBC Driver] 
Description  = iSeries Access for Linux ODBC Driver 
Driver   = /usr/lib/libcwbodbc.so 
Setup   = /usr/lib/libcwbodbcs.so 
NOTE1   = If using unixODBC 2.2.11 or later and you want the 32 and 64-bit ODBC drivers to share DSN's, 
NOTE2   = the following Driver64/Setup64 keywords will provide that support. 
Driver64  = /usr/lib/lib64/libcwbodbc.so 
Setup64   = /usr/lib/lib64/libcwbodbcs.so 
Threading  = 2 
DontDLClose  = 1 
UsageCount  = 1 

Mein Beispiel zeigt mein Setup für eine Remote iSeries aber ich bin sicher, dass Sie sehen können, was Sie für MySQL ändern müssten.

Nämlich Ihre odbc.ini "Driver = ..." Zeile ist falsch. Es sollte etwas wie "Driver = mysql" sein und dann müssen Sie [mysql] in Ihrer odbcinst.ini Datei definieren.

0

Als Abhilfe können und wenn SQLAllocEnv in definiert ist /usr/lib/odbc/libmyodbc.so Sie könnten versuchen, es zu erzwingen Laden vor JDBC mit

try { 
     System.load("/usr/lib/odbc/libmyodbc.so"); 
    } catch (UnsatisfiedLinkError e) { 
     e.printStackTrace(); 
    } 
2

Ich habe vor MySQL mit JDBC verwendet, und der einfachste Weg, ich weiß, ist die Verbindung mit Connector/J, die die offizielle MySQL-Treiber ist. Es wird dasselbe wie Ihr ODBC-Treiber tun und benötigt keine nativen Sachen, die Ihr Problem verursachen könnten.

Holen Sie sich den Treiber von hier: http://dev.mysql.com/downloads/connector/j/

Docs auf das obere Seite.

Docs wie verbinden: http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-connect-drivermanager.html#connector-j-examples-connection-drivermanager

+0

@MarchingHome Der Fragesteller gab den Zweck seiner Frage, und ich habe eine praktische, erfahrene Antwort gegeben, um genau die gleiche Funktionalität zu erreichen.Ich weiß, dass Leute versuchen, ODBC-Treiber zu verwenden, wenn sie könnten, und ich denke, sollte (Effizienz, JDBC-spezifische Funktionalität), offizielle JDBC-Treiber verwenden. – Tom

+0

Sie haben Recht. Mein Fehler :) – MarchingHome

2

Sie in das Verzeichnis:

/usr/lib/jvm/java-7-oracle/jre/lib/amd64/ 

und benennen Sie die Datei libJdbcOdbc.so zu libJdbcOdbcXXX.so

Das ist für mich gearbeitet.

3

Um dies zu beheben, den folgend zu Ihrem Startskript oder Profil hinzufügen:

export LD_PRELOAD=$LD_PRELOAD:/usr/lib/libodbc.so:/usr/lib/libodbcinst.so 

Ihr Weg für mich kann variiert ein wenig, die .so-Dateien, wo in/usr/lib64.

"Es gibt einen Fehler aufgrund der Tatsache, dass die Bibliotheken" libodbc.so "und" libodbcinst.so "libJdbcOdbc.so nicht aus der Bibliothek geladen werden, die die JDBC-ODBC-Brücke implementiert."

Nach https://code.google.com/p/queryconnector/source/browse/wiki/HowToInstall.wiki?spec=svn122&r=121

0

export LD_PRELOAD = $ LD_PRELOAD: /usr/lib/libodbc.so: /usr/lib/libodbcinst.so

einmal definiere ich dies in Bash_profile, Quelle, und es funktioniert gut für mich.