Мое приложение Java возвращает следующее исключение при сохранении нового файла в /opt/wso2
на CentOS 6.4:
Caused by java.io.FileNotFoundException: ... (No space left on device)
Caused by: java.io.FileNotFoundException: /opt/wso2/FrameworkFiles/trk_2014062500042488825_TRCK_PatfallHospis_pFromHospis_66601fb3-a03c-4149-93c3-6892e0a10fea.txt (No space left on device)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:99)
at com.avintis.esb.framework.adapter.wso2.FrameworkAdapterWSO2.sendMessages(FrameworkAdapterWSO2.java:634)
... 23 more
Но когда я бегу df -a
Я вижу, что в разделе все еще достаточно свободного места:
[root@stzsi466 wso2]# df -a
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/vg_stzsi466-lv_root
12054824 2116092 9326380 19% /
proc 0 0 0 - /proc
sysfs 0 0 0 - /sys
devpts 0 0 0 - /dev/pts
tmpfs 4030764 0 4030764 0% /dev/shm
/dev/sda1 495844 53858 416386 12% /boot
/dev/sdb1 51605436 1424288 47559744 3% /opt/wso2
none 0 0 0 - /proc/sys/fs/binfmt_misc
[root@stzsi466 ~]# df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/vg_stzsi466-lv_root
765536 45181 720355 6% /
tmpfs 1007691 1 1007690 1% /dev/shm
/dev/sda1 128016 44 127972 1% /boot
/dev/sdb1 3276800 6137 3270663 1% /opt/wso2
В чем проблема? Это вызвано Java на CentOS 6.4? У меня есть другой сервер с Redhat REHL 6.4, и все работает нормально - та же Java и т. Д.
Кто-нибудь знает об этой проблеме?
Итак, из трассировки стека мы можем видеть, что при создании объекта FileOutputStream внутри этого кода он вызывает ошибку open (), а затем выдает исключение FileNotFoundException с сообщением об ошибке «Нет места на устройстве».
Интересно посмотреть на код, который дает сбой (FileOutputStream.java):
public FileOutputStream(File file, boolean append)
throws FileNotFoundException
{
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(name);
}
if (name == null) {
throw new NullPointerException();
}
this.fd = new FileDescriptor();
this.append = append;
fd.incrementAndGetUseCount();
open(name, append); /* HERE */
}
Итак, это вызов собственного кода (FileOutputStream_md.c):
Java_java_io_FileOutputStream_open(JNIEnv *env, jobject this,
jstring path, jboolean append) {
fileOpen(env, this, path, fos_fd,
O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC));
}
И fileOpen (io_util_md.c):
fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags)
{
WITH_PLATFORM_STRING(env, path, ps) {
FD fd;
#ifdef __linux__
/* Remove trailing slashes, since the kernel won't */
char *p = (char *)ps + strlen(ps) - 1;
while ((p > ps) && (*p == '/'))
*p-- = '\0';
#endif
fd = JVM_Open(ps, flags, 0666); /* HERE IS WHERE THINGS BREAK */
if (fd >= 0) {
SET_FD(this, fd, fid);
} else {
throwFileNotFoundException(env, path); /* EXCEPTION */
}
} END_PLATFORM_STRING(env, ps);
}
И JVM_Open (jvm.cpp):
JVM_LEAF(jint, JVM_Open(const char *fname, jint flags, jint mode))
JVMWrapper2("JVM_Open (%s)", fname);
//%note jvm_r6
int result = os::open(fname, flags, mode);
if (result >= 0) {
return result;
} else {
switch(errno) {
case EEXIST:
return JVM_EEXIST; /* returns -100, will trigger Exception */
default:
return -1; /* returns -1, will trigger Exception */
}
}
JVM_END
А os :: open - это просто обертка вокруг fdopen (2) системный вызов.
Можете ли вы воспроизвести эту ошибку, когда захотите? Если да, запустите команду с strace -e trace=fopen,fdopen,freopen
и опубликовать результаты (или прикрепить к запущенному процессу с помощью strace -p <PID>
).