RFR: 8314263: Signed jars triggering Logger finder recursion and StackOverflowError [v4]
Daniel Fuchs
dfuchs at openjdk.org
Mon Aug 28 18:47:21 UTC 2023
On Mon, 28 Aug 2023 17:29:16 GMT, Sean Coffey <coffeys at 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.
>
> Sean Coffey has updated the pull request incrementally with two additional commits since the last revision:
>
> - Tidy up SignedLoggerFinderTest.java
> - Code contribution from Daniel included. New tests. Fix up extra service call issues
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java line 58:
> 56: * of this run). Running test in signed and unsigned jar mode for sanity coverage.
> 57: * The current bug only manifests when jars are signed.
> 58: */
Suggestion:
/**
* This test triggers recursion by calling `System.getLogger` in the class init
* of a custom LoggerFinder. Without the fix, this is expected to throw
* java.lang.NoClassDefFoundError: Could not initialize class jdk.internal.logger.LoggerFinderLoader$ErrorPolicy
* caused by: java.lang.StackOverflowError
*
*/
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/PlatformRecursiveLoadingTest.java line 65:
> 63: logs.stream().map(SimpleLogRecord::of).forEach(System.out::println);
> 64: logs.stream().map(SimpleLogRecord::of).forEach(SimpleLogRecord::check);
> 65: assertEquals(String.valueOf(logs.size()), String.valueOf(2));*/
Why is this code commented? Is it an oversight?
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java line 55:
> 53: * of this run). Running test in signed and unsigned jar mode for sanity coverage.
> 54: * The current bug only manifests when jars are signed.
> 55: */
Suggestion:
/**
* This test triggers recursion by calling `System.getLogger` in the class init
* of a custom LoggerFinder. Without the fix, this is expected to throw
* java.lang.NoClassDefFoundError: Could not initialize class jdk.internal.logger.LoggerFinderLoader$ErrorPolicy
* caused by: java.lang.StackOverflowError
*
*/
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/RecursiveLoadingTest.java line 61:
> 59: logs.stream().map(SimpleLogRecord::of).forEach(System.out::println);
> 60: logs.stream().map(SimpleLogRecord::of).forEach(SimpleLogRecord::check);
> 61: assertEquals(String.valueOf(logs.size()), String.valueOf(2));
See suggested changes to SimpleLoggerFinder
Suggestion:
assertEquals(String.valueOf(logs.size()), String.valueOf(3));
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java line 28:
> 26: import java.lang.*;
> 27: import java.util.*;
> 28: import java.util.concurrent.CopyOnWriteArrayList;
Suggestion:
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ConcurrentHashMap;
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java line 49:
> 47: }
> 48:
> 49: public static final CopyOnWriteArrayList<Object> LOGS = new CopyOnWriteArrayList<>();
Suggest to move the declaration before the static block above.
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java line 50:
> 48:
> 49: public static final CopyOnWriteArrayList<Object> LOGS = new CopyOnWriteArrayList<>();
> 50:
Suggestion:
private final Map<String, SimpleLogger> loggers = new ConcurrentHashMap<>();
public SimpleLoggerFinder() {
System.getLogger("dummy")
.log(System.Logger.Level.INFO,
"Logger finder service created");
}
test/jdk/java/lang/System/LoggerFinder/RecursiveLoading/SimpleLoggerFinder.java line 53:
> 51: @Override
> 52: public System.Logger getLogger(String name, Module module) {
> 53: return new SimpleLogger(name);
Suggestion:
return loggers.computeIfAbsent(name, SimpleLogger::new);
We're now getting the "dummy" logger twice, and since its constructor has side effects on its underlying jul logger implementation, we don't want to create two loggers for the same name - as that would cause two identical SimpleHandler instances to be added to the same underlying logger, making the log message appear twice in the LOGS list.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307771237
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307725024
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307773997
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307773194
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307776466
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307774748
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307775886
PR Review Comment: https://git.openjdk.org/jdk/pull/15404#discussion_r1307777399
More information about the core-libs-dev
mailing list