Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6926209

ClassCastException in sun.font.Font2D

XMLWordPrintable

    • 2d
    • b77
    • x86
    • solaris_8, windows_7
    • Verified

      FULL PRODUCT VERSION :
      java version "1.6.0.05"
      Java(TM) SE Runtime Environment (build 1.6.0.05-jinteg_14_oct_2009_01_44-b00)
      Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01-jre1.6.0.05-rc5, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      HP-UX drsaca05 B.11.31 U ia64 1459067606 unlimited-user license

      A DESCRIPTION OF THE PROBLEM :
      This problem arises because the strikeCacheMap in Font2D is populated by calling StrikeCache.getStrikeRef(FontStrike strike, boolean weak) which can return a SoftReference, WeakReference, or a StrikeCache.DisposableStrike. Font2D assumes everything in strikeCacheMap implements StrikeCache.DisposableStrike and will occasionally throw a ClassCastException as a result.

      I do not know why I'm running into the case where a FontStrike does not have a disposer, but this issue seems resolved after specifying java.awt.headless=true.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided test program on HP-UX. After about 5 minutes, the program should throw the ClassCastException.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No error.
      ACTUAL -
      java.lang.ClassCastException: java.lang.ref.SoftReference cannot be cast to
      sun.font.StrikeCache$DisposableStrike
          at sun.font.Font2D.getStrike(Font2D.java:308)
          at sun.font.Font2D.getStrike(Font2D.java:262)
          at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
          at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
          at
      sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:345)
          at sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:336)
          at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:284)
          at sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:764)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      java.lang.ClassCastException: java.lang.ref.SoftReference cannot be cast to
      sun.font.StrikeCache$DisposableStrike
          at sun.font.Font2D.getStrike(Font2D.java:308)
          at sun.font.Font2D.getStrike(Font2D.java:262)
          at sun.font.CompositeStrike.getStrikeForSlot(CompositeStrike.java:59)
          at sun.font.CompositeStrike.getFontMetrics(CompositeStrike.java:75)
          at
      sun.font.FontDesignMetrics.initMatrixAndMetrics(FontDesignMetrics.java:345)
          at sun.font.FontDesignMetrics.<init>(FontDesignMetrics.java:336)
          at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:284)
          at sun.java2d.SunGraphics2D.getFontMetrics(SunGraphics2D.java:764)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      package fonttest;

      import java.awt.Color;
      import java.awt.Font;
      import java.awt.FontMetrics;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.GraphicsEnvironment;
      import java.awt.Rectangle;
      import java.awt.image.BufferedImage;

      public class Main {

          private static String[] fontNames;
          private static final int SIZE = 100;

          private static void _resetFont(Graphics g) {
              Font font = g.getFont();
              int numfonts = fontNames.length;
              for (int j = 0; j < numfonts; ++j) {
                  String name = fontNames[j];
                  for (int i = 1; i < 100; ++i) {
                      Font f = new Font(name, font.getStyle(), i);
                      g.setFont(f);
                      FontMetrics fm = g.getFontMetrics();
                  }
              }
              System.gc();
              Thread.yield();

              g.setFont(font);
          }

          public static void paint(Graphics g) {
              Font font = new Font("Arial", Font.PLAIN, 9);
              Rectangle r = new Rectangle(0, 0, SIZE, SIZE);
              g.drawLine(0, 0, r.width - 1, r.height - 1);
              g.setColor(new Color(255, 127, 0));
              g.drawLine(0, r.height - 1, r.width - 1, 0);
              g.setFont(font);
              _resetFont(g);
              g.drawString("Test", 32, 8);
          }

          public static void main(String[] args) {
              System.setProperty("java.awt.headless", "false");

             GraphicsEnvironment ge =
              GraphicsEnvironment.getLocalGraphicsEnvironment();
              System.out.println("Headless mode: " + ge.isHeadless());

              fontNames = ge.getAvailableFontFamilyNames();

              BufferedImage image = new BufferedImage(SIZE, SIZE, BufferedImage.TYPE_4BYTE_ABGR);
              Graphics2D gr = image.createGraphics();
              while (true) {
                  try {
                      paint(gr);
                  } catch (Exception e) {
                      e.printStackTrace();
                      System.exit(0);
                  }
              }
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      set java.awt.headless=true

            prr Philip Race
            igor Igor Nekrestyanov (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: