java.util.logging.LogManager.getLogger() returns null
Asked Answered
N

3

6

I got an issue which is really baffling me. I wanted to try out some things with the JUL logging (JDK logging). I started out with the following simple program:

package biz.ple;

import java.util.logging.LogManager;
import java.util.logging.Logger;

public class Application {

    public static void main(String[] args)
    {
        Logger logA = LogManager.getLogManager().getLogger("LoggerA");
        Logger logB = LogManager.getLogManager().getLogger("LoggerB");
        if (logA == null) {
            System.out.println("LoggerA is null!");
        }
        if (logB == null) {
            System.out.println("LoggerB is null!");
        }

        String normalMsg = "Message without cookie prefix.";
        String cookieMsg = "[Cookie] Message with a cookie prefix.";

        logA.info(normalMsg);
        logA.info(cookieMsg);
        logB.info(normalMsg);
        logB.info(cookieMsg);
    }
}

Amazingly, the loggers logA and logB are always null. I read in the documentation that a logger to which the application holds no strong reference my be GCed at any time, but it seems to me that the variables logA and logB are indeed strong references, aren't they?

I really don't understand this and would appreciate any help.

Nickolai answered 23/1, 2014 at 11:26 Comment(4)
Have you created "LoggerA" elsewhere? My reading of this suggests that this just gets an existing logger, it doesn't create oneXenophon
That would explain a lot :-) I'm used to log4j logging and I kinda thought that LogManager.getLogger() would create a logger if it doesn't exist. Isn't that the case?Nickolai
Oh silly me :-) I confused LogManager.getLogger() and Logger.getLogger(). Thanks for pointing me in the right direction!Nickolai
Does seem odd, im my opinion neither should create a currently non existant loggerXenophon
X
7

My understanding is that this will only get existing loggers, not create a new one of that name. To create a new logger you need to use the static Logger.getLogger("myLogger"); command

public static void main(String[] args){
    Logger log=Logger.getLogger("myLogger");
    
    Logger logA = LogManager.getLogManager().getLogger("myLogger"); //exists
    Logger logB = LogManager.getLogManager().getLogger("nonExistantLogger"); //is null
    
}

Logger.getLogger("myLogger") javadoc:

Find or create a logger for a named subsystem. If a logger has already been created with the given name it is returned. Otherwise a new logger is created.

If a new logger is created its log level will be configured based on the LogManager configuration and it will configured to also send logging output to its parent's Handlers. It will be registered in the LogManager global namespace.

Note: The LogManager may only retain a weak reference to the newly created Logger. It is important to understand that a previously created Logger with the given name may be garbage collected at any time if there is no strong reference to the Logger. In particular, this means that two back-to-back calls like getLogger("MyLogger").log(...) may use different Logger objects named "MyLogger" if there is no strong reference to the Logger named "MyLogger" elsewhere in the program.

LogManager.getLogManager().getLogger("myLogger") javadoc

Method to find a named logger.

Note that since untrusted code may create loggers with arbitrary names this method should not be relied on to find Loggers for security sensitive logging. It is also important to note that the Logger associated with the String name may be garbage collected at any time if there is no strong reference to the Logger. The caller of this method must check the return value for null in order to properly handle the case where the Logger has been garbage collected.

Xenophon answered 23/1, 2014 at 11:34 Comment(1)
As I said, I confused the LogManager.getLogger() and Logger.getLogger() methods. Thank you!Nickolai
N
1

Give the class name for which you want to use logger as below:

    Logger logA = LogManager.getLogManager().getLogger(MyClass.class .getName());
Nucleon answered 23/1, 2014 at 11:31 Comment(0)
S
0

You do indeed have a strong reference so they have not been garbage collected. You must be using the API wrong as it is returning null references.

Storfer answered 23/1, 2014 at 11:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.