Details
-
Bug
-
Status: Open
-
Resolution: Unresolved
-
2.5
-
None
-
None
-
Operating System: All
Platform: All
-
46336
Description
I have a multi-threaded rendering application. It produced this exception:
java.lang.NullPointerException
at org.apache.fop.fonts.autodetect.FontInfoFinder.find(FontInfoFinder.java:172)
at org.apache.fop.render.PrintRendererConfigurator.addFontInfoListFromFileList(PrintRendererConfigurator.java:233)
at org.apache.fop.render.PrintRendererConfigurator.buildFontListFromConfiguration(PrintRendererConfigurator.java:140)
at org.apache.fop.render.PrintRendererConfigurator.configure(PrintRendererConfigurator.java:95)
at org.apache.fop.render.pdf.PDFRendererConfigurator.configure(PDFRendererConfigurator.java:71)
at org.apache.fop.render.RendererFactory.createRenderer(RendererFactory.java:187)
at org.apache.fop.area.RenderPagesModel.<init>(RenderPagesModel.java:68)
at org.apache.fop.area.AreaTreeHandler.setupModel(AreaTreeHandler.java:127)
at org.apache.fop.area.AreaTreeHandler.<init>(AreaTreeHandler.java:102)
at org.apache.fop.render.RendererFactory.createFOEventHandler(RendererFactory.java:224)
at org.apache.fop.fo.FOTreeBuilder.<init>(FOTreeBuilder.java:100)
at org.apache.fop.apps.Fop.createDefaultHandler(Fop.java:100)
at org.apache.fop.apps.Fop.<init>(Fop.java:78)
at org.apache.fop.apps.FopFactory.newFop(FopFactory.java:247)
...
I guess the problem is, that you don't synchronize usage of FontCache in this method:
150 public EmbedFontInfo find(URL fontUrl, FontResolver resolver, FontCache fontCache) {
151 String embedUrl = null;
152 embedUrl = fontUrl.toExternalForm();
153
154 long fileLastModified = -1;
155 if (fontCache != null) {
156 try {
157 URLConnection conn = fontUrl.openConnection();
158 try
finally
{ 161 //An InputStream is created even if it's not accessed, but we need to close it. 162 IOUtils.closeQuietly(conn.getInputStream()); 163 }164 } catch (IOException e)
{ 165 // Should never happen, because URL must be local 166 log.debug("IOError: " + e.getMessage()); 167 fileLastModified = 0; 168 }169 // firstly try and fetch it from cache before loading/parsing the font file
170 if (fontCache.containsFont(embedUrl)) {
171 CachedFontInfo fontInfo = fontCache.getFont(embedUrl);
172 if (fontInfo.lastModified() == fileLastModified)
else
{ 175 // out of date cache item 176 fontCache.removeFont(embedUrl); 177 }178 // is this a previously failed parsed font?
179 } else if (fontCache.isFailedFont(embedUrl, fileLastModified)) {
180 if (log.isDebugEnabled())
183 return null;
184 }
185 }
186
187 // try to determine triplet information from font file
188 CustomFont customFont = null;
189 try
catch (Exception e) {
192 //TODO Too verbose (it's an error but we don't care if some fonts can't be loaded)
193 if (log.isErrorEnabled())
196 if (fontCache != null)
{ 197 fontCache.registerFailedFont(embedUrl, fileLastModified); 198 }199 return null;
200 }
201 return fontInfoFromCustomFont(fontUrl, customFont, fontCache);
202 }
203 }
204
When thread1 and thread2 both enter IF at line 170, one can remove the font and then the other will get null at line 171.