Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8153955

increase java.util.logging.FileHandler MAX_LOCKS limit

    Details

      Backports

        Description

        The submitter faced following problem.
        OS : Solaris
        Java : 6u65 (may be 64bit ) / JDK 7 and 8 are same result.
        When they invoke a lot of same Java Program that using java.util.logger with
        FileHandler,
        IOException occured.
        Can't load log handler "java.util.logging.FileHandler"
        java.io.IOException: Couldn't get lock for test%u.%g.log
        java.io.IOException: Couldn't get lock for test%u.%g.log
                at java.util.logging.FileHandler.openFiles(FileHandler.java:nnn)
                at java.util.logging.FileHandler.<init>(FileHandler.java:nnn)
                 ...
            (Note: it is not a actual stacktrace)
            
        Submitter's evaluation:
        [src/share/classes/java/util/logging/FileHandler.java]
             ...
            private static final int MAX_LOCKS = 100;
             ...
                // Create a lock file. This grants us exclusive access
                // to our set of output files, as long as we are alive.
                int unique = -1;
                for (;;) {
                    unique++;
                    if (unique > MAX_LOCKS) {
                        throw new IOException("Couldn't get lock for " + pattern); <<
        this Exception happen >>
                    }
                    // Generate a lock file name from the "unique" int.
            "unique" range is 0 to 100, so "max number of concurrent process" is
        limited to 101.

        [test case]:
        -- logging.properties --
        handlers= java.util.logging.FileHandler
        .level= ALL
        java.util.logging.FileHandler.pattern = test%u.%g.log
        java.util.logging.FileHandler.limit = 10000
        java.util.logging.FileHandler.count = 10
        java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
        -- LoggingTest.java --
        import java.io.*;
        import java.util.*;
        import java.util.logging.*;
        class LoggingTest {
          public static void main(String[] args) throws Exception {
            System.setProperty("java.util.logging.config.file",
        "logging.properties");
            Logger logger = Logger.getLogger(LoggingTest.class.getName());
            for (int i = 0; i < 1200; i++) {
              logger.log(Level.INFO, String.format("Test: %s", logger));
              Thread.sleep(100L);
            }
          }
        }
        -- do101.bash --
        #!/usr/bin/bash
        rm *.log *.lck
        for i in {0..101}
        do
          echo $i
          ${JAVA_HOME}/bin/java -Xmx8m LoggingTest &
        done
        sleep 15
        pkill java
        ----------------------------------------------------
        % ./do101.bash
          ...
        95
        96
        97
        98
        99
        100
        101
        Can't load log handler "java.util.logging.FileHandler"
        java.io.IOException: Couldn't get lock for test%u.%g.log
        java.io.IOException: Couldn't get lock for test%u.%g.log
                at java.util.logging.FileHandler.openFiles(FileHandler.java:372)
                at java.util.logging.FileHandler.<init>(FileHandler.java:208)
                at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
        Method)
                at
        sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccesso
        rImpl.java:39)
                at
        sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructo
        rAccessorImpl.java:27)
                at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
                at java.lang.Class.newInstance0(Class.java:355)
                at java.lang.Class.newInstance(Class.java:308)
                at java.util.logging.LogManager$3.run(LogManager.java:359)
        ¦ @ at java.security.AccessController.doPrivileged(Native Method)
                at
        java.util.logging.LogManager.loadLoggerHandlers(LogManager.java:345)
                at
        java.util.logging.LogManager.initializeGlobalHandlers(LogManager.java:1032)
                at java.util.logging.LogManager.access$1100(LogManager.java:129)
                at
        java.util.logging.LogManager$RootLogger.getHandlers(LogManager.java:1113)
                at java.util.logging.Logger.log(Logger.java:474)
                at java.util.logging.Logger.doLog(Logger.java:500)
                at java.util.logging.Logger.log(Logger.java:523)
                at LoggingTest.main(LoggingTest.java:13)
                
        [Expected]
        "max number of concurrent process" is unlimited (logically).

        Java API doc (java.util.logging.FileHanlder) writes:
        ==============================================================================
         Normally the "%u" unique field is set to 0.
         However, if the FileHandler tries to open the filename and finds the file
         is currently in use by another process it will increment the unique number
         field and try again. This will be repeated until FileHandler finds a file
        name
         that is not currently in use. If there is a conflict and no "%u" field has
        been
         specified, it will be added at the end of the filename after a dot.
         (This will be after any automatically added generation number.)
        ==============================================================================
         This is not describe the limitation of max number of process / conflict.
         

          Activity

          Hide
          tongwan Andrew Wang added a comment -
          The licensee believes that a fundamental point of this issue is MAX_LOCKS cannot be changed. Even if MAX_LOCKS set a reasonable value for now, maybe same problem turns up in the future.

          Also, https://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html mentioned "increment the unique number field and try again".
          So MAX_LOCKS should NOT be extremely large because it may cause a performance problem in scalability.
          Show
          tongwan Andrew Wang added a comment - The licensee believes that a fundamental point of this issue is MAX_LOCKS cannot be changed. Even if MAX_LOCKS set a reasonable value for now, maybe same problem turns up in the future. Also, https://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html mentioned "increment the unique number field and try again". So MAX_LOCKS should NOT be extremely large because it may cause a performance problem in scalability.
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d473607154f0
          User: coffeys
          Date: 2016-06-28 14:12:40 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/d473607154f0 User: coffeys Date: 2016-06-28 14:12:40 +0000
          Hide
          hgupdate HG Updates added a comment -
          URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/d473607154f0
          User: lana
          Date: 2016-07-06 20:17:35 +0000
          Show
          hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/jdk/rev/d473607154f0 User: lana Date: 2016-07-06 20:17:35 +0000
          Hide
          afomin Alexander Fomin (Inactive) added a comment -
          UR SQE OK to defer it from PSU16_04
          Show
          afomin Alexander Fomin (Inactive) added a comment - UR SQE OK to defer it from PSU16_04

            People

            • Assignee:
              rpatil Ramanand Patil
              Reporter:
              shadowbug Shadow Bug
            • Votes:
              0 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: