Closed jerboaa closed 1 year ago
Looking at buildAndRun.log file it fails with (for native):
Exception in thread "main" java.io.IOException: Problem reading font data.
at java.desktop@17.0.7-beta/java.awt.Font.createFont0(Font.java:1208)
at java.desktop@17.0.7-beta/java.awt.Font.createFont(Font.java:1076)
at imageio.Main.loadFonts(Main.java:139)
at imageio.Main.paintRectangles(Main.java:97)
at imageio.Main.main(Main.java:195)
What happens is this:
In https://github.com/openjdk/jdk17u/blob/908cab4123812b6b206b966a6ce92398cdf42c08/src/java.desktop/unix/classes/sun/awt/X11FontManager.java#L686..L707 there is this code:
/* The logic here decides whether to use a preconfigured
* fontconfig.properties file, or synthesise one using platform APIs.
* On Solaris we try to use the
* pre-configured ones, but if the files it specifies are missing
* we fail-safe to synthesising one. This might happen if Solaris
* changes its fonts.
* For Linux we require an exact match of distro and version to
* use the preconfigured file.
* If synthesising fails, we fall back to any preconfigured file
* and do the best we can.
*/
FontConfiguration mFontConfig = new MFontConfiguration(this);
if ((FontUtilities.isLinux && !mFontConfig.foundOsSpecificFile())) {
FcFontConfiguration fcFontConfig =
new FcFontConfiguration(this);
if (fcFontConfig.init()) {
return fcFontConfig; // <--- returns here for JVM mode
}
}
mFontConfig.init(); // <--- reaches here for native mode
return mFontConfig;
So why is the if condition entered for JVM mode, but not for native?
Remember, that we set java.home == .
for native by setting -Djava.home=.
Now, looking at the conditions, we note FontUtilities.isLinux && !mFontConfig.foundOsSpecificFile()
. The former expression is true in both cases for native and JVM mode, but for native the latter is false
. Why? foundOsSpecificFile()
is just returning a boolean which is set to true
by default. It's set to false
here: https://github.com/openjdk/jdk17u/blob/908cab4123812b6b206b966a6ce92398cdf42c08/src/java.desktop/share/classes/sun/awt/FontConfiguration.java#L322. Yet, this never happens in native mode, because ${java.home}/lib
doesn't exist (unless it so happens that ./lib
exists), while for JVM mode it always does since a lib
directory is part of the basic dir structure of a JDK image!
I.e. we return here in native mode and never set foundOsSpecificFile
to false
. Therefore, reaching the mFontConfig.init()
case and throwing the NPE ultimately causing the
java.io.IOException: Problem reading font data.
problem. See https://github.com/Karm/mandrel-integration-tests/issues/151#issuecomment-1516780148
Therefore, creating an empty directory lib
(or conf/fonts
for that matter) in java.home
is sufficient to fix this issue. At that point JVM mode and native mode take the same code path and the test passes.
Therefore, creating an empty directory
lib
(orconf/fonts
for that matter) injava.home
is sufficient to fix this issue. At that point JVM mode and native mode take the same code path and the test passes.
So in a way, @Karm, you were right about it here: https://github.com/Karm/mandrel-integration-tests/issues/102#issuecomment-1508395675
But at least I now know why it fixes the issue ;-)
After https://github.com/Karm/mandrel-integration-tests/pull/146, we still see imageio test failures in CI:
As it turns out this is nothing CI specific (Ubuntu), but was an error in my testing of #146 where I had a
lib
directory in theapp/imageio
directory of my local clone ofmandrel-integration-tests
. Removing that empty directory reproduces this fine on Fedora too.