惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
A
About on SuperTechFans
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
Recent Announcements
Recent Announcements
D
DataBreaches.Net
B
Blog
博客园 - 【当耐特】
爱范儿
爱范儿
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
WordPress大学
WordPress大学
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网
量子位
G
Google Developers Blog

博客园 - 刚泡

数据库短暂波动导致xxl-job-admin不调度任务的问题 CompletableFuture用法详解 使用责任链模式简化if-else代码示例 使用Function Interface简化if-else代码示例 自定义AngularJS Modal弹框大小的方法 SpringCloud Alibaba 改造Sentinel Dashboard将熔断规则持久化到Nacos SpringCloud Alibaba 改造Sentinel Dashboard将流控规则持久化到Nacos Java操作Kafka执行不成功的解决方法,Kafka Broker Advertised.Listeners属性的设置 pom.xml错误:org.codehaus.plexus.archiver.jar.Manifest.write(java.io.PrintWriter)的解决方法 Spring Cloud @HystrixCommand和@CacheResult注解使用,参数配置 Spring Boot的属性加载顺序 Spring Boot 使用properties如何多环境配置 Spring Cloud微服务实战阅读笔记(一) 基础知识 Java使用POI为Excel打水印,调整列宽并设置Excel只读(用户不可编辑) Sitemesh 3使用及配置 Java上传文件夹(Jersey) 路径名导致的异常:javax.imageio.IIOException: Can't read input file! 解决安卓微信浏览器中上传不能调用相机的问题 Mac下安装SVN插件javaHL not available的解决方法
[Access][Microsoft][ODBC 驱动程序管理器] 无效的字符串或缓...
刚泡 · 2021-10-09 · via 博客园 - 刚泡

背景描述:

项目中,客户的工厂有一台检测产品指标的检测仪,其检测结果存储在本地电脑的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");

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