JDK-6244047 : impossible to specify directories to logging FileHandler unless they exist
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.logging
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2005-03-22
  • Updated: 2014-06-24
  • Resolved: 2012-11-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8 b66Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.4.2_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
Java HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows 2000 [Version 5.00.2195]  SP4


A DESCRIPTION OF THE PROBLEM :
if you specify a patern to the FileHandler that contains directories that don't currently exist then the FileHandler will fail to initialise even if the directories can be created

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
configure a FileHandler for logging that uses a directory that can be created but  doesn't exist.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the directories are created if the user has the permissions to do so
ACTUAL -
exception is thrown, FIleHandler is not configured.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
C:\>java -Djava.util.logging.config.file=c:\logging.properties LogTest
Can't load log handler "java.util.logging.FileHandler"
java.io.IOException: Couldn't get lock for %h/.myco/myapp/log%u.%g.log
java.io.IOException: Couldn't get lock for %h/.myco/myapp/log%u.%g.log
        at java.util.logging.FileHandler.openFiles(FileHandler.java:361)
        at java.util.logging.FileHandler.<init>(FileHandler.java:207)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
        at java.lang.Class.newInstance0(Class.java:308)
        at java.lang.Class.newInstance(Class.java:261)
        at java.util.logging.LogManager$5.run(LogManager.java:784)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java:776)
        at java.util.logging.LogManager.access$900(LogManager.java:114)
        at java.util.logging.LogManager$RootLogger.getHandlers(LogManager.java:883)
        at java.util.logging.Logger.log(Logger.java:420)
        at java.util.logging.Logger.doLog(Logger.java:446)
        at java.util.logging.Logger.log(Logger.java:469)
        at LogTest.main(LogTest.java:7)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
-- logging.properties --
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level= ALL
java.util.logging.FileHandler.pattern = %h/.myco/myapp/log%u.%g.log
-- end logging.properties --

-- LogTest.java --

import java.util.logging.*;

public class LogTest {

	public static void main(String[] args)  {
		Logger log = Logger.getLogger(LogTest.class.getName());
		log.log(Level.SEVERE, "Hello World");
	}

}

-- end LogTest.java --


---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
have to make directories first, but then have to parse the pattern.
the generate method in FileHandler is not exposed so need to re-invent the wheel.

Otherwise is a possible one line fix in FileHandler.java:openFiles(),
line 369
	    synchronized(locks) {
		if (locks.get(lockFileName) != null) {
		    // We already own this lock, for a different FileHandler
		    // object.  Try again.
		    continue;
	        }
		FileChannel fc;
		try {
+		    lockFileName.getParent().mkdirs();
		    lockStream = new FileOutputStream(lockFileName);
		    fc = lockStream.getChannel();
		} catch (IOException ix) {
		    // We got an IOException while trying to open the file.
		    // Try the next file.
		    continue;
		}
###@###.### 2005-03-22 04:40:08 GMT

Comments
EVALUATION The following line is in the logging.properties file: java.util.logging.FileHandler.pattern = %h/.myco/myapp/log%u.%g.log It seems to me that the following part of the spec is applicable: http://java.sun.com/javase/6/docs/api/java/util/logging/FileHandler.html http://javaweb.sfbay/javare/jdk/6.0/promoted/latest/doc/api/java/util/logging/FileHandler.html Configuration: By default each FileHandler is initialized using the following LogManager configuration properties. If properties are not defined (or have invalid values) then the specified default values are used. * java.util.logging.FileHandler.level specifies the default level for the Handler (defaults to Level.ALL). <snip> * java.util.logging.FileHandler.pattern specifies a pattern for generating the output file name. See below for details. (Defaults to "%h/java%u.log"). Based on the spec wording above, if the "FileHandler.pattern" property specifies an unusable value, then it is invalid. If an invalid value is specified, then the API is supposed to use the default value. In this case "%h/java%u.log" should be used.
13-08-2009

EVALUATION It looks like the java.util.logging.FileHandler does not expect that the specified directory may not exist. Normally, it has to check this condition anyway. Also, it has to check the directory writing permissions as well. Another question is what to do if one of these check does not pass. One possibility is to create the missing directories in the path if the user has proper permissions. Another is to throw an IOException with a clear message what is wrong. The latter approach looks more consistent. I'm not sure we have to add more clarifications to the javadoc spec. Currently, the spec for FileHandler(...) constructors says that it may throw an IOException: Throws: IOException - if there are IO problems opening the files. Maybe it is good enough.
04-02-2006