src/share/classes/java/util/logging/FileHandler.java
Print this page
*** 23,36 ****
* questions.
*/
package java.util.logging;
! import java.io.*;
import java.nio.channels.FileChannel;
! import java.nio.channels.FileLock;
! import java.security.*;
/**
* Simple file logging <tt>Handler</tt>.
* <p>
* The <tt>FileHandler</tt> can either write to a specified file,
--- 23,45 ----
* questions.
*/
package java.util.logging;
! import static java.nio.file.StandardOpenOption.CREATE_NEW;
! import static java.nio.file.StandardOpenOption.WRITE;
!
! import java.io.BufferedOutputStream;
! import java.io.File;
! import java.io.FileOutputStream;
! import java.io.IOException;
! import java.io.OutputStream;
import java.nio.channels.FileChannel;
! import java.nio.file.FileAlreadyExistsException;
! import java.nio.file.Paths;
! import java.security.AccessController;
! import java.security.PrivilegedAction;
/**
* Simple file logging <tt>Handler</tt>.
* <p>
* The <tt>FileHandler</tt> can either write to a specified file,
*** 135,152 ****
private boolean append;
private int limit; // zero => no limit.
private int count;
private String pattern;
private String lockFileName;
! private FileOutputStream lockStream;
private File files[];
private static final int MAX_LOCKS = 100;
private static java.util.HashMap<String, String> locks = new java.util.HashMap<>();
! // A metered stream is a subclass of OutputStream that
! // (a) forwards all its output to a target stream
! // (b) keeps track of how many bytes have been written
private class MeteredStream extends OutputStream {
OutputStream out;
int written;
MeteredStream(OutputStream out, int written) {
--- 144,163 ----
private boolean append;
private int limit; // zero => no limit.
private int count;
private String pattern;
private String lockFileName;
! private FileChannel lockFileChannel;
private File files[];
private static final int MAX_LOCKS = 100;
private static java.util.HashMap<String, String> locks = new java.util.HashMap<>();
! /**
! * A metered stream is a subclass of OutputStream that
! * (a) forwards all its output to a target stream
! * (b) keeps track of how many bytes have been written
! */
private class MeteredStream extends OutputStream {
OutputStream out;
int written;
MeteredStream(OutputStream out, int written) {
*** 187,199 ****
BufferedOutputStream bout = new BufferedOutputStream(fout);
meter = new MeteredStream(bout, len);
setOutputStream(meter);
}
! // Private method to configure a FileHandler from LogManager
! // properties and/or default values as specified in the class
! // javadoc.
private void configure() {
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();
--- 198,211 ----
BufferedOutputStream bout = new BufferedOutputStream(fout);
meter = new MeteredStream(bout, len);
setOutputStream(meter);
}
! /**
! * Configure a FileHandler from LogManager properties and/or default values
! * as specified in the class javadoc.
! */
private void configure() {
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();
*** 285,295 ****
* @exception IOException if there are IO problems opening the files.
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
* @exception IllegalArgumentException if pattern is an empty string
*/
! public FileHandler(String pattern, boolean append) throws IOException, SecurityException {
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
--- 297,308 ----
* @exception IOException if there are IO problems opening the files.
* @exception SecurityException if a security manager exists and if
* the caller does not have <tt>LoggingPermission("control")</tt>.
* @exception IllegalArgumentException if pattern is an empty string
*/
! public FileHandler(String pattern, boolean append) throws IOException,
! SecurityException {
if (pattern.length() < 1 ) {
throw new IllegalArgumentException();
}
checkPermission();
configure();
*** 374,385 ****
this.count = count;
this.append = append;
openFiles();
}
! // Private method to open the set of output files, based on the
! // configured instance variables.
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
manager.checkPermission();
if (count < 1) {
throw new IllegalArgumentException("file count = " + count);
--- 387,400 ----
this.count = count;
this.append = append;
openFiles();
}
! /**
! * Open the set of output files, based on the configured
! * instance variables.
! */
private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager();
manager.checkPermission();
if (count < 1) {
throw new IllegalArgumentException("file count = " + count);
*** 411,432 ****
if (locks.get(lockFileName) != null) {
// We already own this lock, for a different FileHandler
// object. Try again.
continue;
}
! FileChannel fc;
try {
! 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;
}
boolean available;
try {
! available = fc.tryLock() != null;
// We got the lock OK.
} catch (IOException ix) {
// We got an IOException while trying to get the lock.
// This normally indicates that locking is not supported
// on the target directory. We have to proceed without
--- 426,447 ----
if (locks.get(lockFileName) != null) {
// We already own this lock, for a different FileHandler
// object. Try again.
continue;
}
!
try {
! lockFileChannel = FileChannel.open(Paths.get(lockFileName),
! CREATE_NEW, WRITE);
! } catch (FileAlreadyExistsException ix) {
! // try the next lock file name in the sequence
continue;
}
+
boolean available;
try {
! available = lockFileChannel.tryLock() != null;
// We got the lock OK.
} catch (IOException ix) {
// We got an IOException while trying to get the lock.
// This normally indicates that locking is not supported
// on the target directory. We have to proceed without
*** 438,448 ****
locks.put(lockFileName, lockFileName);
break;
}
// We failed to get the lock. Try next file.
! fc.close();
}
}
files = new File[count];
for (int i = 0; i < count; i++) {
--- 453,463 ----
locks.put(lockFileName, lockFileName);
break;
}
// We failed to get the lock. Try next file.
! lockFileChannel.close();
}
}
files = new File[count];
for (int i = 0; i < count; i++) {
*** 470,481 ****
// Install the normal default ErrorManager.
setErrorManager(new ErrorManager());
}
! // Generate a filename from a pattern.
! private File generate(String pattern, int generation, int unique) throws IOException {
File file = null;
String word = "";
int ix = 0;
boolean sawg = false;
boolean sawu = false;
--- 485,505 ----
// Install the normal default ErrorManager.
setErrorManager(new ErrorManager());
}
! /**
! * Generate a file based on a user-supplied pattern, generation number,
! * and an integer uniqueness suffix
! * @param pattern the pattern for naming the output file
! * @param generation the generation number to distinguish rotated logs
! * @param unique a unique number to resolve conflicts
! * @return the generated File
! * @throws IOException
! */
! private File generate(String pattern, int generation, int unique)
! throws IOException {
File file = null;
String word = "";
int ix = 0;
boolean sawg = false;
boolean sawu = false;
*** 546,556 ****
}
}
return file;
}
! // Rotate the set of output files
private synchronized void rotate() {
Level oldLevel = getLevel();
setLevel(Level.OFF);
super.close();
--- 570,582 ----
}
}
return file;
}
! /**
! * Rotate the set of output files
! */
private synchronized void rotate() {
Level oldLevel = getLevel();
setLevel(Level.OFF);
super.close();
*** 613,641 ****
// Unlock any lock file.
if (lockFileName == null) {
return;
}
try {
! // Closing the lock file's FileOutputStream will close
! // the underlying channel and free any locks.
! lockStream.close();
} catch (Exception ex) {
// Problems closing the stream. Punt.
}
synchronized(locks) {
locks.remove(lockFileName);
}
new File(lockFileName).delete();
lockFileName = null;
! lockStream = null;
}
private static class InitializationErrorManager extends ErrorManager {
Exception lastException;
public void error(String msg, Exception ex, int code) {
lastException = ex;
}
}
! // Private native method to check if we are in a set UID program.
private static native boolean isSetUID();
}
--- 639,668 ----
// Unlock any lock file.
if (lockFileName == null) {
return;
}
try {
! // Close the lock file channel (which also will free any locks)
! lockFileChannel.close();
} catch (Exception ex) {
// Problems closing the stream. Punt.
}
synchronized(locks) {
locks.remove(lockFileName);
}
new File(lockFileName).delete();
lockFileName = null;
! lockFileChannel = null;
}
private static class InitializationErrorManager extends ErrorManager {
Exception lastException;
public void error(String msg, Exception ex, int code) {
lastException = ex;
}
}
! /**
! * check if we are in a set UID program.
! */
private static native boolean isSetUID();
}