在 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 变量。之后字体扫描过程花费了正常的时间,我的应用程序开始正常工作。
我在其中一个项目中使用 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 变量。之后字体扫描过程花费了正常的时间,我的应用程序开始正常工作。