我的问题与找到JDK Logging的实际打开的日志文件相同,只是我想使用由Java 9. java支持的API。
在Java 8中,我目前使用了与该问题答案中所述的几乎相同的反射黑客攻击,只是我查看实际日志文件名而不是解析LockFilename。
这是我的代码:
private static String logFileName = null;
public static String getLogFileName() {
// determined on demand and cached so we only need to do all of this the first time.
if (logFileName == null) {
for (Handler handler : Logger.getLogger("").getHandlers()) {
if (handler.getClass().isAssignableFrom(FileHandler.class)) {
FileHandler fileHandler = (FileHandler) handler;
try {
// FileHandler.files has private access,
// so I'm going to resort to reflection to get the file name.
Field privateFilesField = fileHandler.getClass().getDeclaredField("files");
privateFilesField.setAccessible(true); // allow access to this private field
File[] files = (File[]) privateFilesField.get(fileHandler);
logFileName = files[0].getCanonicalPath();
break;
} catch (NullPointerException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | IOException ex) {
logger.log(Level.SEVERE, "Unable to determine log file name.", ex);
}
}
}
if (logFileName == null) {
logFileName = "your home directory"; // just be sure it's not null
logger.warning("Unable to identify log file name.");
}
}
return logFileName;
}
反射hack在Java 8&9,但在Java 9中,它会产生以下警告,我希望修复,而不是忽略-ILLEGAL-ACCESS =允许标志。
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.foo.MyApp (file:/C:/Users/me/Documents/foo/build/classes/java/main/) to field java.util.logging.FileHandler.files
WARNING: Please consider reporting this to the maintainers of org.foo.MyApp
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
有什么想法吗?谢谢。
如果特定于Linux特定的解决方案足够好,您可以尝试在/proc/self/fd/
中解决伪合并,其中一个应该是当前打开的日志文件,与记录文件模式匹配。
有几种方法:
- 使用JDK提出更改请求,以允许访问该字段(至少将其访问
protected
,以便您可以在子类中读取它(。 - 解析用于配置Appender的属性文件。您将必须从Java 9代码中复制一些逻辑,但很可能会使该代码很长一段时间(向后兼容(。
- 从记录API中复制大量代码,以便您可以编写自己的
FileHandler
,允许访问该字段。在此期间,您也可以在所有附录中添加代码。 - 使用不同的记录框架。