Uploaded image for project: 'FOP'
  1. FOP
  2. FOP-1608

[PATCH] Synchronization fault in FontInfoFinder

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Resolution: Unresolved
    • 2.5
    • None
    • font/unqualified
    • 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

      { 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.

      Attachments

        1. b46336.diff
          8 kB
          Andreas L. Delmelle
        2. b46336.diff
          8 kB
          Andreas L. Delmelle
        3. b46336.diff
          7 kB
          Andreas L. Delmelle

        Activity

          People

            Unassigned Unassigned
            rogov@devexperts.com ilj
            Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: