Configure Logger Programmatically

I want to programmatically configure my java.util.logging.Logger

. According to Oracle Docs , this seems possible.

However, this example shows that something is wrong here:

public static void main(String[] args) {
    Logger logger = Logger.getLogger("org.acme.project");
    logger.setLevel(Level.SEVERE);
    logger = null;

    System.gc();

    logger = Logger.getLogger("org.acme.project");
    logger.warning("You shouldn't see this warning!");
    logger.severe("But this error!");
}

      

If you run the code, you will see both messages. However, if you delete logger = null;

or System.gc();

, you only see the second one, which proves that the garbage collector is simply deleting the configured log, leaving it Logger.getLogger(String)

with a new one (by default).

To "solve" this, I could just keep a link to that particular registrar somewhere, but I don't think that's a good idea.

So how can I determine the program log?

+3


source to share


2 answers


To "solve" this, I could just keep a link to that particular registrar somewhere, but I don't think that's a good idea.

In versions prior to JDK6u18, the LogManager contained a strong link to the logger. After this pattern, the java.util.logging.Logger.getLogger () method points the reader to a strong reference:

Note. The LogManager can only store a weak reference to the newly created Logger. It is important to understand that a previously created Logger with a given name can be compiled at any time if there is no strong reference to the Logger. In particular, this means that there are two callbacks of type getLogger ("MyLogger"). Log (...) can use different Logger objects named "MyLogger" unless there is a strong reference to a Logger named "MyLogger" elsewhere in the program.

A common idiom is to use:



private static final String CLASS_NAME = Foo.class.getName();
private static final Logger logger = Logger.getLogger(CLASS_NAME);

      

The reason you define CLASS_NAME

is also because you will be using it for log trace methods or methodslogp

Also, tools like FindBugs will detect this lost log template as:

LG: Potentially lost logger changes due to weak link in OpenJDK (LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE)

+2


source


Javadoc for Logger # getLogger refers to your problem:

https://docs.oracle.com/javase/7/docs/api/java/util/logging/Logger.html#getLogger%28java.lang.String%29

Note. The LogManager can only store a weak reference to the newly created Logger. It is important to understand that a previously created Logger with a given name can be compiled at any time if there is no strong reference to the Logger. In particular, this means that there are two callbacks of type getLogger ("MyLogger"). Log (...) can use different Logger objects named "MyLogger" unless there is a strong reference to a Logger named "MyLogger" elsewhere in the program.



In turn, Logger # getLogger calls LogManager # addLogger and its documentation also recommends that you keep the link:

https://docs.oracle.com/javase/7/docs/api/java/util/logging/LogManager.html#addLogger%28java.util.logging.Logger%29

The application must maintain its own reference to the Logger object to avoid garbage collection. LogManager can only store a weak reference.

0


source







All Articles