java - Java 9 的 LogManager.getLogger()/Logger.getHandlers() 上缺少斜杠似乎会导致异常

标签 java logging applet java-9 java.util.logging

当我尝试创建日志文件 C:\Users\cardal\ApplicationLog.html 时,我在运行 Java 9 的 Windows 上发现 Applet 出现问题。该代码在 Java 8 上运行良好。

代码执行LogManager.readConfiguration()和LogManager.getLogger()。然后 Logger.getHandlers() 遇到异常。看起来第一个斜杠被错误地删除了:

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 中是否存在第一个斜杠:

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 之前和之后流中是否存在第一个斜杠:

LAC: reloadCoreLoggerProperties myBytes[218] is 58  “:”
LAC: reloadCoreLoggerProperties myBytes[219] is 47  “/”
LAC: reloadCoreLoggerProperties myBytes[220] is 85  “U”

下面是代码(我删除了一些异常编码以简化代码)。如果需要,我可以发布整个 Java 控制台日志输出。

谢谢!

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 constructor throws NoSuchFileException with absolute path 下的错误.

从错误报告来看,这似乎是绝对路径的问题。由于您正在定位主目录,因此将文件模式更改为使用 %h:

java.util.logging.FileHandler.pattern=%h\ApplicationLog.html

否则,按照FileHandler documentation正斜杠在运行时被替换。所以你可以尝试使用反斜杠来代替。

java.util.logging.FileHandler.pattern=C:\Users\cardal\ApplicationLog.html

修复错误报告后,您应该能够简单地升级到较新版本的 Java 9。

关于java - Java 9 的 LogManager.getLogger()/Logger.getHandlers() 上缺少斜杠似乎会导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46980752/

相关文章:

java - Weblogic 12c粘性问题

java - 初始化 Ellipse2D 数组时出错

java - Android Firebase - 为什么 map 字段中的空值被忽略

sql-server - 记录到文件还是数据库更好?

java - 从 logback 配置文件中读取环境变量

java - 有没有办法在 chrome 扩展中加载小程序?

java - Jpeg 计算最大尺寸

java - 发送记录并等待其确认接收

java - 应用程序无法在 ADB 上运行

Java Applet 无法清除屏幕上的文本