On Wed, 23 Aug 2023 15:41:16 GMT, Sean Coffey <coff...@openjdk.org> wrote:
> Recursive initialization calls possible during loading of LoggerFinder > service. > > This fix detects the recursive call and returns a temporary LoggerFinder that > is backed by a lazy logger. Automated test case developed to simulate loading > of an external LoggerFinder service while also having other threads poke > System.getLogger during this framework initialization. src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java line 230: > 228: // The accessor in which this logger is temporarily set. > 229: final LazyLoggerAccessor holder; > 230: final BooleanSupplier isLoadingThread; Suggestion: // tests whether the logger is invoked by the loading thread before // the LoggerFinder is loaded; can be null; final BooleanSupplier isLoadingThread; src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java line 234: > 232: boolean isLoadingThread() { > 233: return isLoadingThread != null && isLoadingThread.getAsBoolean(); > 234: } Suggestion: // returns true if the logger is invoked by the loading thread before the // LoggerFinder service is loaded boolean isLoadingThread() { return isLoadingThread != null && isLoadingThread.getAsBoolean(); } src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java line 948: > 946: // and the LogManager has not been initialized yet. > 947: public static boolean useLazyLoggers() { > 948: if (!BootstrapLogger.isBooted() || Suggestion: // Note: avoid triggering the initialization of the DetectBackend class // while holding the BotstrapLogger class monitor if (!BootstrapLogger.isBooted() || src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java line 425: > 423: */ > 424: public static final Logger getLogger(String name, Module module) { > 425: BootstrapLogger.detectBackend(); Suggestion: // triggers detection of the backend BootstrapLogger.detectBackend(); src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 76: > 74: > 75: // Return the loaded LoggerFinder, or load it if not already loaded. > 76: static volatile Thread loadingThread; Suggestion: // record the loadingThread while loading the backend static volatile Thread loadingThread; // Return the loaded LoggerFinder, or load it if not already loaded. src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 83: > 81: Thread currentThread = Thread.currentThread(); > 82: if (loadingThread == currentThread) { > 83: return new TemporaryLoggerFinder(); Suggestion: // recursive ttempt to load the backend while loading the backend // use a temporary logger finder that returns special BootsrtapLoggers // which will wait until loading is finished return new TemporaryLoggerFinder(); src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 98: > 96: } > 97: > 98: static boolean isLoadingThread() { Suggestion: // returns true if called by the thread that loads the LoggerFinder, while // loading the LoggerFinder. static boolean isLoadingThread() { src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 140: > 138: } > 139: > 140: static class TemporaryLoggerFinder extends LoggerFinder { Suggestion: private static final class TemporaryLoggerFinder extends LoggerFinder { src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 145: > 143: @Override > 144: public Logger apply(String name, Module module) { > 145: return LazyLoggers.getLoggerFromFinder(name, > module); A better idea might be to: Suggestion: return LazyLoggers.getLogger(name, module); src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java line 154: > 152: } > 153: }; > 154: Suggestion: private static final TemporaryLoggerFinder INSTANCE = new TemporaryLoggerFinder(); test/jdk/java/lang/System/LoggerFinder/SignedLoggerFinderTest/SignedLoggerFinderTest.java line 161: > 159: Logger testLogger = Logger.getLogger("jdk.event.security"); > 160: assertEquals(testLogger.getClass().getName(), > "java.util.logging.Logger"); > 161: testComplete = true; I believe these lines should be after `Security.setProperty("test_2", "test");`, to make sure the logger is loaded by the module that uses it. Also I was expecting some kind of checks to verify that the expected messages are indeed logged. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303306422 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303310327 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303314153 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303315890 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303317596 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303320330 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303323768 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303327924 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303324768 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303326813 PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1303342480