https://issues.apache.org/bugzilla/show_bug.cgi?id=46336

           Summary: Synchronization fault in FontInfoFinder
           Product: Fop
           Version: 0.95
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: fonts
        AssignedTo: fop-dev@xmlgraphics.apache.org
        ReportedBy: [EMAIL PROTECTED]


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 {
159                     fileLastModified = conn.getLastModified();
160                 } 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) {
173                     return fontInfo;
174                 } 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()) {
181                     log.debug("Skipping font file that failed to load
previously: " + embedUrl);
182                 }
183                 return null;
184             }
185         }
186         
187         // try to determine triplet information from font file
188         CustomFont customFont = null;
189         try {
190             customFont = FontLoader.loadFont(fontUrl, resolver);
191         } 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()) {
194                 log.error("Unable to load font file: " + embedUrl + ".
Reason: " + e.getMessage());
195             }
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.


-- 
Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.

Reply via email to