Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In OpenJdk how do I set font dir with appendedfontpath property

I am trying to get my application to use fonts from a particular location in an OpenJdk installation using appendedfontpath property but it is not working for me.

../jre1.8.0_121+1/bin/java  -Dappendedfontpath=/usr/lib/fonts/  -jar lib/songkong-4.7.jar -m /mnt/disk1/share

reporting no fonts installed, but the /usr/lib/fonts folder does contain a font ipag.ttf

Please Note:

  • OpenJdk comes with no preinstalled fonts it relies on fonts installed on system
  • This is an embedded system that reports no fonts installed on server, fc-list returns nothing
  • If I copy the font into jre/lib/fonts folder it works but I'm not allowed to copy anything into this folder.
  • Nor am I allowed to run root commands such as fc-cache -f

If I could get it working by just specifying a font folder containing fonts, it would be a working solution for me.

like image 903
Paul Taylor Avatar asked Apr 07 '17 11:04

Paul Taylor


People also ask

Where are Java fonts installed?

Support for Physical Fonts The JRE looks in two locations: the lib/fonts directory within the JRE itself, and the normal font location(s) defined by the host operating system. If fonts with the same name exist in both locations, the one in the lib/fonts directory is used.


2 Answers

You don't need to specify the font directory. If it is installed in your machine, the JRE will pick the fonts automatically.

I was also facing this issue in the past and found a pre-built open JRE packages with fonts in github. These packages are released under GNU GPL v. 2 with classpath exception.

https://github.com/ojdkbuild/ojdkbuild/releases/tag/1.8.0.121-1

You can download the Linux version (java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.x86_64.zip) or else you can look for updates other than 121 as well under releases.

Note: You can also include the missing True Type fonts under jre/lib/fonts if required.

Alternate Option I

Installing the required fonts in your machine. This will work seamlessly and you don't have to configure anything in the JRE.

Note:

  • If you don't have privilege to install fonts, you can very well copy the fonts /usr/share/fonts directory.
  • If it is a read-only partition, you can mount the partition in read-write mode and copy the font files.
  • In case if there is no space left in the partition where /usr/share/fonts belongs to, you can copy the files in a different directory and make a soft link to it.

Alternate Option II

Including the fonts in jre/lib/fonts directory (create fonts directory if not exists) and configuring the fontconfig.properties file in jre/lib. I haven't tested this option but it should work.

Edit:

  • If fonts are already installed in the machine, JVM should pick the fonts automatically. Otherwise you can specify the fonts as mentioned in @BdoubleB97 answer using JAVA_FONTS environment variable.
  • If you don't have permission to set the environment variable, you can pass the environment variable during run time as below.

    ./java -DJAVA_FONTS=/usr/share/fonts Test

like image 62
Loganathan Mohanraj Avatar answered Oct 11 '22 14:10

Loganathan Mohanraj


You could try to set the JAVA_FONTS enviroment variable befor starting the JVM to make it aware of the directory path. For your case this could be done by export JAVA_FONTS=/usr/lib/fonts. My answer is based on the Java Runtime Enviroment fonts article of the archlinux wiki.


EDIT:
Test in a VM with no Fonts installed show that setting JAVA_FONTS does not work and I have come to the conclusion that with your setup it might not be possible to achieve your goal.
I used the following Program to reproduce the error on a VM with no Fonts installed:

import javax.swing.*;
public class example{

    public static void main(String[] tArgs){
        JFrame j = new JFrame();
        j.add(new JButton("Test"));
        j.setVisible(true);
        j.pack();
   }

}

Here is my Stacktrace: https://pastebin.com/fy3JDnkN
Given the source of the X11FontManager the error occurs while the Font Manager is constructed in the line with for (int i=0; i<fontConfigFonts.length; i++) {.

public String[] getDefaultPlatformFont() {
    if (defaultPlatformFont != null) {
        return defaultPlatformFont;
    }
    String[] info = new String[2];
    getFontConfigManager().initFontConfigFonts(false);
    FontConfigManager.FcCompFont[] fontConfigFonts =
        getFontConfigManager().getFontConfigFonts();
    for (int i=0; i<fontConfigFonts.length; i++) {
        if ("sans".equals(fontConfigFonts[i].fcFamily) &&
            0 == fontConfigFonts[i].style) {
            info[0] = fontConfigFonts[i].firstFont.familyName;
            info[1] = fontConfigFonts[i].firstFont.fontFile;
            break;
        }
    }
    /* Absolute last ditch attempt in the face of fontconfig problems.
     * If we didn't match, pick the first, or just make something
     * up so we don't NPE.
     */
    if (info[0] == null) {
        if (fontConfigFonts.length > 0 &&
            fontConfigFonts[0].firstFont.fontFile != null) {
            info[0] = fontConfigFonts[0].firstFont.familyName;
            info[1] = fontConfigFonts[0].firstFont.fontFile;
        } else {
            info[0] = "Dialog";
            info[1] = "/dialog.ttf";
        }
    }
    defaultPlatformFont = info;
    return defaultPlatformFont;
}

This makes it impossible to add Fonts Manually since the NullPointerException occurs prior to us having access to the Font Manager, this behavior seams to not be intended given the comment a couple lines later.

It might still be possible to achieve your goal if there is another FontManager for Linux that does not crash with no default System Font installed, but I could not find such a replacement.

like image 37
Skgland Avatar answered Oct 11 '22 13:10

Skgland