• [Access][Microsoft][ODBC 驱动程序管理器] 无效的字符串或缓冲区长度 Invalid string or buffer length


    背景描述:

    项目中,客户的工厂有一台检测产品指标的检测仪,其检测结果存储在本地电脑的Access数据库中。项目的目的是服务器连接这台电脑,通过rmi的方式进行连接,读取这台电脑上的Access数据库的mdb文件中的内容。

    Java 在服务器上通过RMI的方式访问客户电脑上的Access数据库中的内容的方法可以参考:https://blog.csdn.net/hongdi/article/details/5482470 中的介绍,很详细了。

    错误描述:

    在读取客户电脑上的Access数据库中的数据时,最开始一切都很正常,从某一时间点开始,报如下错误:

     1 java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 无效的字符串或缓冲区长度
     2     at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source)
     3     at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source)
     4     at sun.jdbc.odbc.JdbcOdbc.SQLGetDataString(Unknown Source)
     5     at sun.jdbc.odbc.JdbcOdbcResultSet.getDataString(Unknown Source)
     6     at sun.jdbc.odbc.JdbcOdbcResultSet.getString(Unknown Source)
     7     at org.objectweb.rmijdbc.RJResultSetServer.getString(RJResultSetServer.java:144)
     8     at sun.reflect.GeneratedMethodAccessor59.invoke(Unknown Source)
     9     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    10     at java.lang.reflect.Method.invoke(Unknown Source)
    11     at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    12     at sun.rmi.transport.Transport$2.run(Unknown Source)
    13     at sun.rmi.transport.Transport$2.run(Unknown Source)
    14     at java.security.AccessController.doPrivileged(Native Method)
    15     at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    16     at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    17     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    18     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access$400(Unknown Source)
    19     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
    20     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$1.run(Unknown Source)
    21     at java.security.AccessController.doPrivileged(Native Method)
    22     at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    23     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    24     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    25     at java.lang.Thread.run(Unknown Source)
    26     at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
    27     at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
    28     at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
    29     at org.objectweb.rmijdbc.RJResultSetServer_Stub.getString(Unknown Source)
    30     at org.objectweb.rmijdbc.RJResultSet.getString(RJResultSet.java:143)

    经查,用户的电脑的操作系统为64位Windows 7系统。同样的代码,当用户的电脑是32位Windows XP时就好用,不报错。

    程序中读取数据的代码如下:

    1 String sampNo = rs.getString(1);

    经过不断的查找,终于在这篇帖子上找到了问题的根源:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8038751

    是因为Jdk 1.6/7在64位操作系统上JDBC-ODBC桥上的Bug,导致在调用ResultSet.getObject()/getString()的时候随机并且不定时的报出 [Microsoft][ODBC 驱动程序管理器] 无效的字符串或缓冲区长度 这个错误。并不是一定会报错,可能是正常的运行了一段时间之后才报出来。

    这也解释了为什么当用户电脑是Windows XP时读取没问题,当用户是Windows 7 64位的时候才会有问题。

    解决方法:
    避免使用ResultSet.getObject()/getString(),根据数据库的类型,如果是数字使用getLong,如果是字符串使用getBytes来进行读取。比如:
    1 String remark = new String(rs.getBytes(4), "gbk");

    至此,此问题再也没有再复现过,问题解决!

  • 相关阅读:
    串的模式匹配问题
    游戏手柄directinput编程
    Hibernate的generator属性的意义
    MySQL——基础入门
    IEbug——li标签之间的空隙
    struts2 jar包详解
    hibernate自动建库(MySQL)
    hibernate参数一览表
    js中的逻辑运算符
    hibernate的离线关联(多级)查询
  • 原文地址:https://www.cnblogs.com/wanggangblog/p/15384216.html
Copyright © 2020-2023  润新知