You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用documents4j转DOCX为PDF在Windows Server 2019中线程阻塞问题

DOCX转PDF服务在Windows Server 2019上的线程阻塞问题

我使用documents4j(内部通过VBScript实现转换)将DOCX文件转为PDF,代码取自documents4j官方实现。该代码作为Web服务部署在以Windows服务运行的Tomcat 9.0.37中,已创建C:\Windows\SysWOW64\config\systemprofile\Desktop文件夹,且安装了正版MS Office 2016。相同配置下,Windows Server 2012虚拟机可正常转换,但Windows Server 2019虚拟机中调用execute方法时线程永久阻塞,引发内存泄漏,栈跟踪如下:

org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [appName] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation. Stack trace of request processing thread:[
 java.base@11.0.5/jdk.internal.misc.Unsafe.park(Native Method)
 java.base@11.0.5/java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
 java.base@11.0.5/java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:885)
 java.base@11.0.5/java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1039)
 java.base@11.0.5/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1345)
 java.base@11.0.5/java.util.concurrent.CountDownLatch.await(CountDownLatch.java:232)
 com.documents4j.job.AbstractFutureWrappingPriorityFuture.get(AbstractFutureWrappingPriorityFuture.java:204)
 com.documents4j.job.AbstractFutureWrappingPriorityFuture.get(AbstractFutureWrappingPriorityFuture.java:10)
 com.documents4j.job.ConversionJobAdapter.execute(ConversionJobAdapter.java:13)

代码片段1

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;

public class WordMLToPDF2 {

    public static void main(String[] args) {

        File inputWord  = new File("C:\\Users\\anshu\\Downloads\\test.docx")
        , outputFile  = new File("C:\\Users\\anshu\\Downloads\\test.pdf");
        try  {
            InputStream docxInputStream = new FileInputStream(inputWord);
            OutputStream outputStream = new FileOutputStream(outputFile);
            IConverter converter = LocalConverter.builder()
                       .baseFolder(tmpDir)
                       .workerPool(20, 25, 2, TimeUnit.SECONDS)
                       .processTimeout(30, TimeUnit.SECONDS)
                       .build();
            converter.convert(docxInputStream).as(DocumentType.DOCX).to(outputStream).as(DocumentType.PDF).execute();
            outputStream.close();
            System.out.println("success");
            converter.shutDown();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
}

pom.xml依赖配置

<dependencies>
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-documents4j-local</artifactId>
        <version>8.3.3</version>
    </dependency>
    <dependency>
        <groupId>org.docx4j</groupId>
        <artifactId>docx4j-JAXB-ReferenceImpl</artifactId>
        <version>8.3.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.17.1</version>
    </dependency>
    <!-- API, java.xml.bind module -->
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
        <version>2.3.2</version>
    </dependency>

    <!-- Runtime, com.sun.xml.bind module -->
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.2</version>
    </dependency>
</dependencies>

分析结果

通过分析源码得知,documents4j借助zt-exec(ZeroTurnaround Process Executor)库执行VBScript来启动WINWORD、执行DOCX转PDF或关闭WINWORD;当执行wordApplication.Documents.Open(inputFile, False, True, False)时,WINWORD程序发生冻结,其中wordApplication为Word.Application对象。

内容的提问来源于stack exchange,提问作者Anshu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 10:05:32