java - SpringBoot Jar 无法加载 TrueType 字体
问题描述
当我想使用包含在 springboot fat jar 中的字体时,我发现了一个奇怪的行为。在从目录加载字体的本地机器上运行测试时/resources
,它运行良好。但是如果我用 maven 构建一个应用程序并从终端运行它,那么我将收到:
java.io.IOException: Problem reading font data.
at java.awt.Font.createFont0(Font.java:1000)
at java.awt.Font.createFont(Font.java:877)
我试图找到一个解决方案并做了以下事情:
- 使用不同的字体(有时会出现另一个关于损坏的表或某事的错误。)
- 构建了各种版本的 docker openjdk 容器来测试行为
- 构建一个ubuntu容器,安装openjdk
- 使用 debian 映像,安装 fc-cache 并通过以下方式提供字体
/usr/share/fonts/truetype/europlate
fc-cache -f -v
- 创建了一个临时文件,以确保 jar 中没有访问问题。
- 从我的终端运行应用程序,加载字体也失败
- 使用字体适用于编辑器,甚至当应用程序从 IDE 运行时(无测试)
方法:
public Font getFont() throws IOException, FontFormatException {
File f = File.createTempFile("dang", "tmp");
assert f != null;
f.delete();
ClassLoader classLoader = getClass().getClassLoader();
Font font = Font.createFont(Font.TRUETYPE_FONT, classLoader.getSystemResourceAsStream("EuroPlate.ttf"));
font.deriveFont(105f);
System.out.println(font.getFontName());
return font;
}
编辑:IDE 运行应用程序-> 工作
终端运行应用程序 -> 失败
堆栈跟踪:
java.io.IOException: Problem reading font data.
at java.desktop/java.awt.Font.createFont0(Font.java:1183)
at java.desktop/java.awt.Font.createFont(Font.java:1052)
at components.NumberPlateUtility.getFont(NumberPlateUtility.java:81)
at components.NumberPlateUtility.completeImage(NumberPlateUtility.java:173)
at main.NumberplateClientCommands.one(NumberplateClientCommands.java:63)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:223)
at org.springframework.shell.Shell.evaluate(Shell.java:169)
at org.springframework.shell.Shell.run(Shell.java:134)
at org.springframework.shell.jline.InteractiveShellApplicationRunner.run(InteractiveShellApplicationRunner.java:84)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:783)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:773)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
at main.Main.main(Main.java:20)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51)
解决方案
此代码将起作用:
public Font getFont() throws IOException, FontFormatException {
File f = File.createTempFile("dang", "tmp");
assert f != null;
f.delete();
ClassLoader classLoader = getClass().getClassLoader();
Font font = Font.createFont(Font.TRUETYPE_FONT, classLoader.getResourceAsStream("EuroPlate.ttf"));
font.deriveFont(105f);
System.out.println(font.getFontName());
return font;
}
注意 中的变化classLoader.getResourceAsStream
。检查这个答案以获得更多解释。
推荐阅读
- android - 我们可以再在 android 11 中创建文件夹吗?
- django - DRF 通过 Viewset 接口更新产品价格
- xaml - 在 Xamarin AppShell TabBar 图标属性中使用 FontAwesome 或任何其他 webfonts
- mysql - 尝试通过 MySQL Monitor 连接到 MySQL 时出现错误 1049 未知数据库
- gap-system - 如何在批处理模式下使用 GAP?
- postgresql - 使用golang连接到谷歌云VM实例上的postgres?
- python - 下载文件夹的自动管理器导致所有 chrome 下载失败
- api - JSON:API 规范 | 外部标识符
- android-studio - Android Studio 构建失败,没有有用的错误消息
- cloudflare - Cloudflare Worker GeoIP 重定向与匹配 URL 和后备