Java 11 没有字体?

标签 java aws-lambda fonts apache-poi

我将 Java 11 Corretto + Spring Boot 与 Apache POI 结合使用,但在 AWS Lambda 上使用时遇到问题。如果我作为“普通”API 运行时工作正常,但在 AWS lambda 中运行无服务时失败。

try (ByteArrayOutputStream out = new ByteArrayOutputStream(); SXSSFWorkbook workbook = new SXSSFWorkbook(1000)) {
    SXSSFSheet sheet = workbook.createSheet("test"); //error here!!
    } ...

Caused by: java.lang.Error: Probable fatal error: No physical fonts found. at java.desktop/sun.font.SunFontManager.lambda$getDefaultPhysicalFont$0(Unknown Source) at java.base/java.util.Optional.orElseThrow(Unknown Source) at java.desktop/sun.font.SunFontManager.getDefaultPhysicalFont(Unknown Source) at java.desktop/sun.font.CompositeFont.doDeferredInitialisation(Unknown Source) at java.desktop/sun.font.CompositeFont.getSlotFont(Unknown Source) at java.desktop/sun.font.CompositeGlyphMapper.initMapper(Unknown Source) at java.desktop/sun.font.CompositeGlyphMapper.(Unknown Source) at java.desktop/sun.font.CompositeFont.getMapper(Unknown Source) at java.desktop/sun.font.CompositeFont.canDisplay(Unknown Source) at java.desktop/java.awt.Font.canDisplayUpTo(Unknown Source) at java.desktop/java.awt.font.TextLayout.singleFont(Unknown Source) at java.desktop/java.awt.font.TextLayout.(Unknown Source) at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:285) at org.apache.poi.xssf.streaming.AutoSizeColumnTracker.(AutoSizeColumnTracker.java:117) at org.apache.poi.xssf.streaming.SXSSFSheet.(SXSSFSheet.java:84) at org.apache.poi.xssf.streaming.SXSSFWorkbook.createAndRegisterSXSSFSheet(SXSSFWorkbook.java:705) at org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:724)

我试图对字体进行修复,但我不知道如何进行

@PostConstruct
public void loadFonts() {
    URL configURL = getClass().getClassLoader().getResource("fontconfig.properties");
    String path = configURL != null ? configURL.getPath() : null;
    Properties props = System.getProperties();
    LOGGER.info("Loading font config file: {}", path);
    props.put("sun.awt.fontconfig", path);

    String[] fonts;
    try {
        GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    } catch (Throwable ex) {
        LOGGER.warn("Reloading Fonts");
    }
    try {
        fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        for (String font : fonts) {
            LOGGER.info("Available Font: {}", font);
        }
    } catch (Throwable ex) {
        LOGGER.error("Could not load Fonts");
    }
}

配置文件:

version=1
sequence.allfonts=default

在 AWS Lambda 上运行时,它会向日志输出一些字体,所以我不明白为什么会出现该错误:

2022-05-31 16:00:14  INFO  Starting Lambda Container Handler
2022-05-31 16:00:18  INFO  Loading font config file: /var/task/fontconfig.properties
2022-05-31 16:00:18  INFO  Available Font: Dialog
2022-05-31 16:00:18  INFO  Available Font: DialogInput
2022-05-31 16:00:18  INFO  Available Font: Monospaced
2022-05-31 16:00:18  INFO  Available Font: SansSerif
2022-05-31 16:00:18  INFO  Available Font: Serif

知道如何添加物理字体以及为什么 POI 不能使用输出到日志的可用字体吗?

编辑: 我也尝试过 headless 运行,但我得到了同样的错误:

`props.setProperty("java.awt.headless", "true");`

最佳答案

字体捆绑

Any idea how to add physical fonts

来自 Oracle 的 Oracle JDK 产品 stopped bundling fonts从 Java 11 开始。

OpenJDK项目不捆绑字体,至少在最近的版本中没有。

Amazon 产品的 Corretto JDK 基于 OpenJDK 代码库。根据您的报告,显然他们没有捆绑字体。

您必须选择:

  • 依赖主机操作系统提供的字体。
  • 在您的 Java 应用程序中捆绑字体。仔细研究许可条款。有些字体允许这样的捆绑,有些则不允许。有些需要收费,有些则不需要。有些需要确认,有些则不需要。
  • 从供应商处获取包含字体的 JDK。

我知道至少有一家这样的供应商:Azul Systems 将字体与其 Azul Platform Core 商业产品捆绑在一起。

可能还有其他我不知道的此类供应商。许多供应商提供 JDK 二进制文件和安装程序。这些供应商包括 Adoptium、SAP、BellSoft、Microsoft、Azul Systems、Amazon、Oracle、Red Hat/IBM、Pivo​​tal 等。

物理字体与逻辑字体

why can't the POI use the available fonts that output to the logs

您在日志中列出的字体是逻辑 字体,而不是物理 字体。 Font 的 Javadoc 中清楚地记录了这种区别。类。

要使用逻辑字体名称,您必须有一些支持物理字体。如果您的应用、JDK 或主机操作系统中不存在任何字体,则逻辑字体无法工作。

AWS Lambda 字体

关于在 AWS Lambda 中提供字体,也许这两页可能会有所帮助。 (感谢 jarmod for the links。)

基本思想是在您的包中创建一个/fonts 文件夹。在其中包含一个带有 XML 配置元素的 fonts.conf 文件。将捆绑的字体文件放在该配置文件旁边。

关于Java 11 没有字体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72451039/

相关文章:

amazon-web-services - AWS lambda 捕获 IoT 注册事件

html - Gmail 未显示正确的字体

html - 浏览器无法正确显示阿拉伯字体

java - 在 Java 中,为什么在使用二进制搜索搜索数组时返回负数?

aws-lambda - Lambda 支持的自定义资源 cf 模板返回 'CREATE_FAILED'

node.js - mongoose 从 MongoDB (NodeJS/AWS Lambda) 检索空数组

pdf - 将 Arial Unicode MS 添加到 CKEditor

java - Play Framework/Java : A good way to send x-www-form-urlencoded data back

java - StringBuilder 和 ResultSet 性能问题的可能原因是什么

java - 有什么方便的方法可以将 w3c Document 转换为 jsoup one