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

Jeremy Manson jeremymanson at google.com
Fri Jun 7 21:32:39 UTC 2013


Hi Phil,

Thanks for reviewing the issue.  I'll just reiterate that I don't really
have an opinion about whether you should support lack of fonts as a use
case.  I do think that if you don't, it should be clearer that you don't,
as the trail of breadcrumbs about what happened is a little mysterious.  A
"fontconfig not installed / configured" or "No fonts found" message in the
exception would probably have been fine.

We do ship fonts with our builds of OpenJDK, FWIW.  As I said up front, my
notes are a little incomplete, but I think what probably happened was that
we were deployed on a (headless) system for which there was no appropriate
fontconfig properties file; we fixed that, and moved on (I do have a record
of doing some semi-related configuration jiggering at the time).

Thanks!

Jeremy


On Fri, Jun 7, 2013 at 12:19 PM, Phil Race <philip.race at oracle.com> wrote:

> "Oracle" JDK ships with fonts. And it has a default fontconfig.properties
> (not
> the same thing as libfontconfig) file that maps all the logical fonts to
> those fonts.
> So it fully meets the spec and can function just fine on a system that has
> no other fonts installed.
> So on reflection we wouldn't want to fail at this point without checking
> to see if we actually
> can continue.
> This doesn't help "Open" JDK as it is, since it doesn't have fonts, but
> there's nothing to stop
> an OpenJDK port doing the exact same, except that its kind of pointless
> for a distro to do
> that as it would be easier to make libfontconfig and some core fonts a
> pre-requisite package.
>
> I think I'll need to review everyone's "requirements" again to say
> exactly what should be the path forward.
>
> For your "headless" situation,  I'm not completely clear about what you
> intend to run,
> but it occurs to me that if you are even tickling this code, its
> reasonable to suppose
> that the app is likely to need fonts. Whereas someone running a back-end
> server app
> would never initialise the AWT toolkit, so shouldn't care less whether
> fonts are installed.
>
> -phil.
>
>
>
> On 6/5/2013 9:38 AM, Jeremy Manson wrote:
>
>> 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 <http://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 <mailto:
>> 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**>
>>         <mailto: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>
>>         <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/20130607/43f0d58d/attachment.html>


More information about the 2d-dev mailing list