[OpenJDK 2D-Dev] NPE in X11FontManager.getDefaultPlatformFont

Jeremy Manson jeremymanson at google.com
Wed Jun 5 16:38:17 UTC 2013


I don't have enough of an understanding of the issues to say that this
configuration should necessarily be supported.  However, I am relatively
sure that it shouldn't be supported just enough to make the error and the
code confusing.  If it doesn't find any fonts, FontConfigManager logs
something to the platform logger and returns quietly.

      213         if (anyFont == null) {
      214             if (FontUtilities.isLogging()) {
      215                 PlatformLogger logger = FontUtilities.getLogger();
      216                 logger.info("Fontconfig returned no fonts at
all.");
      217             }
      218             fontConfigFailed = true;
      219             return;

and then when the X11FontManager "believes" it doesn't find a default font,
it does a fallback:

      787         /* Absolute last ditch attempt in the face of fontconfig
problems.
      788          * If we didn't match, pick the first, or just make
something
      789          * up so we don't NPE.
      790          */
      791         if (info[0] == null) {
      792             if (fontConfigFonts.length > 0 &&
      793                 fontConfigFonts[0].firstFont.fontFile != null) {
      794                 info[0] = fontConfigFonts[0].firstFont.familyName;
      795                 info[1] = fontConfigFonts[0].firstFont.fontFile;
      796             } else {
      797                 info[0] = "Dialog";
      798                 info[1] = "/dialog.ttf";
      799             }
      800         }

That would make the casual reader believe that "no fonts" is a supported
configuration (or, at least, a configuration that isn't supposed to NPE).
 But the fallback doesn't get hit in this case, because the X11FontManager
believes that getFontConfigFonts can't return null.

It seems reasonable to throw an exception, if that's what you want to do,
but it seems to me that the exception should have a relatively clear
message about what happened, and the fact that that configuration is
unsupported.  If you really want not to have code that deals with a lack of
fonts, it would make a certain amount of sense to take out the code that is
there and tries to do so.  As it is, the code and its behavior occupy a
very confusing middle ground, where the developer has to trace through the
library to figure out what happened and why it happened.

(As for not linking with libfontconfig: we're trying to make a JDK that
works regardless of whether fontconfig is there.  It should be able to work
in headless, stripped down mode, and for a developer who wants to use
eclipse.  I don't mind if devs need to catch exceptions on the headless
machines, but they like to know why they are catching them.)

Jeremy



On Wed, Jun 5, 2013 at 1:56 AM, Jiri Vanek <jvanek at redhat.com> wrote:

> Hi!
>
>
> This is known issue - Openjdk fails when no fonts are installed.
>
> You can fix this by your own fontmanager (feel free to inspire at
> https://bugzilla.redhat.com/**show_bug.cgi?id=862355#c5<https://bugzilla.redhat.com/show_bug.cgi?id=862355#c5>where I'm creating an custom dummy fontmanager in case of failure)
> You can set up similar manager class by -Dsun.font.fontmanager property.
>
> Or you can support me and "force somebody" to review my patch where I have
> tried to smuggle inside Openjdk default fallback font[1]
>
> On the contrary, if [1] will go in, then it can mask deeper problems (as
> can be eg yours).
>
>
>
> [1]http://mail.openjdk.java.**net/pipermail/2d-dev/2013-**
> January/002999.html<http://mail.openjdk.java.net/pipermail/2d-dev/2013-January/002999.html>
>
>
> Best regards
>  J.
>
>
>
> On 06/05/2013 01:32 AM, Jeremy Manson wrote:
>
>> Hi Phil,
>>
>> Thanks for the response.  You've actually caught me out: this was a bug I
>> found a while ago, and am
>> only now just getting around to reporting.  I made this change locally
>> (inside Google), and lost my
>> repro instructions.  It was probably for a user issue, which means that
>> I'm too chicken to back it
>> out and see what happens.  This fix looked obvious enough that I thought
>> I could get away with it,
>> since it is clearly the case that X11FontManager expects a non-null
>> fontConfigFonts regardless of
>> the value of fontConfigFailed.
>>
>> IIRC, the cause was either that the fontconfig library wasn't installed
>> or that the fontconfig file
>> was obsolete / incorrect for the given system.  I almost certainly did
>> not fix any ULEs (I would
>> have a record of that).  We have some stripped down systems, and this may
>> have been one of them.  It
>> was a headless configuration.  I did preserve my stack trace:
>>
>> Exception in thread "main" java.lang.NullPointerException at
>> sun.awt.X11FontManager.**getDefaultPlatformFont(**X11FontManager.java:779)
>> at
>> sun.font.SunFontManager$2.run(**SunFontManager.java:428) at
>> java.security.**AccessController.doPrivileged(**Native Method) at
>> sun.font.SunFontManager.<init>**(SunFontManager.java:371) at
>> sun.awt.X11FontManager.<init>(**X11FontManager.java:32) at
>> sun.reflect.**NativeConstructorAccessorImpl.**newInstance0(Native
>> Method) at
>> sun.reflect.**NativeConstructorAccessorImpl.**newInstance(**
>> NativeConstructorAccessorImpl.**java:57) at
>> sun.reflect.**DelegatingConstructorAccessorI**mpl.newInstance(**
>> DelegatingConstructorAccessorI**mpl.java:45)
>> at java.lang.reflect.Constructor.**newInstance(Constructor.java:**530) at
>> java.lang.Class.newInstance0(**Class.java:372) at
>> java.lang.Class.newInstance(**Class.java:325) at
>> sun.font.FontManagerFactory$1.**run(FontManagerFactory.java:**80) at
>> java.security.**AccessController.doPrivileged(**Native Method) at
>> sun.font.FontManagerFactory.**getInstance(**FontManagerFactory.java:71)
>> at
>> sun.java2d.**SunGraphicsEnvironment.**getFontManagerForSGE(**
>> SunGraphicsEnvironment.java:**185) at
>> sun.java2d.**SunGraphicsEnvironment.**getAllFonts(**
>> SunGraphicsEnvironment.java:**192) at
>> sun.java2d.**HeadlessGraphicsEnvironment.**getAllFonts(**
>> HeadlessGraphicsEnvironment.**java:91)
>>
>> I'm sure that the line numbers are obsolete, but you get the general
>> idea. I don't seem to have what
>> was beneath that in the stack, but I imagine it was something that was
>> relatively comfortable with
>> getAllFonts returning nothing (as appropriate).
>>
>> Having said all that, it seems to me that if fontConfigFailed is not
>> allowed to be true unless you
>> have a system configuration problem, then that should be made clear at
>> runtime, and that you should
>> not get rather mysterious NPEs at later points in the code.  You do have
>> a fallback in
>> getDefaultPlatformFont that says "make something up so that we don't get
>> NPE", which made me think
>> that the original author intended to prefer avoiding NPEs.
>>
>> Jeremy
>>
>>
>> On Tue, Jun 4, 2013 at 3:29 PM, Phil Race <philip.race at oracle.com<mailto:
>> philip.race at oracle.com**>>
>>
>> wrote:
>>
>>     Jeremy,
>>
>>     Why didn't it return any fonts ? Is this because the libfontconfig
>> library isn't installed ?
>>
>>     We've been runtime loading that lib but these days could potentially
>>     switch to linking against it at compile time, in which case you won't
>>     even get this far. So in other words this could be a system config
>> issue.
>>     The most common thing I've seen is that 64 bit Linux doesn't have
>>     all the libs to run a 32 bit JRE. You probably found and fixed all of
>> those
>>     because it was Unsatisfiedlinkerror or similar but the runtime linking
>>     is disguising that its really the same problem.
>>
>>     If you really don't have any fonts installed, then that's also
>>     a missing package and we perhaps should have a better diagnostic,
>>     but there isn't really any point in continuing anyway without any
>> fonts.
>>     Even headless applications may require fonts.
>>
>>     -phil.
>>
>>
>>     On 6/4/2013 2:50 PM, Jeremy Manson wrote:
>>
>>         Hi folks,
>>
>>         I encountered a NullPointerException in the above method, when
>> fontconfig doesn't return any
>>         fonts:
>>
>>         http://hg.openjdk.java.net/__**jdk8/jdk8/jdk/file/__**
>> 7eae7c89dab4/src/solaris/__**classes/sun/awt/__**X11FontManager.java<http://hg.openjdk.java.net/__jdk8/jdk8/jdk/file/__7eae7c89dab4/src/solaris/__classes/sun/awt/__X11FontManager.java>
>>
>>         <http://hg.openjdk.java.net/**jdk8/jdk8/jdk/file/**
>> 7eae7c89dab4/src/solaris/**classes/sun/awt/**X11FontManager.java<http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/7eae7c89dab4/src/solaris/classes/sun/awt/X11FontManager.java>
>> >
>>
>>         Line 779.  The issue is that FontConfigManager sets
>> fontConfigFonts to null when Fontconfig
>>         doesn't return any fonts:
>>
>>         http://hg.openjdk.java.net/__**jdk8/jdk8/jdk/file/__**
>> 7eae7c89dab4/src/solaris/__**classes/sun/font/__**FontConfigManager.java<http://hg.openjdk.java.net/__jdk8/jdk8/jdk/file/__7eae7c89dab4/src/solaris/__classes/sun/font/__FontConfigManager.java>
>>
>>         <http://hg.openjdk.java.net/**jdk8/jdk8/jdk/file/**
>> 7eae7c89dab4/src/solaris/**classes/sun/font/**FontConfigManager.java<http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/7eae7c89dab4/src/solaris/classes/sun/font/FontConfigManager.java>
>> >
>>
>>         Line 218.
>>
>>         The solution I came up with is to initialize fontConfigFonts with
>> a zero-element array in
>>         this case:
>>
>>         diff --git a/src/solaris/classes/sun/__**
>> font/FontConfigManager.java
>>         b/src/solaris/classes/sun/__**font/FontConfigManager.java
>>         --- a/src/solaris/classes/sun/__**font/FontConfigManager.java
>>         +++ b/src/solaris/classes/sun/__**font/FontConfigManager.java
>>         @@ -216,6 +216,7 @@
>>         logger.info <http://logger.info> <http://logger.info>("__**Fontconfig
>> returned no fonts at all.");
>>
>>
>>                       }
>>                       fontConfigFailed = true;
>>         +            fontConfigFonts = new FcCompFont[0];
>>                       return;
>>                   } else if (fontConfigFailed) {
>>                       for (int i = 0; i< fontArr.length; i++) {
>>
>>         Thanks for your attention!
>>
>>         Jeremy
>>
>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/2d-dev/attachments/20130605/ca0e92c2/attachment.html>


More information about the 2d-dev mailing list