JDK-8187073 : The java.util.logging.Level.findLevel() will not correctly find a Level by it's int value
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.logging
  • Affected Version: 9
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2017-08-30
  • Updated: 2017-12-18
  • Resolved: 2017-12-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10
10 b36Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :


ADDITIONAL OS VERSION INFORMATION :
Linux 4.12.8-300.fc26.x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
The java.util.logging.Level.findLevel() internal method will attempt to find a level by name, if not found it will attempt to find it by an int value then finally by localized method name. However when finding the level by it's int value the value will never be returned. It will always fall through to the KnownLevel.findByLocalizedLevelName().

try {
    int x = Integer.parseInt(name);
    level = KnownLevel.findByValue(x, KnownLevel::mirrored);
    if (!level.isPresent()) {
        // add new Level
        Level levelObject = new Level(name, x);
        // There's no need to use a reachability fence here because
        // KnownLevel keeps a strong reference on the level when
        // level.getClass() == Level.class.
        return KnownLevel.findByValue(x, KnownLevel::mirrored).get();
    }
} catch (NumberFormatException ex) {
    // Not an integer.
    // Drop through.
}

level = KnownLevel.findByLocalizedLevelName(name,
        KnownLevel::mirrored);
if (level.isPresent()) {
    return level.get();
}

return null;

In the above snippet it only checks if the optional value is not found when looking up by int value. This should return the value if it's found.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Simply invoke java.util.logging.Level.findLevel("400"). You should get a null value.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
In the steps above this should result in Level.TRACE being returned.
ACTUAL -
A null value is returned.

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
Looks like a bug. I probably introduced it. Strange that no test found the issue!
01-09-2017

The findByLevel() is not a public API, the public API is parse(), using which I get a correct output. Level level = Level.parse("400"); System.out.println(level); // prints FINER
01-09-2017