我不使用JasperServer,而是直接使用JasperReport 4.0.2创建了一个Webapp。

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

在最新版本的Jasper Report中,字体管理已按照this document中的指示进行了更改。因此,我需要提供Font JAR,当将它们直接放在WEB-INF / lib目录中时可以使用。

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

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

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

有人知道net.sf.jasperreports.extensions.getExtensionsRegistry()如何可以改用于检索threadRegistry实例吗? (必须以某种方式初始化)。

最佳答案

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

当JasperReport加载扩展名(懒惰,第一次使用时)时,字体扩展名使用JasperReport Classloader,而不是上下文类加载器。

 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代码中使用的类加载器可以解决此问题,但是可能会对其他用例产生副作用。

10-08 13:35
查看更多