Java ODBC数据源(未定义的符号:SQLAllocEnv)

时间:2012-10-19 17:42:57

标签: java mysql odbc

我有以下Java代码。此代码的目的是建立连接 到远程MySQL数据库ProductionDb(我的/etc/odbc.ini文件中定义的数据源)。

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());
        }
    }

}

/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

顺便说一下 - 我使用的是Java 7和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

当我尝试运行程序时,出现以下错误:

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

有谁知道我为什么会收到这个错误? 这有什么不对?

P.S顺便说一下我运行了sudo apt-get install unixodbc-dev,sudo apt-get install libmyodbc和sudo apt-get install libmysql-java :-)

更新

我也尝试过以下其中一个回复(Benny Hill)中提出的想法:使用/etc/odbcinst.ini以及/etc/odbc.ini。仍然无法正常工作,我收到相同的错误消息。

$ 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

附加说明:

我可以从R成功使用此ODBC数据源 编程语言。

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

7 个答案:

答案 0 :(得分:6)

该错误是libJdbcOdbc.so在其他一些.so中查找函数“SQLAllocEnv”而未找到它的结果。调试方法是运行命令 ldd /usr/lib/jvm/java-7-oracle/jre/lib/amd64/libJdbcOdbc.so 。这将显示链接的.so对象列表及其所在位置。

一般来说,它们应该在/ usr / lib中,但是如果您自己编译了任何软件,您可能会发现其中一些库位于/ usr / local / lib或其他位置。如果您在/ usr / local / lib中有任何显示内容,则可能是导致您出现问题的原因。要进行测试,请将/ usr / local / lib中的库重命名为其他内容( sudo mv /usr/local/lib/mylib.so /usr/local/lib/mylib.so.SAVE )。

现在运行你的程序,看看你是否仍然得到同样的错误。如果这可以解决您的问题,那就太好了!如果没有,请告诉我们您是否收到相同的错误消息,或者是否有新消息。

我希望你的odbc.ini文件看起来像这样:

[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

你的odbcinst.ini文件看起来像这样:

[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

我的示例显示了我对远程iSeries的设置,但我确信您可以看到您需要为MySQL更改的内容。

即你的odbc.ini“Driver = ...”行是错误的。它应该类似于“Driver = mysql”,然后你需要在你的odbcinst.ini文件中定义[mysql]。

答案 1 :(得分:3)

听起来像是缺少或不匹配的库。尝试调试ldd处理。

首先,检查一下

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

说,是否存在所有列出的依赖项?

然后,尝试设置LD_DEBUG并再次启动Java程序,以查看加载程序调试。

$ export LD_DEBUG=all
$ java Test

答案 2 :(得分:3)

要解决此问题,请将以下内容添加到您的启动脚本或配置文件中:

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

您的路径可能会有所不同,对于我在/ usr / lib64中的.so文件。

“由于没有从实现JDBC-ODBC桥的库加载库”libodbc.so“和”libodbcinst.so“libJdbcOdbc.so,因此存在一个错误。”

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

答案 3 :(得分:2)

之前我曾使用MySQL和JDBC,我知道连接的最简单方法是使用Connector / J这是官方的MySQL驱动程序。它将与您的ODBC驱动程序相同,并且不需要可能导致您的问题的本机内容。

从这里获取驱动程序:http://dev.mysql.com/downloads/connector/j/

上页的文档。

文档如何连接:http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-connect-drivermanager.html#connector-j-examples-connection-drivermanager

答案 4 :(得分:2)

转到目录:

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

将文件libJdbcOdbc.so重命名为libJdbcOdbcXXX.so

这对我有用。

答案 5 :(得分:0)

作为一种解决方法,如果在/usr/lib/odbc/libmyodbc.so中定义SQLAllocEnv,您可以尝试在使用JDBC之前强制加载它

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

答案 6 :(得分:0)

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

一旦我在.bash_profile中定义了它,请找到它,它对我来说很好。