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

如何在Maven打包的JAR中运行DITA-OT?

问题:将DITA-OT打包进JAR后通过Java API调用失败

操作背景

  • 已从Maven Central添加org.dita-ot.dost依赖
  • 手动执行mvn install安装了DITA-OT下载包中的dost-configuration.jar(该JAR未包含在Maven库中)
  • 将DITA-OT 3.7.3作为资源添加(排除lib目录),尝试通过Java API调用

问题详情

根据API要求,需要提供指向DITA-OT目录的File对象,但两次尝试构造File均报错:

第一次尝试代码

File ditaOtDir = new File(this.getClass().getResource("/dita-ot-3.7.3").toURI());
ProcessorFactory pf = ProcessorFactory.newInstance(ditaOtDir);

报错信息:

Exception in thread "main" java.lang.IllegalArgumentException: DITA-OT directory must be absolute at org.dita.dost.ProcessorFactory.newInstance(ProcessorFactory.java:30) ...

第二次尝试代码

URL ditaOtDirUrl = this.getClass().getResource("/dita-ot-3.7.3");
File ditaOtDir = new File(ditaOtDirUrl.toString()).getAbsoluteFile();
// 后续调用Processor.run()

报错信息:

Caused by: Basedir /full/example/path/jar:file:/path/to/this.jar!/dita-ot-3.7.3 does not exist 
at org.apache.tools.ant.Project.setBaseDir(Project.java:858)
 at org.dita.dost.Processor.run(Processor.java:207)
...

疑问:是构造File对象时忽略了要点,还是将DITA-OT打包进JAR的方式本身不可行?


解答

将DITA-OT目录打包进JAR的方式本身不可行,核心原因有两点:

  1. File对象仅能指向文件系统中真实存在的物理目录,而JAR内部的资源是压缩包内的条目,并非文件系统中的独立目录,无法用File直接访问。
  2. DITA-OT的Processor底层依赖Ant的Project组件,Ant的setBaseDir方法要求传入的是文件系统中真实存在的绝对路径,JAR内部的资源路径(格式为jar:file:/...)完全不符合这个要求,这也是第二次报错的直接原因。

可行解决方案

方案1:将DITA-OT作为外部目录部署

不要把DITA-OT打包进JAR,而是将其解压到运行环境的固定目录,代码中直接使用该绝对路径:

// 替换为实际的DITA-OT解压目录绝对路径
File ditaOtDir = new File("/opt/dita-ot-3.7.3").getAbsoluteFile();
ProcessorFactory pf = ProcessorFactory.newInstance(ditaOtDir);

方案2:启动时将JAR内的DITA-OT资源解压到临时目录

如果需要简化部署,可以在应用启动阶段,把打包在JAR里的DITA-OT资源(建议打包为ZIP)解压到系统临时目录,再用临时目录路径构造File:

// 创建临时目录
Path tempDir = Files.createTempDirectory("dita-ot-temp-");

// 从JAR资源中读取DITA-OT的ZIP包并解压
try (InputStream zipInputStream = this.getClass().getResourceAsStream("/dita-ot-3.7.3.zip")) {
    ZipInputStream zis = new ZipInputStream(zipInputStream);
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        Path targetPath = tempDir.resolve(entry.getName());
        if (entry.isDirectory()) {
            Files.createDirectories(targetPath);
        } else {
            Files.copy(zis, targetPath, StandardCopyOption.REPLACE_EXISTING);
        }
        zis.closeEntry();
    }
} catch (IOException e) {
    // 处理解压异常
    e.printStackTrace();
}

// 使用临时目录初始化ProcessorFactory
File ditaOtDir = tempDir.toFile().getAbsoluteFile();
ProcessorFactory pf = ProcessorFactory.newInstance(ditaOtDir);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 23:02:51