5

我有以下 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

有谁知道我为什么会收到这个错误?这里有什么问题?

PS顺便说一句,我确实运行了 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
4

7 回答 7

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]。

于 2012-10-19T17:53:31.120 回答
3

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

首先,检查什么

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

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

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

$ export LD_DEBUG=all
$ java Test
于 2012-10-23T15:41:41.153 回答
3

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

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

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

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

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

于 2013-10-04T16:28:44.107 回答
2

我之前使用过带有 JDBC 的 MySQL,我知道的最简单的连接方法是使用 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

于 2012-10-27T16:02:06.300 回答
2

进入目录:

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

并将文件重命名libJdbcOdbc.solibJdbcOdbcXXX.so

这对我有用。

于 2013-02-27T11:45:37.930 回答
0

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

 try {
        System.load("/usr/lib/odbc/libmyodbc.so");
    } catch (UnsatisfiedLinkError e) {
      e.printStackTrace();
    }
于 2012-10-23T09:25:36.557 回答
0

导出 LD_PRELOAD=$LD_PRELOAD:/usr/lib/libodbc.so:/usr/lib/libodbcinst.so

一旦我在 .bash_profile 中定义了它,就获取它,它对我来说很好用。

于 2014-08-14T19:10:59.323 回答