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

时间:2017-10-27 17:45:10

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

当我尝试创建日志文件C:\ Users \ cardal \ ApplicationLog.html时,我发现Windows上运行Java 9的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() 
{
}
}

1 个答案:

答案 0 :(得分:2)

这已被报告为JDK-8189953: FileHandler constructor throws NoSuchFileException with absolute path下的错误。

从错误报告中看,这似乎是绝对路径的问题。由于您要查找主目录,因此请将文件模式更改为使用str(goal) num [1:10, 1:5] 7.5 15 20 7.5 10 12.5 15 5 25 10 ... goal [,1] [,2] [,3] [,4] [,5] [1,] 7.5 15 22.5 30 37.5 [2,] 15.0 30 45.0 60 75.0 [3,] 20.0 40 60.0 80 100.0 [4,] 7.5 15 22.5 30 37.5 [5,] 10.0 20 30.0 40 50.0 [6,] 12.5 25 37.5 50 62.5 [7,] 15.0 30 45.0 60 75.0 [8,] 5.0 10 15.0 20 25.0 [9,] 25.0 50 75.0 100 125.0 [10,] 10.0 20 30.0 40 50.0

%h

否则,根据FileHandler documentation,在运行时替换正斜杠。所以你可以尝试使用反斜杠。

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

修复错误报告后,您应该只需升级到较新版本的Java 9即可。