V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zackzergzeng
V2EX  ›  Java

求助, Java 只能用全局安装的 fontconfig 来使用字体吗?

  •  
  •   zackzergzeng · 362 天前 · 1915 次点击
    这是一个创建于 362 天前的主题,其中的信息可能已经有所发展或是发生改变。
    用的是 openjdk 1.8,使用 apache batik 写了个 svg 转 png 的功能,结果放到 centos 服务器运行报错,调查是因为没有安装 fontconfig ,虽然安装 fontconfig 就能解决,但是想要自动化部署,而且要兼容很多系统( centos ,欧拉,红帽...,还得区分 x86 和 arm),所以自动化脚本那边不想安装 fontconfig ,之后又研究了下泪痣 libfontconfig.so 的形式,但是内置后 sun.font.FontConfigManager.getFontConfig 方法一直返回为空,还是报错,所以在这里咨询各位大神,有什么解决方案能够绕开安装 fontconfig 来正常运行 batik
    第 1 条附言  ·  362 天前
    我描述的有点问题,其实就是产品有个一键安装脚本,内部讨论了下不同意在脚本那层安装 fontconfig ,因为用户的安装环境基本不联网,所以要准备的安装包就太多了
    第 2 条附言  ·  362 天前
    还有一点,没有用 docker 这种先进系统
    第 3 条附言  ·  361 天前
    再加一个前提,我是做不是给某一个客户做的定制产品,而是通用 to B 的产品,需要考虑各个客户之间环境和条件的差异,其实退而求其次,我完全可以在文档加一句让现场实施同事或者客户自行安装就完事了,但是还是想追求下有没有更方便的办法(实在没有就算了)
    还有就是我这个是因为环境没有 fontconfig 而导致的 java 的报错,不是缺字体哈
    第 4 条附言  ·  339 天前
    挖个坟,问题解决了,总结几条
    1 、本以为“缺少全局 fontconfig 就报空指针异常”是特性,结果翻了下 openjdk 最新的 release 发现是 bug ,刚在 8u372 修复了😂
    2 、之前有过“把字体放入~/.local/share/fonts/里,然后在 System.load 引入 libfontconfig.so”也能解决的方案,但是一是升级到 8u372 以上就不行了,二来 linux 发行版太多 so 兼容不过来,三是没有 debug 出原理,就 pass 了,希望有懂哥能解释一下为什么
    3 、翻了下源码,看 sun 的实现是在 linux 系统下使用一个 fontpath.c 文件获取 libfontconfig.so 来管理字体,c 文件用 dlopen 来引入的 libfontconfig.so 好像默认就是找全局的。(好像可以通过自定义 fontconfigruation 类的方法来自定义字体查找,但是印象有点模糊了以后在研究吧)
    22 条回复    2023-12-05 17:08:58 +08:00
    Ayanokouji
        1
    Ayanokouji  
       362 天前
    如果是 docker ,可以将字体打包到镜像,如果是裸机,可以写脚本,安装字体
    adoal
        2
    adoal  
       362 天前
    说得好像安装 fontconfig 这个包不能做到自动化部署里去似的
    adoal
        3
    adoal  
       362 天前
    你想像的自动化部署是什么,只包括用脚本或者其它系统把你的打包好的业务软件拷过去这一件事,不包括对目标环境的配置?
    kd9yYw2RyhQwAwzn
        4
    kd9yYw2RyhQwAwzn  
       362 天前
    自动化部署不是也需要基础镜像吗 把 fontconfig 直接安装到基础镜像就可以了
    zackzergzeng
        5
    zackzergzeng  
    OP
       362 天前
    @adoal 我描述的有点问题,其实就是产品有个一键安装脚本,内部讨论了下不同意在脚本那层安装,因为基本安装环境不联网,所以要准备的安装包就太多了
    thofx
        6
    thofx  
       362 天前
    @zackzergzeng 离线 rpm 包 可以啊
    cheng6563
        7
    cheng6563  
       362 天前
    内核版本够的话,可以用 nerdctl ,一步解压就装好容器环境。
    adoal
        8
    adoal  
       362 天前   ❤️ 2
    @zackzergzeng 又想马儿跑又想马儿不吃草。不联网的环境就不能装包了吗?那客户当初按安装操作系统的介质总还在的吧,fontconfig 这么基础的东西你说的这几个发行版的安装盘里应该都有的。如果确定一定要离线安装,方案一是没必要把发行版这种东西也放到一键安装里去,这事可以让客户自己先解决好(别笑,没必要太舔客户,我(甲方)就遇到过供应商的文档里的 requirement 一张明确写了要预装哪些包)。方案二是把你们要兼容的几个发行版的 fontconfig 及其直接依赖先准备好,现场环境里没装的就从你们介质装,“要兼容很多系统”是你们自己贪心的商务策略,那就要付出相应的劳动代价。NO SILVER BULLET, NO SILVER BULLET, NO SILVER BULLET 。
    McZoden
        9
    McZoden  
       362 天前
    怀疑是客户服务器压根没有装 X ,所以 fontconfig 之类的 X 环境的基础都没有,不止缺少这单个包的
    wjup
        10
    wjup  
       362 天前
    上周刚遇到个类似的问题。业务是数据根据模板导出 pdf ,用到了字体,本地开发试着没问题,打成 jar 包后运行字体总是返回空,最终发现打包时二进制会破坏字体文件,大概是这样原因,然后在 pom 里添加 nonFilteredFileExtensions 解决的
    zackzergzeng
        11
    zackzergzeng  
    OP
       362 天前
    @thofx 要准备至少 4-5 个系统的 rpm ,还有 x86 和 arm 两种架构,还得准备 fontconfig 依赖的 rpm ,甚至依赖的依赖
    ldyisbest
        12
    ldyisbest  
       362 天前
    字体打包到 java 项目里面
    siweipancc
        13
    siweipancc  
       362 天前 via iPhone
    (⊙o⊙)还有这么难搞的吗,上次出问题我直接打包一个字体注册到虚拟机就完事了
    janus77
        14
    janus77  
       361 天前
    要不你先在一台机器上试试,装了 fontconfig 以后能不能解决
    说不定,依然解决不了呢?
    我的意思是,客户的环境有时候是很坑的,他们从嘴里说的话不一定靠谱,要亲自调研过才能确定。不然你们又做了无用功
    zackzergzeng
        15
    zackzergzeng  
    OP
       361 天前
    @janus77 安装 fontconfig 是肯定解决的,而且卸载了 fontconfig 就会报原来的错
    bigfei
        16
    bigfei  
       361 天前
    用 js 在浏览器实现呢? svg 到 png
    zackzergzeng
        17
    zackzergzeng  
    OP
       361 天前
    @bigfei 没有浏览器的,用来生成图片放入 word 文档的
    bigfei
        18
    bigfei  
       361 天前
    bigfei
        19
    bigfei  
       361 天前
    或者这个:
    https://www.npmjs.com/package/convert-svg-to-png
    用 java 的话确实没有 nodejs 方便
    buliugu
        20
    buliugu  
       361 天前
    to B 其实非常建议用 docker 做部署,把部署的复杂度统一搞到开发阶段处理掉,通过租赁云服务器的方式测试各种不同的操作系统与硬件环境,不然客户千奇百怪的服务器环境会把你的实施工程师逼疯的
    404E
        21
    404E  
       361 天前
    svg 转 png ,我之前写的是用 skiko(kotlin 的,java 可以用 skija)来处理,win 开发 linux 部署,只要改一下依赖的 os 就行了,但是有一个问题就是不支持 css 的样式(浏览器是支持的),要手动处理把 css 放到对应的元素里面(用 jsoup)
    991547436
        22
    991547436  
       361 天前
    不用 fontconfig 的话可以在转换之前把用到的字体加载一下
    // 从文件加载字体
    File fontFile = new File("./font/SIMHEI.TTF");
    Font customFont = Font.createFont(Font.TRUETYPE_FONT, fontFile);
    // 获取全局图形环境
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    // 注册字体到全局
    ge.registerFont(customFont);
    // 获取所有可用的字体
    Font[] allFonts = ge.getAllFonts();
    System.out.println("Available Fonts:");
    for (Font font : allFonts) {
    System.out.println(font.getFontName());
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2425 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 02:07 · PVG 10:07 · LAX 18:07 · JFK 21:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.