Java 9 的 LogManager.getLogger()/Logger.getHandlers() 上缺少斜线似乎会导致异常 [英] Missing slash on Java 9’s LogManager.getLogger() / Logger.getHandlers() seems to cause an exception
问题描述
当我尝试创建日志文件 C:\Users\cardal\ApplicationLog.html 时,我发现运行 Java 9 的 Windows 小程序存在问题.该代码在 Java 8 上运行良好.
I am seeing a problem with an Applet on Windows, running Java 9, when I am trying to create a log file C:\Users\cardal\ApplicationLog.html. The code works fine on Java 8.
代码执行 LogManager.readConfiguration() 和 LogManager.getLogger().然后 Logger.getHandlers() 遇到异常.看起来第一个斜杠被错误地删除了:
The code does LogManager.readConfiguration () and LogManager.getLogger(). Then Logger.getHandlers() hits an exception. It looks like the first slash is getting removed by mistake:
Can't load log handler "java.util.logging.FileHandler"
java.nio.file.NoSuchFileException: C:Users\cardal\ApplicationLog.html.lck
java.nio.file.NoSuchFileException: C:Users\cardal\ApplicationLog.html.lck
at java.base/sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
at java.base/sun.nio.fs.WindowsFileSystemProvider.newFileChannel(Unknown Source)
at java.base/java.nio.channels.FileChannel.open(Unknown Source)
at java.base/java.nio.channels.FileChannel.open(Unknown Source)
at java.logging/java.util.logging.FileHandler.openFiles(Unknown Source)
at java.logging/java.util.logging.FileHandler.<init>(Unknown Source)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.base/java.lang.Class.newInstance(Unknown Source)
at java.logging/java.util.logging.LogManager.createLoggerHandlers(Unknown Source)
at java.logging/java.util.logging.LogManager.access$1300(Unknown Source)
at java.logging/java.util.logging.LogManager$4.run(Unknown Source)
at java.logging/java.util.logging.LogManager$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.logging/java.util.logging.LogManager.loadLoggerHandlers(Unknown Source)
at java.logging/java.util.logging.LogManager.initializeGlobalHandlers(Unknown Source)
at java.logging/java.util.logging.LogManager.access$1800(Unknown Source)
at java.logging/java.util.logging.LogManager$RootLogger.accessCheckedHandlers(Unknown Source)
at java.logging/java.util.logging.Logger.getHandlers(Unknown Source)
at appletExample.TestAppletLAC._getAllSpecificHandlers(TestAppletLAC.java:238)
at appletExample.TestAppletLAC.loadConfig(TestAppletLAC.java:116)
at appletExample.TestAppletLAC.reloadCoreLoggerProperties(TestAppletLAC.java:184)
at appletExample.TestAppletLAC.paint(TestAppletLAC.java:283)
at java.desktop/sun.awt.RepaintArea.paintComponent(Unknown Source)
at java.desktop/sun.awt.RepaintArea.paint(Unknown Source)
at java.desktop/sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue.access$500(Unknown Source)
at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
代码做错了吗?
Java 控制台输出验证 strLogConfig 中是否存在第一个斜杠:
The Java console output verifies that the first slash exists in strLogConfig:
LAC: reloadCoreLoggerProperties strLogConfig is
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
.level=WARNING
java.util.logging.ConsoleHandler.level=WARNING
java.util.logging.FileHandler.level=WARNING
java.util.logging.FileHandler.pattern=C:/Users/cardal/ApplicationLog.html
java.util.logging.FileHandler.formatter=com.emc.navisphere.gui.core
.utilities.logger.HTMLFormatter
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
Java 控制台输出还会验证在调用 readConfiguration 前后流中是否存在第一个斜杠:
The Java console output also verifies that the first slash exists in the stream before and after calling readConfiguration:
LAC: reloadCoreLoggerProperties myBytes[218] is 58 ":"
LAC: reloadCoreLoggerProperties myBytes[219] is 47 "/"
LAC: reloadCoreLoggerProperties myBytes[220] is 85 "U"
下面是代码(我删除了一些异常编码以简化代码).如果需要,我可以发布整个 Java 控制台日志输出.
Below is the code (I removed some exception coding to simplify the code). I can post the entire Java console log output if needed.
谢谢!
package appletExample;
import java.applet.Applet;
import java.awt.*;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.LogManager;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
public class TestAppletLAC extends Applet {
// try double backward slash, for now.
private static String NEW_LOG_FILE_DIR = "C:\\Users\\cardal\\";
public static String getDefaultOutputFileName() {
return NEW_LOG_FILE_DIR + "ApplicationLog.html";
}
/** Default Logging Config */
private static final String DEFAULT_CONFIG = "handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler\n"
+ ".level={0}\n"
+ "java.util.logging.ConsoleHandler.level={0}\n"
+ "java.util.logging.FileHandler.level={0}\n"
+ "java.util.logging.FileHandler.pattern={1}\n"
+ "java.util.logging.FileHandler.formatter=com.emc.navisphere.gui.core.utilities .logger.HTMLFormatter\n"
+ "java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter";
private final static String seperator = System.getProperty
("file.separator");
/** a LogManager */
private LogManager _manager = LogManager.getLogManager();
public static String getDefaultLogFile(String strLogFile) {
String strReturn = "";
// Logger wants the "/" not "\"
strLogFile = strLogFile.replace("\\", "/");
strReturn = MessageFormat.format(DEFAULT_CONFIG, new Object[] {
"WARNING", strLogFile });
// lac debug
System.out.println("LAC: getDefaultLogFile strReturn is " + strReturn);
return strReturn;
}
/**
* Loads config file using an InputStream
*
* @param stream
* - stream
*/
public synchronized boolean loadConfig(InputStream stream) {
boolean bReturn = false;
try {
if (stream != null)
{
// lac debug
System.out.println("LAC: loadConfig: printing out InputStream stream. Look for colon (58) then slash (47)");
// LAC
for(int y = 0 ; y < 1; y++)
{
int c;
while(( c = stream.read())!= -1)
{
System.out.println(c);
}
stream.reset();
}
// LAC: debug
System.out.println("lac: loadConfig: _manager.readConfiguration(stream) ");
/**
* first configure loggers by the LogManager as getAllSpecificHandlers
* may call logmanager
*/
_manager.readConfiguration(stream);
stream.reset();
// lac debug
System.out.println("LAC: loadConfig: AFTER READCONFIGURATION: printing out InputStream stream. Look for colon (58) then slash (47)");
// LAC
for(int y = 0 ; y < 1; y++)
{
int c;
while(( c = stream.read())!= -1)
{
System.out.println(c);
}
stream.reset();
}
// LAC: debug
System.out.println("lac: loadConfig: Calling _getAllSpecificHandlers(stream)");
/** add all specific handlers to loggers as neccessary */
_getAllSpecificHandlers(stream);
bReturn = true;
}
} catch (Exception e) {
}
return bReturn;
}
public void reloadCoreLoggerProperties() {
try
{
InputStream defaultNaviConfig = null;
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties getDefaultOutputFileName is " + getDefaultOutputFileName());
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties seperator from system.getproperty of file.separator is " + seperator);
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties NEW_LOG_FILE_DIR is " + NEW_LOG_FILE_DIR);
String strLogConfig = getDefaultLogFile(getDefaultOutputFileName());
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties strLogConfig is " + strLogConfig);
// lac debug
byte[] myBytes = strLogConfig.getBytes("UTF-8");
System.out.println("LAC: reloadCoreLoggerProperties myBytes at 209 -> 217 is 112,97,116,116,101,114,110,61,67 (pattern=C)");
System.out.println("LAC: reloadCoreLoggerProperties myBytes at 218 is 58 (colon)");
System.out.println("LAC: reloadCoreLoggerProperties myBytes at 219 should be 47 (forward slash)");
System.out.println("LAC: reloadCoreLoggerProperties myBytes at 220 should be 85 (U)");
System.out.println("LAC: reloadCoreLoggerProperties myBytes[208] is " + myBytes[208]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[209] is " + myBytes[209]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[210] is " + myBytes[210]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[211] is " + myBytes[211]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[212] is " + myBytes[212]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[213] is " + myBytes[213]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[214] is " + myBytes[214]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[215] is " + myBytes[215]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[216] is " + myBytes[216]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[217] is " + myBytes[217]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[218] is " + myBytes[218]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[219] is " + myBytes[219]);
System.out.println("LAC: reloadCoreLoggerProperties myBytes[220] is " + myBytes[220]);
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties about to do new ByteArrayInputStream(strLogConfig)");
defaultNaviConfig = new ByteArrayInputStream(strLogConfig
.getBytes("UTF-8"));
// lac debug
System.out.println("LAC: reloadCoreLoggerProperties printing out defaultNaviConfig. Look for colon (58) then slash (47)");
// LAC
for(int y = 0 ; y < 1; y++)
{
int c;
while(( c = defaultNaviConfig.read())!= -1) {
System.out.println(c);
}
defaultNaviConfig.reset();
}
// lac debug
System.out.println("LAC: about to call loadConfig with defaultNaviConfig");
// Load the logging configuration
loadConfig(defaultNaviConfig);
defaultNaviConfig.close();
} catch (Exception e)
{
}
}
private void _getAllSpecificHandlers(InputStream stream) {
Properties properties = new Properties();
try {
// LAC: debug
System.out.println("lac: TOP OF _getAllSpecificHandlers; properties.load(stream) to get the properties.");
properties.load(stream);
} catch (IOException ex) {
}
// LAC: debug
System.out.println("lac: Looping through the properties.");
Enumeration<?> propkeys = properties.propertyNames();
while (propkeys.hasMoreElements())
{
String loggerHasHandler = (String) propkeys.nextElement();
// LAC: Print the properties and values.
System.out.println("lac: key:value " + loggerHasHandler
+":"+_getProperty(loggerHasHandler));
if (loggerHasHandler.contains(".SpecificFileHandler.formatter"))
{
int end = loggerHasHandler.indexOf(".SpecificFileHandler.formatter");
String loggerName = loggerHasHandler.substring(0, end);
}
else if (loggerHasHandler
.equalsIgnoreCase("java.util.logging.FileHandler.formatter")
|| loggerHasHandler
.equalsIgnoreCase("java.util.logging.ConsoleHandler.formatter"))
{
/** get value and see if it is our HTMLFormatter */
String formatterValue = _getProperty(loggerHasHandler);
// LAC: debug
System.out.println("lac: formatterValue is " + formatterValue);
if (formatterValue.contains("HTMLFormatter"))
{
// LAC: debug
System.out.println("lac: Found HTMLFormatter; ABOUT TO _manager.getLogger()");
Logger rootLogger = _manager.getLogger("");
// LAC: debug
System.out.println("lac: ABOUT TO DO rootLogger.getHandlers() AND GET EXCEPTION");
Handler[] h = rootLogger.getHandlers();
// LAC: debug
System.out.println("lac: AFTER THE EXCEPTION, BEFORE THE LOOP");
for (int i = 0; i < h.length; i++)
{
if ((h[i] instanceof FileHandler && loggerHasHandler
.contains("FileHandler"))
|| (h[i] instanceof ConsoleHandler && loggerHasHandler
.contains("ConsoleHandler")))
{
Handler aHandler = h[i];
rootLogger.removeHandler(aHandler);
rootLogger.addHandler(aHandler);
}
}
}
}
}
}
/**
* This will return the corresponding values of the key as defined in a config
* file.
*
* @param key
* - key to look for the properties
* @return value from the key
*/
private String _getProperty(String key) {
String value = _manager.getProperty(key);
if (null != value) {
return value.trim();
}
return _manager.getProperty(key);
}
public void paint(Graphics g) {
// Draw a rectangle width=250, height=100
g.drawRect(0, 0, 500, 100);
// Set the color to blue
g.setColor(Color.blue);
g.drawString("Testing log on java versions",10,50);
reloadCoreLoggerProperties();
}
public void init()
{
}
}
推荐答案
这已经在 JDK-8189953:FileHandler 构造函数使用绝对路径抛出 NoSuchFileException.
从错误报告来看,它似乎是绝对路径的问题.由于您要定位主目录,请将文件模式更改为使用 %h
:
From the bug report it appears to be an issue with absolute paths. Since your are locating the home directory, change the file pattern to use %h
:
java.util.logging.FileHandler.pattern=%h\ApplicationLog.html
否则,根据 FileHandler 文档 正斜杠在运行时被替换.所以你可以尝试改用反斜杠.
Otherwise, per the FileHandler documentation the forward slash is replaced at runtime. So you can try to use back slash instead.
java.util.logging.FileHandler.pattern=C:\Users\cardal\ApplicationLog.html
修复错误报告后,您应该可以简单地升级到 Java 9 的更新版本.
When the bug report is fixed, you should be able to simply upgrade to a newer version of Java 9.
这篇关于Java 9 的 LogManager.getLogger()/Logger.getHandlers() 上缺少斜线似乎会导致异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!