【问题标题】:FOP throws "IllegalArgumentException: URI is not absolute" when running in a jarFOP 在 jar 中运行时抛出“IllegalArgumentException:URI 不是绝对的”
【发布时间】:2016-04-28 12:14:37
【问题描述】:

我正在使用 Spring Boot 和 FOP 生成 PDF 并发送回 UI 组件。当我使用“mvn spring-boot:run”运行 Spring Boot 应用程序时,一切正常(动态生成 PDF 并在 UI 中呈现),但是,如果我将此 Spring Boot 应用程序打包在一个 jar 中并通过“ java -jar xxx.jar”,我遇到了FOP引发的以下错误:

java.lang.IllegalArgumentException: URI is not absolute
at java.net.URI.toURL(URI.java:1088)
at org.apache.fop.fonts.FontDetectorFactory$DefaultFontDetector.detect(FontDetectorFactory.java:94)
at org.apache.fop.fonts.FontManager.autoDetectFonts(FontManager.java:229)
at org.apache.fop.fonts.DefaultFontConfigurator.configure(DefaultFontConfigurator.java:82)
at org.apache.fop.render.PrintRendererConfigurator.getCustomFontCollection(PrintRendererConfigurator.java:147)
at org.apache.fop.render.PrintRendererConfigurator.setupFontInfo(PrintRendererConfigurator.java:127)
at org.apache.fop.render.intermediate.IFUtil.setupFonts(IFUtil.java:170)
at org.apache.fop.render.intermediate.IFRenderer.setupFontInfo(IFRenderer.java:187)
at org.apache.fop.area.RenderPagesModel.<init>(RenderPagesModel.java:75)
at org.apache.fop.area.AreaTreeHandler.setupModel(AreaTreeHandler.java:135)
at org.apache.fop.area.AreaTreeHandler.<init>(AreaTreeHandler.java:105)
at org.apache.fop.render.RendererFactory.createFOEventHandler(RendererFactory.java:350)
at org.apache.fop.fo.FOTreeBuilder.<init>(FOTreeBuilder.java:107)
at org.apache.fop.apps.Fop.createDefaultHandler(Fop.java:104)
at org.apache.fop.apps.Fop.<init>(Fop.java:78)
at org.apache.fop.apps.FOUserAgent.newFop(FOUserAgent.java:182)
at org.apache.fop.apps.FopFactory.newFop(FopFactory.java:240)

...

FopFactory 是在一行中使用配置文件 (fop.xconf) 的 InputStream 创建的:

fopFactory = FopFactory.newInstance(fopConfig.getURI(),fopConfig.getInputStream());
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);

我怀疑异常与 fop.xconf 中的字体配置有关,我在其中放置了两行添加中文字体支持:

    <font kerning="yes" embed-url="/Users/matrix/Library/Fonts/msyh.ttf" embedding-mode="subset">
      <font-triplet name="MicrosoftYaHei" style="normal" weight="normal"/>
    </font>
    <font kerning="yes" embed-url="/Users/matrix/Library/Fonts/msyhbd.ttf" embedding-mode="subset">
      <font-triplet name="MicrosoftYaHei" style="normal" weight="bold"/>
    </font>

我的问题是: 1) 这真的是与 fop.xconf 文件中的字体配置有关的问题吗?

2) 如果是,我该如何解决?

3) FOP 是否有更好的方法来支持中文字体,例如利用主机上安装的系统字体,而不是每个字体系列的硬编码字体配置。

非常感谢您的帮助。

【问题讨论】:

  • 你能分享一个重现问题的完整最小示例吗?
  • 让我提供几个 cmets:您的 embed-url 值确实是相对路径 URL,因此只有当进程在系统上的正确位置运行时,才能成功找到这些字体,指定它们的位置并不是一个真正可靠的方法。您还可以通过暂时取出那些
  • @acg_so 建议被采纳。嵌入的 url 是绝对路径(我使用的是 Mac,所以这是字体文件的绝对路径)。看起来不同的类加载器导致了这个问题。 Spring boot 应用程序,如果作为 jar 运行,则使用 LaunchedURLClassLoader,但是,如果使用“mvn spring-boot:run”运行,则使用的类加载器是标准的 java.net.URLClassLoader。我试图通过从 fop.xconf 中删除一些配置来隔离问题。如果我有一些进展会报告。

标签: spring-boot pdf-generation apache-fop


【解决方案1】:

经过一番挖掘,问题解决了。这是因为 Spring Boot 在以不同模式运行 Spring Boot 应用程序时使用了不同的类加载器,例如,作为 jar 运行或作为 Web 应用程序运行。以下是我为解决此问题所做的更改:

<font kerning="yes" embed-url="file:/Users/matrix/Library/Fonts/msyh.ttf" embedding-mode="subset">
  <font-triplet name="MicrosoftYaHei" style="normal" weight="normal"/>
</font>
<font kerning="yes" embed-url="file:/Users/matrix/Library/Fonts/msyhbd.ttf" embedding-mode="subset">
  <font-triplet name="MicrosoftYaHei" style="normal" weight="bold"/>
</font>

请注意嵌入网址中使用的“文件:”。这是解决这个问题的关键。

由于不同的类加载器,我在 xslt 样式表中使用 时遇到了同样的问题。根据使用的类加载器,fop 可能找不到具有相对路径的外部图像。所以我必须使用以“http”开头的绝对网址,并将我的图像作为公共资源,这对我来说没问题,因为它们是徽标和图标。

【讨论】:

    【解决方案2】:

    当我从资源 (embed-url="/fonts/times.ttf") 中引用字体时,我遇到了类似的问题(java.lang.IllegalArgumentException: URI is not absolute)。使用 "classpath:" (embed-url="classpath:/fonts/times.ttf") 作为前缀可以解决问题,并且 FOP 可以正确找到字体。

    【讨论】:

    • 这并没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review
    • 有没有办法可以在这个特定线程下提供这些信息?我的评论可能对其他面临与 Apache FOP 组合的相同错误消息的人有所帮助,尽管它没有提供主要问题的答案。当我在寻找解决方案时,我会很感激这些信息。我在任何地方都找不到解决方案 - 我的同事帮助了我。
    猜你喜欢
    • 2021-12-28
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多