人大金仓kingbase invalid value for parameter client_encoding ANSI_X3.4-1968

人大金仓kingbase invalid value for parameter client_encoding ANSI_X3.4-1968

背景

应用连接数据库的时候提示以下错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is com.kingbase8.util.KSQLException: ������������: ������ "client_encoding" ������������: "ANSI_X3.4-1968"
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.cloud.autoconfigure.RefreshAutoConfiguration$JpaInvokerConfiguration.init(RefreshAutoConfiguration.java:120)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)
    ... 26 common frames omitted

怀疑问题

  1. jdbc驱动连接没有设置和数据库一致的编码

    人大金仓的资料实在是少,甚至如何在jdbc连接设置编码都无法找到,但是我们可以查找kingbase://协议,看看别人是怎么写的,发现是这样写的:

    *jdbc:kingbase8*://***:5419/cdb?useUnicode=true&characterEncoding=utf-8。于是改上去,并没有用。排除改方向

  2. Druid不支持kingbase8

    在百度确实找到了这个说法,但是官网上不去,没办法验证这个说法。而且本地可以正常连接,服务器连接不正常。排除改方向

解决步骤

  1. 解决初始化连接返回的乱码信息

    com.kingbase8.util.KSQLException: ������������: ������ "client_encoding" ������������: "ANSI_X3.4-1968"
    

    在以上信息可以看到,这个应该是链接的时候返回的,第一反应就是去查看kingbase日志:/data/kingbase/ES/V8/data/sys_log。可以看到如下信息:

    2021-04-14 16:18:43 CST 致命错误:  参数 "client_encoding" 的值无效: "ANSI_X3.4-1968"
    

    终于发现错误本体了,但是,是什么导致了乱码?乱码肯定是中文不是英文了,所以应该有什么地址可以设置日志的编码。不过kingbase基本和postgresql一致,所以按照postgresql的方法修改日志的编码即可。大致找了下kingbase的日志,发现在这个文件kingbase.conf

    修改kingbase.conf日志编码

    lc_messages = 'zh_CN.UTF-8'
    

    修改成:

    lc_messages = 'en_US.UTF-8'
    

    重启kingbase:sudo systemctl restart kingbase

    之后可以看到java的日志打印正常了:

    FATAL: invalid value for parameter "client_encoding": "ANSI_X3.4-1968"

  2. 调试源码

    根据提示信息查找,发现并没有查看到有用的信息,所以尝试调试源码

    在以下文件的对应方法[com.kingbase8.core.v3.ConnectionFactoryImpl#openConnectionImpl]找到了108行关键代码:

    newStream = new KBStream(socketFactory, hostSpec, connectTimeout);
    String client_encoding;
    if (KBProperty.CLIENT_ENCODING.get(info) == null) {
    client_encoding = System.getProperty("file.encoding");
    info.setProperty("clientEncoding", client_encoding);
    LOGGER.log(Level.FINE, "Use current JVM default encoding {0}", client_encoding);
    }
    
    client_encoding = KBProperty.CLIENT_ENCODING.get(info);
    newStream.setEncoding(Encoding.getJVMEncoding(client_encoding));
    

    可以看到初始化连接的时候,获取了jvm_encoding。这里,我们可以调试一下,在容器下的jvm_encoding究竟是什么编码?

    可以使用arthas修改容器class文件打印以下,或者随便在启动的时候日志打印以下System.getProperty("file.encoding")。容器只记录日志的输出,所以可能使用System.out.println会无法显示。

  3. 修改docker的jvm_encoding

    在dockerfile添加以下代码即可:ENV JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8

    完整的Dockerfile大致如下:

    #FROM指令必须指定且需要在Dockerfile其他指令的前面,指定的基础image可以是官方远程仓库中的,也可以位于本地仓库
    FROM livingobjects/jre8
    # UTF-8 并配置环境
    ENV LANG C.UTF-8
    ENV JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8
    #使容器中的一个目录具有持久化存储数据的功能,该目录可以被容器本身使用
    VOLUME /tmp
    #从src目录复制文件到容器的dest。其中src可以是Dockerfile所在目录的相对路径,也可以是一个URL,还可以是一个压缩包
    ADD target/*.jar app.jar
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    RUN echo 'Asia/Shanghai' >/etc/timezone
    #ADD wait-for-it.sh /wait-for-it.sh
    RUN bash -c 'touch /app.jar'
    #指定Docker容器启动时执行的命令,可以多次设置,但是只有最后一个有效。
    ENTRYPOINT ["java","-Dfile.encoding=UTF8","-jar","/app.jar","--spring.profiles.active=test","&"]
    
  4. 修改重新build了之后可以发现,连接正常了。

总结

  1. 网上关于人大金仓的资料比较少,如果遇到问题,可以尝试把关键字更换成postgresql再查看,也许更容易查找到答案
  2. 需要意识到容器化部署下一些参数不一致。
  3. 网上找不到答案可以从源码入手
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容