2012-02-28 148 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