如何在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的方式本身不可行,核心原因有两点:
File对象仅能指向文件系统中真实存在的物理目录,而JAR内部的资源是压缩包内的条目,并非文件系统中的独立目录,无法用File直接访问。- 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
相关产品推荐
相关产品推荐

