2012-02-28 147 views
3

我不使用JasperServer,而是直接使用JasperReport 4.0.2创建了一个webapp。JasperReport加载字体扩展

模板不在默认的类加载器中,在调用JasperReport之前,使用ContextClassLoader添加了模板。

在最新版本的Jasper Report字体管理中,如this document所示更改。因此,我需要提供字体JAR,这些字体JAR在我直接将其放入目录中时起作用。

但是,出于模块化的原因,我想将它们添加到使用与模板相同的ContextClassloader的类路径中,但在这种情况下,文本不会使用正确的字体呈现。

我的确认为这与JasperReport加载字体的方式有关。 使用调试器我可以追溯到net.sf.jasperreports.engine.util.getFontInfo(...)方法,该方法不会返回相同的结果。

这是由于在两种情况下ExtensionsEnvironment.getExtensionsRegistry().getExtensions(FontFamily.class)都不会返回相同的族列表。仅当JAR位于WEB-INF/lib中时才会加载扩展。

是否有人知道net.sf.jasperreports.extensions.getExtensionsRegistry()可以如何适应检索threadRegistry实例呢? (必须以某种方式初始化我猜)。

回答

1

这个问题似乎是http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=76180

重复的JasperReport时加载扩展(懒洋洋地,在第一次使用)的字体扩展名是使用JasperReport的类加载器,而不是上下文类加载器。

From JRLoader.getClassLoaderResources(String) line: 
      Map<URL, ClassLoaderResource> resources = 
        new LinkedHashMap<URL, ClassLoaderResource>(); 
      collectResources(resource, JRLoader.class.getClassLoader(), resources); 

JRLoader.collectResources然后通过迭代上.getParent()得到所有的类加载器的列表。

使用Thread.currentThread().getContextClassLoader()而不是处理错误应该提供扩展类加载器(其需要将JRLoader.class.getClassLoader()设置为父类)。

更改JasperReport代码中使用的类加载器可以修复问题,但可能会对其他用例产生副作用。

+0

我还有另一个问题,因为在生成文档时ContextClassLoader被设置回早。我把它在finally块中移动。请参阅http://stackoverflow.com/questions/3151562/jasperreports-how-to-add-font-not-in-the-application-classpath进行相关的解释 – 2012-02-29 15:33:22