В коде Java я хочу «дотронуться» до файла.Я хочу обновить метки времени до текущего времени.Файл использует ACL.И это, похоже, проблема.
Файл:
$ ll file.xml
-rw-rwxrw-+ 1 root root 8611 Oct 4 17:28 file.xml
$ getfacl file.xml
# file: file.xml
# owner: root
# group: root
user::rw-
user:tomcat8:rwx
group::r-x
mask::rwx
other::rw-
И мое приложение Java запускается из Tomcat 8 с пользователем tomcat8.А sudo -u tomcat8 touch file.xml
работает.Это также работает, если я полностью удаляю ACL и устанавливаю tomcat8 в качестве владельца.Но это невозможно в производственной среде.
Итак, сначала я попробовал Apache common-io:
FileUtils.touch(path);
Это вызывает IOException.Я немного отладил его и обнаружил, что библиотека вызывает FileSystem.setLastModifiedTime
, которая вызывает функцию Linux utimes
.
Я отладил команду Linux touch
и увидел, что она вызывает еще одну более современную функцию: utimensat(0, NULL, NULL, 0)
.Он также вызывает dup2
и дублирует дескриптор файла.
Поэтому я создал свой собственный сенсорный метод в Java:
long time = System.currentTimeMillis();
FileTime fileTimeNow = FileTime.fromMillis(time);
BasicFileAttributeView fileAttributeView = Files.getFileAttributeView(derivative.toPath(), BasicFileAttributeView.class);
fileAttributeView.setTimes(fileTimeNow, fileTimeNow, fileTimeNow);
Это также вызывает исключение (операция не разрешена).
Внутренне он вызывает utimensat(69, NULL, [{1538666780, 483000000}, {1538666780, 483000000}], 0)
.
Я не могу установить null
на .setTimes(...)
.Этот вызов игнорируется.И нет Java-способа дублировать файловый дескриптор (dup2).Поэтому я не могу протестировать дальнейшие шаги, чтобы сделать его более похожим на прикосновение Linux.
Как заставить это работать, когда файл использует ACL?Я не хочу запускать внешние программы (коснитесь).