JDK-8173468 : Font.loadFont returns null on some Ubuntu 32bits
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 8u121,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2017-01-26
  • Updated: 2020-01-31
  • Resolved: 2017-01-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u152Fixed 9Fixed
Description
FULL PRODUCT VERSION :
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) Server VM (build 25.121-b13, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Out of the box Ubuntu 16.10 32 bits


A DESCRIPTION OF THE PROBLEM :
Related to this https://bitbucket.org/Jerady/fontawesomefx/issues/40/fontawesomefx-icons-displayed-as-garbage and this https://github.com/torakiki/pdfsam/issues/166

Loading FontAwesome ttf font results in a Font instance in Ubuntu 64 bits and a null instance in an Ubuntu 32 bits. It seems it does affect only some users and the behavior seems the one described here http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-March/018776.html

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the Font is loaded
ACTUAL -
it returns null on some Ubuntu 32 bits

REPRODUCIBILITY :
This bug can be reproduced occasionally.

---------- BEGIN SOURCE ----------
package my.test;

import java.nio.file.Files;
import java.nio.file.Paths;

import javafx.application.Application;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class App extends Application {

	private static final String FONT = "/home/torakiki/workspaces/test-fa/test-fa/src/my/test/fontawesome-webfont.ttf";
	public static void main(String[] args) {
		Application.launch(App.class, args);
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		 Font font = Font.loadFont(Files.newInputStream(Paths.get(FONT)), 10.0d);
		 System.out.println(font);
	}

}
---------- END SOURCE ----------


Comments
Approved to push to 8u-dev for 8u152.
08-02-2017

I'd like to backport this simple and risk-free fix to 8u.
08-02-2017

Changeset: 110824f8639a Author: vadim Date: 2017-02-01 00:09 +0300 URL: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/110824f8639a
31-01-2017

Raising the priority to P3 as visibility appears to be high enough (any 32-bit Linux)
31-01-2017

What's happening is that the compiler pushes arguments on the stack in reverse order, so it pushes 4 bytes for "text", then 8 zero bytes as "arg0" And then the callee pops two 4-bytes arguments which are both 0.
31-01-2017

Well spotted. If anything I'm a little surprised this is sufficient. It seems it must imply that this gets the compiler to effectively replace arg0 with (void*)arg0. +1
31-01-2017

Here's the patch, first argument is FcConfig *config which is 4 bytes on 32-bit systems, while jlong is 8 bytes. I think it's worth to backport it to 8u as well. diff -r aecac095fe44 modules/javafx.graphics/src/main/native-font/pango.c --- a/modules/javafx.graphics/src/main/native-font/pango.c Mon Jan 23 17:39:25 2017 -0800 +++ b/modules/javafx.graphics/src/main/native-font/pango.c Tue Jan 31 21:58:40 2017 +0300 @@ -225,7 +225,7 @@ if (text) { // rc = (jboolean)FcConfigAppFontAddFile(arg0, text); if (fp) { - rc = (jboolean)((jboolean (*)(jlong, const char *))fp)(arg0, text); + rc = (jboolean)((jboolean (*)(void *, const char *))fp)(arg0, text); } (*env)->ReleaseStringUTFChars(env, arg1, text); }
31-01-2017

For some reason FcConfigAppFontAddFile call fails and returns 0. dlopen and dlsym both succeeds, so the issue is somewhere in the fontconfig library it seems.
31-01-2017

I read what is at http://mail.openjdk.java.net/pipermail/openjfx-dev/2016-March/018776.html Hardwiring the return to true could well make it work .. mostly. It just won't be available to certain native APIs I don't see that the commented out line matters .. it was presumably just used during development. If the fn returns false then it means either that the call to FcConfigAppFontAddFile returns false or it was not actually called. The latter could happen if the library could not be found. FX is trying to open it via this name #define LIB_FONTCONFIG "libfontconfig.so.1" If its not on the path, not present at all, or (say) present only as something like /usr/lib/i386-linux-gnu/libfontconfig.so and /usr/lib/i386-linux-gnu/libfontconfig.so.1.9.0 Then the dlopen will fail. But if that were the case, then you'd have a problem where system fonts weren't found either. I suggest to start with an FX program that lists all fonts on the system plus the results of find / -name 'libfontconfig*'
27-01-2017

does it affect 9?
27-01-2017