问题
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.
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)
Is the code doing something wrong?
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
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”
Below is the code (I removed some exception coding to simplify the code). I can post the entire Java console log output if needed.
Thanks!
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()
{
}
}
回答1:
This has already been reported as bug under JDK-8189953: FileHandler constructor throws NoSuchFileException with absolute path.
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
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
When the bug report is fixed, you should be able to simply upgrade to a newer version of Java 9.
来源:https://stackoverflow.com/questions/46980752/missing-slash-on-java-9-s-logmanager-getlogger-logger-gethandlers-seems-to