在OpenJdk中如何设置带有additionalfontpath属性

时间:2017-04-07 11:01:08

标签: java fonts openjdk

我正在尝试让我的应用程序使用 attachedfontpath 属性在OpenJdk安装中使用特定位置的字体,但它对我不起作用。

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

报告没有安装任何字体,但/ usr / lib / fonts文件夹确实包含字体ipag.ttf

请注意:

  • OpenJdk没有预装的字体,它依赖于系统上安装的字体
  • 这是一个嵌入式系统,报告服务器上没有安装任何字体,fc-list不返回任何内容
  • 如果我将字体复制到jre / lib / fonts文件夹中,它可以正常工作,但我不允许将任何内容复制到此文件夹中。
  • 我也不能运行fc-cache -f
  • 等根命令

如果我只需指定一个包含字体的字体文件夹就能让它工作,那么对我来说这将是一个有效的解决方案。

4 个答案:

答案 0 :(得分:2)

您可以尝试设置JAVA_FONTS环境变量,以启动JVM以使其了解目录路径。 对于您的情况,可以通过export JAVA_FONTS=/usr/lib/fonts完成。 我的回答是基于archlinux wiki的Java Runtime Enviroment fonts文章。

编辑:
在没有安装字体的VM中进行测试表明设置JAVA_FONTS不起作用 我得出结论,通过你的设置,可能无法实现你的目标 我使用以下程序在没有安装字体的VM上重现错误:

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();
   }

}

这是我的Stacktrace: https://pastebin.com/fy3JDnkN
鉴于X11FontManager的来源 在使用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;
}

这使得无法手动添加字体,因为在我们访问字体管理器之前发生了NullPointerException,这种行为在几行之后给出评论时不会打算接收。

如果有另一个没有安装默认系统字体但没有崩溃的FontManager for Linux,可能仍然可以实现你的目标,但我找不到这样的替代品。

答案 1 :(得分:1)

一种解决方案可能是在您自己的jar中打包字体并尝试执行this之类的操作。

答案 2 :(得分:1)

您无需指定字体目录。如果它安装在您的机器中,JRE将自动选择字体。

我过去也遇到过这个问题,并在github上发现了一个带有字体的预构建的开放式JRE包。这些软件包在GNU GPL v.2下发布,带有类路径异常。

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

您可以下载Linux版本(java-1.8.0-openjdk-1.8.0.121-0.b13.el6_8.x86_64.zip),否则您可以在发布版本下查找121以外的更新。

注意:如果需要,您还可以在jre / lib / fonts下包含缺少的True Type字体。

  

替代选项I

在您的机器中安装所需的字体。这将无缝地工作,您不必在JRE中配置任何内容。

注意:

  • 如果您没有安装字体的权限,则可以很好地复制 字体/ usr / share / fonts目录。
  • 如果它是只读分区,则可以以读写模式安装分区并复制字体文件。
  • 如果/ usr / share / fonts所属的分区中没有剩余空间,您可以将文件复制到不同的目录中并进行软链接。
  

备选方案II

在jre / lib / fonts目录中包含字体(如果不存在则创建字体目录)并在jre / lib中配置fontconfig.properties文件。我没有测试过这个选项,但它应该可以工作。

  

编辑:

  • 如果机器中已安装字体,JVM应自动选择字体。否则,您可以使用JAVA_FONTS环境变量指定 @ BdoubleB97 中提到的字体。
  • 如果您没有设置环境变量的权限,可以在运行时传递环境变量,如下所示。

    ./ java-DJAVA_FONTS = / usr / share / fonts测试

答案 3 :(得分:0)

字体的标准系统位置是/ usr / share / fonts和子目录(请参阅fontconfig&amp; # fc-cache -f)。 / usr / lib / fonts是大约14年前已被弃用的miriad非标准位置之一,这就是系统和OpenJDK无法找到你的字体的原因。

与传统的SUN JVM不同,OpenJDK实际上尝试与系统集成并使用系统资源(不仅仅是在Windows下)。