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

increase java.util.logging.FileHandler MAX_LOCKS limit

    XMLWordPrintable

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.
         

        Attachments

          Issue Links

            Activity

              People

                rpatil Ramanand Patil (Inactive)
                shadowbug Shadow Bug
                Votes:
                0 Vote for this issue
                Watchers:
                12 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: