英文:
Apache POI inside Docker container
问题
我已经创建了一个简单的Java应用程序,使用Apache POI库(3.17版本)生成Excel文件。该代码在我的机器上作为Web应用程序(Liberty的一部分)运行得很好。
我必须在一个容器内运行这段代码。因此,我使用以下Docker文件创建了Docker镜像:
FROM icr.io/ibm/liberty:20.0.0.6-wl-full
# 添加我的应用程序和配置
COPY --chown=1001:0 Home.war /config/apps/
COPY --chown=1001:0 server.xml /config/
COPY --chown=1001:0 server.env /config/
# 添加DB2库
COPY --chown=1001:0 Shared/DB2/ /config/myLib/DB2/
# 添加通用库
COPY --chown=1001:0 Shared/Commons/ /config/myLib/Commons/
# 添加Jackson库
COPY --chown=1001:0 Shared/Jackson/ /config/myLib/Jackson/
# 添加POI库
COPY --chown=1001:0 Shared/POI/ /config/myLib/POI/
该代码在"Docker化"的Liberty中运行得很好,直到我达到创建工作簿的语句。然后,代码执行完全冻结(至少在调用构造函数后,System.out没有显示)。
XSSFWorkbook wb = new XSSFWorkbook();
我尝试了不同的方法来解决错误。最初,由于历史原因,我使用的是SXSSFWorkbook而不是XSSFWorkbook。我尝试创建一个临时文件并将该文件传递给XSSFWorkbook构造函数。但都没有成功。
我认为这可能与POI对临时文件的使用有关。或者可能是缺少某个库,但正如我所说,当在我的计算机上运行时,代码运行得很好。
我不是Docker方面的专家,也许我错过了一些基本的配置。关于为什么我无法使用POI,您有什么想法吗?提前感谢。
英文:
I have created a simple Java application which generates an Excel file using Apache POI libraries (3.17). The code runs great while running in my machine as part of a Web application (Liberty).
I have to run this code inside a container. So I have created the docker image using this dockerfile:
FROM icr.io/ibm/liberty:20.0.0.6-wl-full
# Add my app and config
COPY --chown=1001:0 Home.war /config/apps/
COPY --chown=1001:0 server.xml /config/
COPY --chown=1001:0 server.env /config/
# Add DB2 libraries
COPY --chown=1001:0 Shared/DB2/ /config/myLib/DB2/
# Add Common libraries
COPY --chown=1001:0 Shared/Commons/ /config/myLib/Commons/
# Add Jackson libraries
COPY --chown=1001:0 Shared/Jackson/ /config/myLib/Jackson/
# Add POI libraries
COPY --chown=1001:0 Shared/POI/ /config/myLib/POI/
The code runs fine inside the 'dockerized' Liberty until I reach the sentence which creates the workbook. Then the code execution totally freezes (at least the System.out after calling the constructor is not being displayed).
XSSFWorkbook wb = new XSSFWorkbook();
I have tried different approaches to solve the error. Initially I was using (for historical reasons) SXSSFWorkbook instead of XSSFWorkbook. I have tried to create a temporary file and pass the file to the XSSFWorkbook constructor. No way.
I think this might be related with the use that POI is doing of temporary files. Or maybe a missing library but, as I said, the code is working fine when running on my computer.
I am not an expert in docker and maybe I am missing some basic configuration. Any ideas on why I am not capable of using POI? Thanks in advance.
答案1
得分: 0
Here is the translated content:
最后我发现了问题。我在这里发布解决方案,以防有人觉得有用。
在Docker容器中使用POI没有任何问题。问题在于我将POI库声明为共享库,但这些POI库对应用程序不可用。没有错误或异常。应用程序只是冻结了。
我尝试将这些库包含在WAR文件中,一切都正常工作。所以,明显是可见性的问题。
我将commonLibraryRef条目切换为server.xml文件中的privateLibraryRef,然后一切都按预期工作。
<webApplication contextRoot="/" id="Home" location="Home.war" name="Home">
<application-bnd>
...
</application-bnd>
<classloader privateLibraryRef="DB2,Commons,Jackson,POI"/>
</webApplication>
<library id="DB2">
<fileset dir="${server.config.dir}/myLib/DB2" id="DB2" includes="db2jcc4.jar db2jcc_license_cu.jar" scanInterval="5s"/>
</library>
<library id="Jackson">
<fileset dir="${server.config.dir}/myLib/Jackson" id="Jackson" includes="*.jar" scanInterval="5s"/>
</library>
<library id="Commons">
<fileset dir="${server.config.dir}/myLib/Commons" id="Commons" includes="*.jar" scanInterval="5s"/>
</library>
<library id="POI">
<fileset dir="${server.config.dir}/myLib/POI" id="POI" includes="*.jar" scanInterval="5s"/>
</library>
英文:
Finally I discovered the problem. And I am posting here the solution just in case someone finds it useful.
There is no problem at all with using POI inside a docker container. I was declaring the POI libraries as shared libraries. But those POI libraries where not available to the application. No errors or exceptions. The application just freezes.
I tried to include the libraries inside the WAR and everything worked fine. So, definitely was a problem of visibility.
I switched the commonLibraryRef entry for a privateLibraryRef in my server.xml file and everything started to work as expected.
<webApplication contextRoot="/" id="Home" location="Home.war" name="Home">
<application-bnd>
...
</application-bnd>
<classloader privateLibraryRef="DB2,Commons,Jackson,POI"/>
</webApplication>
<library id="DB2">
<fileset dir="${server.config.dir}/myLib/DB2" id="DB2" includes="db2jcc4.jar db2jcc_license_cu.jar" scanInterval="5s"/>
</library>
<library id="Jackson">
<fileset dir="${server.config.dir}/myLib/Jackson" id="Jackson" includes="*.jar" scanInterval="5s"/>
</library>
<library id="Commons">
<fileset dir="${server.config.dir}/myLib/Commons" id="Commons" includes="*.jar" scanInterval="5s"/>
</library>
<library id="POI">
<fileset dir="${server.config.dir}/myLib/POI" id="POI" includes="*.jar" scanInterval="5s"/>
</library>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论