远程JodConverter服务调用报NullPointerException问题求助
问题描述
将LibreOffice服务部署至公网服务器并开放端口后,项目调用远程JodConverter服务的execute方法时触发NullPointerException,本地部署服务时一切正常,怀疑文件传输环节存在问题,相关信息如下:
错误日志
2023-11-09 17:27:58.675 ERROR 15750 --- [ter-poolentry-0] o.j.remote.task.RemoteConversionTask : Remote conversion failed. java.lang.NullPointerException: null at java.base/java.util.Objects.requireNonNull(Objects.java:221) ~[na:na] at org.jodconverter.remote.task.RemoteConversionTask.execute(RemoteConversionTask.java:135) ~[jodconverter-remote-4.3.0.jar:4.3.0] at org.jodconverter.remote.office.RemoteOfficeManagerPoolEntry.doExecute(RemoteOfficeManagerPoolEntry.java:306) ~[jodconverter-remote-4.3.0.jar:4.3.0] at org.jodconverter.core.office.AbstractOfficeManagerPoolEntry.lambda$execute$0(AbstractOfficeManagerPoolEntry.java:83) ~[jodconverter-core-4.3.0.jar:4.3.0] at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) ~[na:na] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na] at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] org.jodconverter.core.office.OfficeException: Remote conversion failed at org.jodconverter.remote.task.RemoteConversionTask.execute(RemoteConversionTask.java:153) at org.jodconverter.remote.office.RemoteOfficeManagerPoolEntry.doExecute(RemoteOfficeManagerPoolEntry.java:306) at org.jodconverter.core.office.AbstractOfficeManagerPoolEntry.lambda$execute$0(AbstractOfficeManagerPoolEntry.java:83) at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.lang.NullPointerException at java.base/java.util.Objects.requireNonNull(Objects.java:221) at org.jodconverter.remote.task.RemoteConversionTask.execute(RemoteConversionTask.java:135) ... 7 more WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.alibaba.fastjson2.util.JDKUtils (file:/Users/jayleonc/Developer/Environment/apache-maven-3.8.4/maven-repo/com/alibaba/fastjson2/fastjson2/2.0.17/fastjson2-2.0.17.jar) to constructor java.lang.invoke.MethodHandles$Lookup(java.lang.Class,int) WARNING: Please consider reporting this to the maintainers of com.alibaba.fastjson2.util.JDKUtils WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release
配置信息
jodconverter. remote. url: http://xxx.xx.xx.xxx:9980 local: # office-home: /Applications/LibreOffice.app/Contents/ # office-home: /Applications/LibreOffice.app/Contents/ enabled: false
配置类代码
package com.xxx.supt.infra.config; import org.jodconverter.core.DocumentConverter; import org.jodconverter.core.office.OfficeManager; import org.jodconverter.remote.RemoteConverter; import org.jodconverter.remote.office.RemoteOfficeManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class LibreofficeConfig { @Value("${jodconverter.remote.url:''}") private String jodconverterUrl; @Bean( initMethod = "start", destroyMethod = "stop" ) public OfficeManager officeManager() { RemoteOfficeManager.Builder builder = RemoteOfficeManager.builder(); builder.urlConnection(jodconverterUrl); builder.poolSize(10); builder.taskExecutionTimeout(60000L); builder.taskQueueTimeout(60000L); return builder.build(); } @Bean @ConditionalOnMissingBean @ConditionalOnBean({OfficeManager.class}) public DocumentConverter jodConverter(OfficeManager officeManager) { return RemoteConverter.make(officeManager); } }
转换方法代码
public void convertToPdfAndOutput(File file) throws IOException, OfficeException { File tempFile = File.createTempFile("temp", ".pdf"); converter.convert(file).to(tempFile).execute(); outputToResponse(tempFile, "application/pdf"); }
调试converter.convert(file).to(tempFile).execute();时触发错误,需排查问题并解决。
问题分析与解决方案
核心问题定位
从报错栈看,NPE发生在RemoteConversionTask.java:135,结合JodConverter 4.3.0源码,这一行是处理远程请求响应时发现响应对象为null,主要原因集中在配置解析错误、网络连通性异常或远程服务未正常启动。
具体修复步骤
1. 修正YAML配置格式
你的配置文件存在格式错误,YAML要求层级用冒号+空格分隔,不能用点号换行,否则Spring无法正确解析jodconverter.remote.url,导致连接地址为空。
修正后的配置:
jodconverter: remote: url: http://xxx.xx.xx.xxx:9980 local: enabled: false
2. 验证网络与远程服务状态
- 在项目部署机器执行
curl http://xxx.xx.xx.xxx:9980,检查是否能正常访问远程服务 - 确认公网服务器的防火墙/安全组已开放9980端口,允许项目机器的IP访问
- 查看远程LibreOffice服务日志,确认服务无启动异常,能正常接收请求
3. 优化配置类的参数校验
配置类中@Value的默认值为空字符串,可能导致无效连接,建议移除默认值并增加非空校验:
package com.xxx.supt.infra.config; import org.jodconverter.core.DocumentConverter; import org.jodconverter.core.office.OfficeManager; import org.jodconverter.remote.RemoteConverter; import org.jodconverter.remote.office.RemoteOfficeManager; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.Assert; @Configuration public class LibreofficeConfig { @Value("${jodconverter.remote.url}") private String jodconverterUrl; @Bean( initMethod = "start", destroyMethod = "stop" ) public OfficeManager officeManager() { // 增加非空校验,避免无效连接 Assert.notNull(jodconverterUrl, "jodconverter.remote.url 必须配置"); RemoteOfficeManager.Builder builder = RemoteOfficeManager.builder(); builder.urlConnection(jodconverterUrl); builder.poolSize(10); builder.taskExecutionTimeout(60000L); builder.taskQueueTimeout(60000L); return builder.build(); } @Bean @ConditionalOnMissingBean @ConditionalOnBean({OfficeManager.class}) public DocumentConverter jodConverter(OfficeManager officeManager) { return RemoteConverter.make(officeManager); } }
4. 验证文件与服务权限
- 确认项目机器上的源文件
file存在且有可读权限 - 检查远程服务器的临时目录(LibreOffice转换时会用到)是否有可写权限
- 在远程服务器直接用LibreOffice命令行转换文件,验证服务本身功能正常:
libreoffice --headless --convert-to pdf /path/to/test/file.docx
内容的提问来源于stack exchange,提问作者Jayleonc
相关产品推荐
相关产品推荐

