在 CentOS 上的 Apache FOP 中无限扫描字体

Infinite scan for fonts in Apache FOP on CentOS

我在其中一个项目中使用 Apache Batik 将 SVG 转换为 PDF。该项目是 Spring application 运行ning in Tomcat 7. 在 运行s under Ubuntu 和 Tomcat 正在启动的开发机器上一切正常使用 $CATALINA_HOME/bin/startup.sh。但是当我尝试 运行 使用 CentOS 6 的生产服务器上的应用程序并且 Tomcat 开始使用 service tomcat7 start 命令时,应用程序在转换时陷入无限循环。我尝试调试问题并找到了这段代码:

/**
 * Creates the {@link FontInfo} instance for the given configuration.
 * @param cfg the configuration
 * @param useComplexScriptFeatures true if complex script features enabled
 * @return the font collection
 * @throws FOPException if an error occurs while setting up the fonts
 */
public static FontInfo createFontInfo(Configuration cfg, boolean useComplexScriptFeatures)
    throws FOPException {
    FontInfo fontInfo = new FontInfo();
    final boolean strict = false;
    if (cfg != null) {
        URI thisUri = new File(".").getAbsoluteFile().toURI();
        InternalResourceResolver resourceResolver
                = ResourceResolverFactory.createDefaultInternalResourceResolver(thisUri);
        //TODO The following could be optimized by retaining the FontManager somewhere
        FontManager fontManager = new FontManager(resourceResolver, FontDetectorFactory.createDefault(),
                FontCacheManagerFactory.createDefault());

        //TODO Make use of fontBaseURL, font substitution and referencing configuration
        //Requires a change to the expected configuration layout

        DefaultFontConfig.DefaultFontConfigParser parser
                = new DefaultFontConfig.DefaultFontConfigParser();
        DefaultFontConfig fontInfoConfig = parser.parse(cfg, strict);
        DefaultFontConfigurator fontInfoConfigurator
                = new DefaultFontConfigurator(fontManager, null, strict);
        List<EmbedFontInfo> fontInfoList = fontInfoConfigurator.configure(fontInfoConfig);
        fontManager.saveCache();
        FontSetup.setup(fontInfo, fontInfoList, resourceResolver, useComplexScriptFeatures);
    } else {
        FontSetup.setup(fontInfo, useComplexScriptFeatures);
    }
    return fontInfo;
}

PDFDocumentGraphics2DConfigurator class 中。当我 运行 在开发者机器上安装应用程序时, URI thisUri = new File(".").getAbsoluteFile().toURI(); 行的结果是 thisUri 被分配了 ~/tomcat/bin/. 文件夹。当应用程序在生产机器上 运行ning 时,它被分配了 /. 值。我认为这是主要问题,因为 thisUri 的值是 FOP 开始字体搜索的文件夹,在生产机器上这是文件系统的根目录,并且对整个 FS 结构的递归搜索非常慢。我尝试使用字体配置将 fop.xconf 文件添加到 WEB-INF 目录,但它没有影响 FOP 的行为。而且我无法像在开发机器上一样在生产服务器上启动 Tomcat。 有没有人知道如何配置 FOR 字体扫描的基本目录?还是我做错了什么?

我找到了解决该问题的方法。我不确定这样做是对还是错,但它确实有效。变通方法基于以下事实:File.getAbsolutFile() 默认情况下 returns 目录根据 user.dir 选项定义的目录进行解析。所以我需要一些方法在 Tomcat 服务启动时传递这个选项。我发现这样做的唯一方法是将 -Duser.dir=/%CATALINA_HOME/ 添加到 %CATALINA_HOME/bin/setenv.sh 文件中定义的 CATALINA_OPTS 变量。之后字体扫描过程花费了正常的时间,我的应用程序开始正常工作。