2012-10-19 11 views
5

Ho il seguente codice Java. Scopo di questo codice è stabilire una connessione in un database MySQL remoto ProductionDb (un'origine dati definita nel mio file /etc/odbc.ini).Origine dati ODBC Java (simbolo non definito: 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()); 
     } 
    } 

} 

Il file /etc/odbc.ini è:

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

A proposito - sto usando Java 7 e 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 

Quando provo a fare funzionare il mio programma Viene visualizzato il seguente errore:

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

D qualcuno sa perché ho questo errore? Cosa c'è di sbagliato qui?

PS A proposito ho fatto eseguire sudo apt-get install unixODBC-dev, sudo apt-get install libmyodbc e sudo apt-get install libmysql-java :-)

UPDATE:

Ho anche provato l'idea suggerita in una delle risposte seguenti (di Benny Hill): per usare /etc/odbcinst.ini e /etc/odbc.ini. Ancora non funziona e ottengo lo stesso messaggio di errore.

$ 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 

Nota aggiuntiva:

posso usare questa fonte dati ODBC con successo dal linguaggio di programmazione R .

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

C'è un motivo per cui non si sta utilizzando un driver JDBC MySQL? – beny23

+0

Hai avuto la possibilità di dare un'occhiata a questo per vedere se il tuo driver JDBC/ODBC sta tentando di utilizzare il file .so sbagliato? –

+0

Non ancora ..stato occupato ..hang on :-) pace e applausi! – MadSeb

risposta

2

Suona come una libreria mancante o non corrispondenti. Prova a eseguire il debug dell'elaborazione LDD.

In primo luogo, controllare ciò

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

dice, esistono tutte le dipendenze elencate?

Quindi, provare a impostare LD_DEBUG e avviare nuovamente il programma Java, per vedere il debug del caricatore.

$ export LD_DEBUG=all 
$ java Test 
6

L'errore è il risultato di libJdbcOdbc.so alla ricerca per la funzione "SQLAllocEnv" in qualche altro .so e non trovarlo. Il modo per eseguire il debug di questo è eseguire il comando ldd /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so. Questo ti mostrerà una lista di oggetti .so collegati e dove si trovano.

In generale, dovrebbero essere in/usr/lib, tuttavia se si è compilato qualsiasi software da soli si potrebbe scoprire che alcune di queste librerie sono in/usr/local/lib o in qualche altra posizione. Se hai qualcosa che appare in/usr/local/lib è possibile che questo sia ciò che sta causando il tuo problema. Per testare, rinominare la libreria in/usr/local/lib con qualcos'altro (sudo mv /usr/local/lib/mylib.so /usr/local/lib/mylib.so.SAVE).

Ora esegui il programma e verifica se ottieni lo stesso errore. Se questo risolve il tuo problema allora fantastico! In caso contrario, faccelo sapere se ricevi lo stesso messaggio di errore o se ne ricevi uno nuovo.

mi aspetterei il file odbc.ini a guardare come questo:

[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 

e il file ODBCINST.INI a guardare come questo:

[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 

Il mio esempio mostra il mio setup per un telecomando iSeries ma sono sicuro che puoi vedere che cosa avresti bisogno di cambiare per MySQL.

Vale a dire che la tua riga "Driver = ..." odbc.ini è errata. Dovrebbe essere qualcosa come "Driver = mysql" e quindi devi definire [mysql] nel tuo file odbcinst.ini.

0

Come una soluzione e se SQLAllocEnv è definito in /usr/lib/odbc/libmyodbc.so si potrebbe provare a forza di carico prima di utilizzare JDBC

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

Ho usato MySQL con JDBC prima, e il modo più semplice che conosco per la connessione sta usando Connector/J, che è il pilota ufficiale di MySQL. Funzionerà come il tuo driver ODBC e non richiede roba nativa che potrebbe causare il tuo problema.

ottenere il driver da qui: http://dev.mysql.com/downloads/connector/j/

Documenti sulla pagina di cui sopra.

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

+0

@MarchingHome Il richiedente ha dato lo scopo della sua domanda, e io Abbiamo dato una risposta pratica ed esperta per ottenere esattamente la stessa funzionalità.So che le persone cercano di usare i driver ODBC, quando possono, e penso che (efficienza, funzionalità specifiche JDBC), usino quelli JDBC ufficiali. – Tom

+0

Hai ragione. Colpa mia :) – MarchingHome

2

passare alla directory:

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

e rinominare il file libJdbcOdbc.so a libJdbcOdbcXXX.so

questo ha funzionato per me.

3

Per correggere questo aggiungere il seguente al vostro script di avvio o profilo:

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

Il percorso può variare un po ', per me i file .so in cui in/usr/lib64.

"C'è un bug dovuto al fatto che le librerie" libodbc.so "e" libodbcinst.so "libJdbcOdbc.so non vengono caricate dalla libreria che implementa il bridge JDBC-ODBC."

Secondo 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

volta definisco questo .bash_profile, lo legge e funziona bene per me

Problemi correlati