Friday, October 10, 2008

Mac OS X, fonts and headless Java

If on Mac OS X your custom font is not available in headless Java, try installing it in /System/Library/Fonts/ instead of /Library/Fonts/.

Don't ask me why, but this solved the issue I'd been struggling with for days. Below is the background.

Font installed
I purchased a font called "standard 07_55" from the miniml.com site and installed it via the font catalog program, which copied the .otf (OpenType) file to /Library/Fonts/:
  $ ls -lae /Library/Fonts/standard*otf
-rw-r--r--@ 1 ernst admin 11996 Oct 8 15:39 /Library/Fonts/standard 07_55.otf
It was accessible from the user account on the Mac, which is confirmed by running a text editor program.

Java program to list all available fonts
The following Java program lists all available fonts:
  public class ListFonts {
public static void main(String[] args) {
String[] fonts = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for(int i=0; i<fonts.length; i++) System.out.println(fonts[i]);
}
}
Running the program from the graphical environment
When I ran this program is from Aqua, it worked well and displayed all fonts, including the installed "standard 07_55" font:
  $ java -version
java version "1.5.0_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05-237)
Java HotSpot(TM) Client VM (build 1.5.0_13-119, mixed mode, sharing)
$ javac ListFonts.java
$ java -cp . ListFonts | grep tand
KufiStandardGK
standard 07_55
Even when I added -Djava.awt.headless=true it still worked fine:
  $ java -Djava.awt.headless=true -cp . ListFonts | grep tand
KufiStandardGK
standard 07_55
Running the program via a remote connection
However, when that same program was run via a remote connection (SSH), then the program would not start up like this:
  $ java -cp . ListFonts | grep tand
Exception in thread "main" java.lang.InternalError: Can't connect to window server - not enough permissions.
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1822)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1723)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at sun.security.action.LoadLibraryAction.run(LoadLibraryAction.java:50)
at java.security.AccessController.doPrivileged(Native Method)
at apple.awt.CGraphicsEnvironment.(CGraphicsEnvironment.java:23)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:68)
at ListFonts.main(ListFonts.java:3)
This is understandable, since this is a remote connection, it cannot access the window server. So I started the Java program in headless AWT mode, and then it did run. However, now it does not show the font anymore:
  $ java -Djava.awt.headless=true -cp . ListFonts | grep tand
KufiStandardGK
Solving the issue
The fix? Simple: as root, move the font file to /System:
  # sudo mv /Library/Fonts/standard*otf /System/Library/Fonts/
I hope this helps someone else with a similar issue.

1 comment:

  1. I have read this post and if I could I desire to suggest you some interesting things or suggestionsWebsite Hosting

    ReplyDelete