我不使用JasperServer,而是直接使用JasperReport 4.0.2创建了一个webapp。
模板不在默认的类加载器中,在调用JasperReport之前使用ContextClassLoader
添加了。
在Jasper Report的最新版本中,字体管理按照this document中的说明进行了更改。因此,我需要提供Font JAR,当我直接将它们放在 WEB-INF / lib 目录中时,它可以正常工作。
但是,出于模块化的原因,我想使用与模板相同的ContextClassloader
将它们添加到类路径中,但在这种情况下,文本不会使用正确的字体呈现。
我认为这与JasperReport加载Font的方式有关。
使用调试器,我可以将其追溯到不会返回相同结果的net.sf.jasperreports.engine.util.getFontInfo(...)
方法。
这是因为ExtensionsEnvironment.getExtensionsRegistry().getExtensions(FontFamily.class)
在两种情况下都不返回相同的族列表。仅当JAR位于 WEB-INF / lib 中时才会加载扩展名。
有人知道如何调整net.sf.jasperreports.extensions.getExtensionsRegistry()
来检索threadRegistry实例吗? (必须以某种方式初始化我猜)。
答案 0 :(得分:1)
此问题似乎与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代码中使用的类加载器可以解决问题,但可能会对其他用例产生副作用。