Spring boot FOP在jar中运行时抛出“IllegalArgumentException:URI不是绝对的”

Spring boot FOP在jar中运行时抛出“IllegalArgumentException:URI不是绝对的”,spring-boot,pdf-generation,apache-fop,Spring Boot,Pdf Generation,Apache Fop,我使用SpringBoot和FOP生成PDF并发送回UI组件。当我使用mvn Spring Boot:run everything works运行Spring Boot应用程序时,PDF会动态生成并在UI中呈现,但是,如果我将此Spring Boot应用程序打包在一个jar中并通过java-jar xxx.jar运行,我遇到了FOP引发的以下错误: java.lang.IllegalArgumentException: URI is not absolute at java.net.URI.to

我使用SpringBoot和FOP生成PDF并发送回UI组件。当我使用mvn Spring Boot:run everything works运行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)
我怀疑这个异常与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是否有更好的方法支持中文字体,例如,利用主机上安装的系统字体,而不是每个字体系列的硬编码字体配置


非常感谢您的帮助。

经过一番挖掘,问题解决了。这是因为SpringBoot在不同模式下运行SpringBoot应用程序时使用了不同的类加载器,例如,作为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>
请注意文件:用于嵌入的url。这是解决这个问题的关键


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

我也有类似的问题java.lang.IllegalArgumentException:当我从参考资料embed url=/font/times.ttf中引用字体时,URI不是绝对的。在它前面加上classpath:embed url=classpath:/font/times.ttf修复了这个问题,FOP可以正确地找到字体。

你能分享一个再现这个问题的完整的最小示例吗?让我提供一些评论:你的嵌入url值确实是相对路径url,因此,只有当流程在系统上的正确位置工作时,才能成功找到这些字体,而不是一种真正可靠的方法来指定它们的位置。您还可以备份一个步骤,根据您的问题1,通过采用这些@acg_确认错误,以便采纳建议。嵌入的URL是绝对路径,我正在使用Mac,所以这是字体文件的绝对路径。看起来是不同的类加载器导致了这个问题。Spring boot应用程序,如果作为jar运行,则使用LaunchedURLClassLoader,但是,如果使用mvn Spring boot:run运行,则使用的classloader是标准的java.net.URLClassLoader。我试图通过从fop.xconf中删除一些配置来隔离这个问题。如果我有一些进展,我将报告。这并不能回答问题。一旦你有足够的钱,你将能够;相反有没有办法在这个特定的线程下提供这些信息?我的评论可以帮助其他人在使用ApacheFop组合时遇到相同的错误消息,尽管它没有提供主要问题的答案。当我在寻找解决方案时,我将非常感谢这些信息。我到处都找不到解决办法——我的同事帮了我。
<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>