为什么使用 Tabula 解析 PDF 文件时出现空白 Java 图标?

Why is a blank Java Icon appearing when I parse a PDF file using Tabula?

我正在与 Apache Drill 集成,使用户能够直接使用 SQL 查询 PDF 文件。我已经完成了大约 80%,Tabula 在这方面的表现给我留下了深刻的印象。

但是,当我执行第一个使用 Tabula 库的 Drill 查询时,会弹出一个 Java 图标,我在命令行中得到以下文本:

2020-10-25 15:06:55.770 java[71188:7121498] Persistent UI failed to open file file://localhost/Users/******/Saved%20Application%20State/net.java.openjdk.cmd.savedState/window_1.data: Permission denied (13)

我更改了该目录的权限,但我仍然收到 Java 弹出窗口。

这不是 Drill 的正常行为,我的目标是以编程方式集成 Tabula。 Tabula 是否试图打开 window 或类似的东西,如果是,有没有办法禁用它?我注意到这不会发生在我的单元测试中。

以下是一些相关的代码片段:

 public static List<Table> extractTablesFromPDF(PDDocument document, ExtractionAlgorithm algorithm) {
    NurminenDetectionAlgorithm detectionAlgorithm = new NurminenDetectionAlgorithm();

    ExtractionAlgorithm algExtractor;

    SpreadsheetExtractionAlgorithm extractor=new SpreadsheetExtractionAlgorithm();

    ObjectExtractor objectExtractor = new ObjectExtractor(document);
    PageIterator pages = objectExtractor.extract();
    List<Table> tables= new ArrayList<>();
    while (pages.hasNext()) {
      Page page = pages.next();

      algExtractor = algorithm;
      /*if (extractor.isTabular(page)) {
        algExtractor=new SpreadsheetExtractionAlgorithm();
      }
      else {
        algExtractor = new BasicExtractionAlgorithm();
      }*/

      List<Rectangle> tablesOnPage = detectionAlgorithm.detect(page);

      for (Rectangle guessRect : tablesOnPage) {
        Page guess = page.getArea(guessRect);
        tables.addAll(algExtractor.extract(guess));
      }
    }
    return tables;
  }

这在我的单元测试中没有发生。 预先感谢您的帮助!

因为执行的某些代码执行的操作通常但在技术上不一定涉及需要所谓的 'headful' 模式的事情(好吧,这可能不是一个真正的术语,而是相反的, 'headless' 肯定是)。这会导致一些事情发生,包括显示该图标。

解决这个问题的一个简单方法是强制使用无头模式。但请注意,当您执行此操作时,这些 'usually but technically not neccessarily headful' 操作中的任何一个可能 [1] 工作正常并且不再显示该图标,,[2] 崩溃并显示 HeadlessException。您最终得到哪个不仅取决于您正在执行的操作,还取决于您在哪个 VM 上执行操作 - 通常,一旦这些操作之一工作正常并且不再抛出,以后的版本将不会恢复投掷(换句话说,java 的较新版本提供了更多在无头模式下工作的东西)。

要强制使用无头模式,运行 java 和 java -Djava.awt.headless=true

如果您必须在 java 代码中执行此操作,运行 System.setProperty("java.awt.headless", "true"); 至少一次,并且在执行任何这些 'usually causes headful mode' 操作之前。

据推测,导致 headful 模式发生的原因是涉及图形,例如将 JPG 或 PNG 渲染到 ImageBuffer 中。例如,Apache Drill 对 'read' 图像执行此操作并不奇怪。

另一种选择是只升级您的 VM,也许这有帮助。作为一般规则,此行的特征 'move downwards':

  • 需要headful模式; 运行宁它使虚拟机变得头疼(出现图标);如果设置了 java.awt.headless,操作将失败并出现 HeadlessException。
  • 导致头脑模式; 运行宁它使虚拟机变得头疼。但是,如果设置了 headless,它工作正常,不会那样做。
  • 彻底解脱。 运行 代码工作正常,不会导致 VM 头晕目眩。 headless 标志与代码的运行方式没有任何关系。