Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

背景

java现代化编程中,通常会使用CI/CD技术进行项目部署,笔者最近的项目就使用了Jekins部署项目到docker环境中。

由于docker image中的jdk版本比较低,计划升级jdk的版本,以规避JDK 1.8.u1xx系列的bug。

举例来说,笔者将docker文件中的版本升级到1.8u322,修改Dockerfile为如下

FROM openjdk:8u322-jre

然后使用IDEA的Docker插件发布,正常运行。唯独使用POI导出Excel时候报错。如下

2022-03-04 10:37:51.471 [XNIO-1 task-1] DEBUG [com.alibaba.excel.context.WriteContextImpl.finish] - Finished write.

2022-03-04 10:37:51.474 [XNIO-1 task-1] DEBUG [org.springframework.web.servlet.FrameworkServlet.logResult] - Failed to complete request: com.alibaba.excel.exception.ExcelGenerateException: java.lang.UnsatisfiedLinkError: /usr/local/openjdk-8/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory
2022-03-04 10:37:51.476 [XNIO-1 task-1] ERROR [io.undertow.servlet.api.LoggingExceptionHandler.handleThrowable] - UT005023: Exception handling request to /API/SAPOrder/exportList
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is com.alibaba.excel.exception.ExcelGenerateException: java.lang.UnsatisfiedLinkError: /usr/local/openjdk-8/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:665) ~[javax.servlet-api-4.0.1.jar!/:4.0.1]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[javax.servlet-api-4.0.1.jar!/:4.0.1]
        at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.websockets.jsr.JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:173) ~[undertow-websockets-jsr-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:97) ~[spring-web-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at com.www.mes.common.filter.HttpTraceLogFilter.doFilterInternal(HttpTraceLogFilter.java:54) ~[classes!/:0.1-SNAPSHOT]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.1.19.RELEASE.jar!/:5.1.19.RELEASE]
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) ~[undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) ~[undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99) [undertow-servlet-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376) [undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830) [undertow-core-2.0.32.Final.jar!/:2.0.32.Final]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_202]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_202]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_202]

当然,笔者的同事也尝试用Oracle JDK1.8u202在centos7.9中制作Docker Image文件,同样也是少文件,只是报错的路径不一样。

经过笔者进入docker尝试,openjdk8u322是在debian11.2上面制作完成的(这里要求了解linux的辨别方法)

Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

解决方法

笔者探索解决方法的过程如下:

首先进入docker镜像,发现文件/usr/local/openjdk-8/lib/amd64/libawt_xawt.so:是存在的。而后面的libXext.so.6则不存在。

Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

笔者在docker中执行以下命令

whereis libXext.so.6

并没发现(截至写博文时已经修复,不再截图)

后来根据笔者的操作系统知识,看上面的报错,应该是libawt_xawt.so缺少libXext.so.6的依赖。

在docker中执行以下命令,发现awt依赖的如下(类似下面,笔者已经安装了libXrender.so情况下执行该命令,如果没安装,会有很多显示not found)

root@0bde6b347fbd:/# ldd /usr/local/openjdk-8/lib/amd64/libawt_xawt.so
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
        linux-vdso.so.1 (0x00007fffcffcb000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fbf32914000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fbf327d0000)
        libawt.so => /usr/local/openjdk-8/lib/amd64/libawt.so (0x00007fbf324fc000)
        libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007fbf324e7000)
        libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007fbf323a4000)
        libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007fbf3219a000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fbf32192000)
        libXtst.so.6 => not found
        libXi.so.6 => not found
        libjava.so => /usr/local/openjdk-8/lib/amd64/libjava.so (0x00007fbf31f68000)
        libjvm.so => /usr/local/openjdk-8/lib/amd64/server/libjvm.so (0x00007fbf30f51000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbf30d8c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbf32ba0000)
        libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007fbf30d5f000)
        libverify.so => /usr/local/openjdk-8/lib/amd64/libverify.so (0x00007fbf30b4f000)
        libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007fbf30b4a000)
        libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007fbf30944000)
        libbsd.so.0 => /usr/lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fbf3092d000)
        libmd.so.0 => /usr/lib/x86_64-linux-gnu/libmd.so.0 (0x00007fbf3091e000)

笔者在docker中执行以下命令,查询相关依赖

sed -i "s@http://deb.debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
sed -i "s@http://security.debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
apt update
apt-cache search libxext

Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

你只需安装 libxext6即可,即执行以下命令

apt-get install libxext6

但是为了兼容不同版本的openjdk8(不同版本的debian查询得到的libxext可能不一样,比如libxext5,libxext4),笔者选择使用以下命令

apt-get install libxext*

当然,也会额外下载其他东西,看你的需要吧。

经过多次测试,笔者得到以下的Dockerfile配置

FROM openjdk:8u322-jre
.....

RUN sed -i "s@http://deb.debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list \
    && sed -i "s@http://security.debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list
RUN apt update
RUN apt-get install libxext* libxrender1* libxtst*  -y
....

按照以上配置后,再次用poi导出excel不再报错,再来执行命令看看libawt_xawt.so依赖

ldd /usr/local/openjdk-8/lib/amd64/libawt_xawt.so

Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

如果你是自己制作镜像,比如使用centos7.9,执行以下命令

sudo yum install libXext* libXrender* libXtst* -y

有人问,为什么,我在宿主机里面安装oracle jdk/jre,openjdk/jre很少遇到问题?

答:因为制作docker镜像时,关于操作系统依赖都是最低依赖库,以便方便发现(Image体积小90-200M左右,否则数GB怎么发行)。

一般宿主机安装linux都会安装libX11或者xorg,即桌面相关,所以不会,会顺便安装上面的依赖库,所以不会报错。

或者因为安装其他库(liboffice,imageMagick,vnc笔者猜想的),顺便安装了xorg,libx11。

java awt中含有图像图形相关的方法/函数,所以需要很多so动态库,而我们使用的POI很可能依赖图像运算相关库,所以报错了。
时间太晚,笔者没去研究libxext libxrender libxtst,感兴趣的你可以自己搜索了解一下。

Original: https://www.cnblogs.com/passedbylove/p/15966156.html
Author: 你不知道的浪漫
Title: Excel导出工具Apache poi在docker环境中报错/usr/local/jdk1.8.0_202/jre/lib/amd64/libawt_xawt.so: libXext.so.6: cannot open shared object file: No such file or directory

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/534246/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球