【问题标题】:OpenJDK 11 java.lang.ClassCastException: class sun.font.CompositeFont cannot be cast to class sun.font.PhysicalFontOpenJDK 11 java.lang.ClassCastException:类 sun.font.CompositeFont 不能转换为类 sun.font.PhysicalFont
【发布时间】:2019-02-06 13:19:25
【问题描述】:

我在 Linux 上使用 openJDK 11 运行 junit 测试并收到以下错误:

java.lang.ClassCastException: class sun.font.CompositeFont cannot be cast to class sun.font.PhysicalFont (sun.font.CompositeFont and sun.font.PhysicalFont are in module java.desktop of loader 'bootstrap')
    at java.desktop/sun.font.SunFontManager.getDefaultPhysicalFont(SunFontManager.java:1086)
    at java.desktop/sun.font.SunFontManager.initialiseDeferredFont(SunFontManager.java:965)
    at java.desktop/sun.font.SunFontManager.findOtherDeferredFont(SunFontManager.java:903)
    at java.desktop/sun.font.SunFontManager.findDeferredFont(SunFontManager.java:919)
    at java.desktop/sun.font.SunFontManager.findFont2D(SunFontManager.java:2120)
    at java.desktop/java.awt.Font.getFont2D(Font.java:506)
    at java.desktop/java.awt.Font.canDisplayUpTo(Font.java:2246)
    at java.desktop/java.awt.font.TextLayout.singleFont(TextLayout.java:469)
    at java.desktop/java.awt.font.TextLayout.<init>(TextLayout.java:530)
    at org.apache.poi.ss.util.SheetUtil.getDefaultCharWidth(SheetUtil.java:275)
    at org.apache.poi.xssf.streaming.AutoSizeColumnTracker.<init>(AutoSizeColumnTracker.java:117)
    at org.apache.poi.xssf.streaming.SXSSFSheet.<init>(SXSSFSheet.java:82)
    at org.apache.poi.xssf.streaming.SXSSFWorkbook.createAndRegisterSXSSFSheet(SXSSFWorkbook.java:658)
    at org.apache.poi.xssf.streaming.SXSSFWorkbook.createSheet(SXSSFWorkbook.java:679)
    at com.textb2.ui.controller.ExcelCreator.newSheet(ExcelCreator.java:135)
    at com.textb2.ui.controller.ExcelCreator.buildExcel(ExcelCreator.java:182)
    at com.textb2.ui.controller.ExcelCreatorTest.testNoData(ExcelCreatorTest.java:91)
    at com.textb2.ui.controller.ExcelCreatorTest.testGermany(ExcelCreatorTest.java:53)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

不确定,但它必须与 /usr/share/fonts 中的字体有关。目前我那里没有字体。我知道 openJdk11 不再包含字体了。但我不确定该怎么做。

谢谢...

刚刚在旧版本中发现了一个已修复的错误: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8144703

【问题讨论】:

  • 为整个单元测试添加代码。请参阅:stackoverflow.com/help/mcve 我的猜测是您可能一直在使用内部 sun 类,这些类不能保证在版本之间存在。这也是从 jdk8 到 jdk11 的类加载器所发生的情况,内部基类和实现类发生了变化,人们向它们进行转换时遇到了这些类型的故障。

标签: java fonts apache-poi java-11


【解决方案1】:

OpenJDK 11 似乎不再包含一些与字体相关的内容,而且您的操作系统目前本身也没有提供任何内容。

您可以尝试在您的操作系统中安装一些与字体相关的软件包,看看是否可以解决问题。

另请参阅https://www.oracle.com/technetwork/java/javase/11-relnote-issues-5012449.html#JDK-8191522 的发行说明

【讨论】:

    【解决方案2】:

    在 Ubuntu 18.0.4 LTS 上,以下命令修复了该问题

    sudo apt-get install fontconfig

    【讨论】:

      【解决方案3】:

      我认为您必须安装一些字体,否则在到达这一点之前您会收到 NullPointerException。

      这个简单的程序可以运行吗,如果没有安装字体会失败?

      import java.awt.*;
      public class Fonts
      {
           public static void main(String[] args) throws Exception
           {
               Font defaultFont = Font.decode(null);
               System.out.println(defaultFont);
           }
      }
      

      我认为问题更多在于您的字体配置不正确正确,很明显 getDefaultPhysicalFont() 希望获得 PhysicalFont 类型的字体,但实际上得到 CompositeFont 类型之一,不清楚为什么会这样。

      尝试运行

      fc-cache -rv *pathoffonts*
      

      例如

      fc-cache -rv /usr/share/fonts
      

      当我也使用 Jakarta Poi 添加相同的错误时,这似乎对我有用,但是我还没有得到一致的结果。

      【讨论】:

        【解决方案4】:

        在我们的例子中,我们有一个在 K8s 上运行的服务,它会在第一次请求时抛出这个错误,但在后续请求中运行良好。通过在我们的 Dockerfile 的基础镜像中安装 DejaVu 解决了这个问题,as some people recommended here

        类似

        FROM <my base image> AS EXPLODED
        RUN apk add --update ttf-dejavu && rm -rf /var/cache/apk/*
        

        构建镜像,将其推送到 Harbor 并使用新镜像作为基础镜像。

        【讨论】:

          猜你喜欢
          • 2021-07-21
          • 2021-04-30
          • 2020-03-25
          • 1970-01-01
          • 2022-08-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多