Apache POI 在 Docker 容器中

huangapple go评论61阅读模式
英文:

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.

   &lt;webApplication contextRoot=&quot;/&quot; id=&quot;Home&quot; location=&quot;Home.war&quot; name=&quot;Home&quot;&gt; 
       	&lt;application-bnd&gt;

	...

    	&lt;/application-bnd&gt;

       	&lt;classloader privateLibraryRef=&quot;DB2,Commons,Jackson,POI&quot;/&gt;
    &lt;/webApplication&gt;

    &lt;library id=&quot;DB2&quot;&gt;
    	&lt;fileset dir=&quot;${server.config.dir}/myLib/DB2&quot; id=&quot;DB2&quot; includes=&quot;db2jcc4.jar db2jcc_license_cu.jar&quot; scanInterval=&quot;5s&quot;/&gt;
    &lt;/library&gt;
    &lt;library id=&quot;Jackson&quot;&gt;
    	&lt;fileset dir=&quot;${server.config.dir}/myLib/Jackson&quot; id=&quot;Jackson&quot; includes=&quot;*.jar&quot; scanInterval=&quot;5s&quot;/&gt;
    &lt;/library&gt;
    &lt;library id=&quot;Commons&quot;&gt;
    	&lt;fileset dir=&quot;${server.config.dir}/myLib/Commons&quot; id=&quot;Commons&quot; includes=&quot;*.jar&quot; scanInterval=&quot;5s&quot;/&gt;
    &lt;/library&gt;
    &lt;library id=&quot;POI&quot;&gt;
    	&lt;fileset dir=&quot;${server.config.dir}/myLib/POI&quot; id=&quot;POI&quot; includes=&quot;*.jar&quot; scanInterval=&quot;5s&quot;/&gt;
    &lt;/library&gt;

huangapple
  • 本文由 发表于 2020年7月30日 09:11:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63164705.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定