2012-10-19 17 views
5

Mam następujący kod Java. Celem tego kodu jest ustanowienie połączenia do zdalnej bazy danych MySQL ProductionDb (źródło danych zdefiniowane w pliku /etc/odbc.ini).Źródło danych ODBC Java (niezdefiniowany 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()); 
     } 
    } 

} 

Plik /etc/odbc.ini jest:

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

przy okazji - używam Java 7 i 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 

Kiedy próbuję uruchomić mój program Pojawia się następujący błąd:

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

D Ktoś wie, dlaczego dostaję ten błąd? Co jest nie tak?

PS Nawiasem mówiąc ja nie uruchamiać sudo apt-get install unixodbc-dev sudo apt-get install libmyodbc i sudo apt-get install libmysql-java :-)

UPDATE:

Próbowałem również pomysł sugerowany w jednej z odpowiedzi poniżej (Benny Hill): do korzystania z /etc/odbcinst.ini, a także /etc/odbc.ini. Nadal nie działa i pojawia się ten sam komunikat o błędzie.

$ 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 

DODATKOWE UWAGA:

mogę użyć tego źródła danych ODBC z powodzeniem od języka programowania R .

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

Czy istnieje powód, dla którego nie używasz sterownika JDBC MySQL? – beny23

+0

Czy miałeś okazję przyjrzeć się temu, aby sprawdzić, czy twój sterownik JDBC/ODBC próbuje użyć niewłaściwego pliku .so? –

+0

Jeszcze nie .. zajęty .. czekaj na :-) spokój i okrzyki! – MadSeb

Odpowiedz

2

Brzmi jak brakujący lub niedopasowane bibliotece. Spróbuj debugować przetwarzanie ldd.

Po pierwsze, sprawdź, co

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

mówi, istnieją wszystkie wymienione zależności?

Następnie spróbuj ustawić LD_DEBUG i ponownie uruchom program Java, aby zobaczyć debugowanie programu ładującego.

$ export LD_DEBUG=all 
$ java Test 
6

Błąd jest wynikiem libJdbcOdbc.so szuka funkcji „SQLAllocEnv” w inny .so i nie znajdując go. Sposobem debugowania jest uruchomienie polecenia: ldd /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so. To pokaże ci listę połączonych obiektów .so i ich lokalizację.

Ogólnie rzecz biorąc powinny one znajdować się w katalogu/usr/lib, ale jeśli sam skompilowałeś jakieś oprogramowanie, niektóre z tych bibliotek mogą znajdować się w katalogu/usr/local/lib lub w innej lokalizacji. Jeśli masz coś, co pokazuje się w/usr/local/lib, to jest możliwe, to właśnie jest przyczyną twojego problemu. Aby przetestować, zmień nazwę biblioteki w/usr/local/lib na coś innego (sudo mv /usr/local/lib/mylib.so /usr/local/lib/mylib.so.SAVE).

Teraz uruchom program i sprawdź, czy nadal występuje ten sam błąd. Jeśli to rozwiąże twój problem, to świetnie! Jeśli nie, daj nam znać, jeśli otrzymasz ten sam komunikat o błędzie lub otrzymasz nowy.

spodziewałbym plik ODBC.INI wyglądać tak:

[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 

a plik ODBCINST.INI wyglądać tak:

[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 

Mój przykład pokazuje mój setup na pilocie iSeries, ale jestem pewien, że widzisz, co musisz zmienić w MySQL.

Mianowicie linia odbc.ini "Driver = ..." jest błędna. Powinno to być coś w stylu "Driver = mysql", a następnie musisz zdefiniować [mysql] w swoim pliku odbcinst.ini.

0

Jako obejście i jeśli SQLAllocEnv jest zdefiniowana w /usr/lib/odbc/libmyodbc.so można spróbować wymusić ładowanie przed użyciem JDBC

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

Użyłem MySQL z JDBC wcześniej, a najprostszym sposobem, wiem, aby połączyć się przy użyciu Connector/J, który jest oficjalnym sterownik MySQL. Będzie działać tak samo, jak sterownik ODBC i nie wymaga natywnych rzeczy, które mogą być przyczyną problemu.

Pobierz sterownik stąd: http://dev.mysql.com/downloads/connector/j/

Docs na powyższej stronie.

Docs Jak podłączyć: http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-connect-drivermanager.html#connector-j-examples-connection-drivermanager

+0

@MarchingHome Pytający podał cel swojego pytania, a ja Otrzymałem praktyczną, doświadczoną odpowiedź, aby osiągnąć dokładnie tę samą funkcjonalność.Wiem, że ludzie próbują używać sterowników ODBC, kiedy tylko mogą i myślę, że powinni (wydajność, specyficzna funkcjonalność JDBC) używać oficjalnych JDBC. – Tom

+0

Masz rację. Mój błąd :) – MarchingHome

2

Przejdź do katalogu:

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

i zmień nazwę pliku libJdbcOdbc.so do libJdbcOdbcXXX.so

Ten pracował dla mnie.

3

Aby rozwiązać ten problem należy dodać następujące do skryptu startowego lub profilu:

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

Twoja ścieżka może różnić się nieco, dla mnie pliki .so gdzie w/usr/lib64.

"Istnieje błąd związany z tym, że biblioteki" libodbc.so "i" libodbcinst.so "libJdbcOdbc.so nie są ładowane z biblioteki, która implementuje mostek JDBC-ODBC."

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

0

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

raz zdefiniować to w .bash_profile, źródło to i to działa dobrze dla mnie.

Powiązane problemy