java加载自定义字体java.io.IOException: Problem reading font data.
com.anji.captcha.service.impl.AbstractCaptchaService.loadWaterMarkFont加载自定义字体异常:java.io.IOException: Problem reading font data
·
异常信息
load font error:{}
java.io.IOException: Problem reading font data.
at java.awt.Font.createFont0(Font.java:1000)
at java.awt.Font.createFont(Font.java:877)
at com.anji.captcha.service.impl.ClickWordCaptchaServiceImpl.init(ClickWordCaptchaServiceImpl.java:49)
at com.anji.captcha.service.impl.DefaultCaptchaServiceImpl.init(DefaultCaptchaServiceImpl.java:33)
at com.anji.captcha.service.impl.CaptchaServiceFactory.getInstance(CaptchaServiceFactory.java:36)
at com.gtb.common.config.CaptchaConfig.captchaService(CaptchaConfig.java:57)
at com.gtb.common.config.CaptchaConfig$$EnhancerBySpringCGLIB$$17f42947.CGLIB$captchaService$0(<generated>)
at com.gtb.common.config.CaptchaConfig$$EnhancerBySpringCGLIB$$17f42947$$FastClassBySpringCGLIB$$8f11612a.invoke(<generated>)
异常原因
由于该项目是从其他服务器上迁移过来的,迁移过程中没有对logs和temp目录进行打包。而 java.awt.Font.createFont0在加载自定义字体时需要创建临时文件,源码如下:
private static Font createFont0(int fontFormat, InputStream fontStream,
CreatedFontTracker tracker)
throws java.awt.FontFormatException, java.io.IOException {
if (fontFormat != Font.TRUETYPE_FONT &&
fontFormat != Font.TYPE1_FONT) {
throw new IllegalArgumentException ("font format not recognized");
}
boolean copiedFontData = false;
try {
//加载字体时在这个位置开始创建临时文件,文件以+~JF开头,.tmp结尾
final File tFile = AccessController.doPrivileged(
new PrivilegedExceptionAction<File>() {
public File run() throws IOException {
return Files.createTempFile("+~JF", ".tmp").toFile();
}
}
);
if (tracker != null) {
tracker.add(tFile);
}
int totalSize = 0;
try {
final OutputStream outStream =
AccessController.doPrivileged(
new PrivilegedExceptionAction<OutputStream>() {
public OutputStream run() throws IOException {
return new FileOutputStream(tFile);
}
}
);
if (tracker != null) {
tracker.set(tFile, outStream);
}
try {
byte[] buf = new byte[8192];
for (;;) {
int bytesRead = fontStream.read(buf);
if (bytesRead < 0) {
break;
}
if (tracker != null) {
if (totalSize+bytesRead > CreatedFontTracker.MAX_FILE_SIZE) {
throw new IOException("File too big.");
}
if (totalSize+tracker.getNumBytes() >
CreatedFontTracker.MAX_TOTAL_BYTES)
{
throw new IOException("Total files too big.");
}
totalSize += bytesRead;
tracker.addBytes(bytesRead);
}
outStream.write(buf, 0, bytesRead);
}
/* don't close the input stream */
} finally {
outStream.close();
}
/* After all references to a Font2D are dropped, the file
* will be removed. To support long-lived AppContexts,
* we need to then decrement the byte count by the size
* of the file.
* If the data isn't a valid font, the implementation will
* delete the tmp file and decrement the byte count
* in the tracker object before returning from the
* constructor, so we can set 'copiedFontData' to true here
* without waiting for the results of that constructor.
*/
copiedFontData = true;
Font font = new Font(tFile, fontFormat, true, tracker);
return font;
} finally {
if (tracker != null) {
tracker.remove(tFile);
}
if (!copiedFontData) {
if (tracker != null) {
tracker.subBytes(totalSize);
}
AccessController.doPrivileged(
new PrivilegedExceptionAction<Void>() {
public Void run() {
tFile.delete();
return null;
}
}
);
}
}
} catch (Throwable t) {
if (t instanceof FontFormatException) {
throw (FontFormatException)t;
}
if (t instanceof IOException) {
throw (IOException)t;
}
Throwable cause = t.getCause();
if (cause instanceof FontFormatException) {
throw (FontFormatException)cause;
}
throw new IOException("Problem reading font data.");
}
}
开始以为是字体库问题:运行命令
fc-list
和
yum install fontconfig
后并没有解决这个问题。然后不断的翻源码,怀疑是临时文件的问题。查看Tomcat下bin/catalina.sh 文件找到java 的JVM临时目录java.io.tmpdir的配置是CATALINA_TMPDIR=“$CATALINA_BASE”/temp
CATALINA_BASE指向的是Tomcat安装目录,由于是迁移过来的没有对temp目录做打包。在新建temp目录后启动正常
mkdir temp
在此记录一下这问题。
更多推荐
已为社区贡献2条内容
所有评论(0)