10

I need to enable logging for some JDK7 internal class programmatically.

This is what I do in the initialization of my application:

httpLogger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
httpLogger.setLevel(Level.FINEST);

where httpLogger is a strong reference (in order to avoid the logger being garbage collected). I also set the level of the ConsoleHandler to ALL. However I cannot get any output.

If I do it via logging configuration file it works as expected.

I may be wrong but I'm thinking this has something to do with me not understanding the PlatformLogger which was introduced in Java 7 and which - afaik - is now used for all JDK internal logging. Or maybe I just don't understand J.U.L. well enough.

I'm guessing it would work if I did:

httpLogger = PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
httpLogger.setLevel(Level.FINEST);

but PlatformLogger class is in a package I cannot reference.

What is PlatformLogger ?

Here's the JavaDoc:

Platform logger provides an API for the JRE components to log
messages.  This enables the runtime components to eliminate the
static dependency of the logging facility and also defers the
java.util.logging initialization until it is enabled.
In addition, the PlatformLogger API can be used if the logging
module does not exist.

If the logging facility is not enabled, the platform loggers
will output log messages per the default logging configuration
(see below). In this implementation, it does not log the
the stack frame information issuing the log message.

When the logging facility is enabled (at startup or runtime),
the java.util.logging.Logger will be created for each platform
logger and all log messages will be forwarded to the Logger
to handle.

Logging facility is "enabled" when one of the following
conditions is met:
1) a system property "java.util.logging.config.class" or
    "java.util.logging.config.file" is set
2) java.util.logging.LogManager or java.util.logging.Logger
    is referenced that will trigger the logging initialization.

Default logging configuration:
  global logging level = INFO
  handlers = java.util.logging.ConsoleHandler
  java.util.logging.ConsoleHandler.level = INFO
  java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

Limitation:
<JAVA_HOME>/lib/logging.properties is the system-wide logging
configuration defined in the specification and read in the
default case to configure any java.util.logging.Logger instances.
Platform loggers will not detect if <JAVA_HOME>/lib/logging.properties
is modified. In other words, unless the java.util.logging API
is used at runtime or the logging system properties is set,
the platform loggers will use the default setting described above.
The platform loggers are designed for JDK developers use and
this limitation can be workaround with setting
-Djava.util.logging.config.file system property.

@since 1.7
peterh
  • 18,404
  • 12
  • 87
  • 115
  • It sounds like an out-of-order logging initialization - Did you get the default LogManager, which reads the system configuration, first? – Anya Shenanigans Dec 28 '13 at 14:09
  • @Petesh. You mean for setting Level on ConsoleHandler? Actually I'm now experimenting with a working `logging.properties`. I then remove the line from this file which sets the Level for the class and then try to do that programmatically instead .. i.e. a situation where I use **both** code and config file. Still can't get it to work. – peterh Dec 28 '13 at 15:53
  • 1
    Just did a test in the same app where I set the log level for my own class programmatically. That works as expected. I do this the same way as for the JDK internal class. Again this just points once again - I believe - to my lack of understanding `PlatformLogger`. – peterh Dec 28 '13 at 15:57
  • @nolan6000 Did you ever find an answer to this problem? Also, for the record, what was your logging config file contents, before you were trying it programmatically? I'm desperately trying to get one of the `java.awt.focus` classes to print its debug output; it's all set up to use PlatformLogger but I cannot get it enabled. – Ti Strga Jun 12 '14 at 16:36
  • No, never found out how to do it programmatically. My config file simply had `sun.net.www.protocol.http.HttpURLConnection.level = FINEST` and that worked well. – peterh Jun 12 '14 at 22:42

2 Answers2

8

My solution that appears at the beginning of a small custom widget demo program:

// Log all focus messages.
final Logger rootLogger = Logger.getLogger("");
rootLogger.setLevel(Level.ALL);
final ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.ALL);
// Because there are a lot of focus messages, make them
// a little easier to read by logging only the message.
consoleHandler.setFormatter(new Formatter() {
    @Override
    public String format(LogRecord record) {
        return "FOCUS: " + record.getMessage() + '\n';
    }
});
final Logger logger = Logger.getLogger("java.awt.focus.Component");
logger.setLevel(Level.ALL);
logger.setUseParentHandlers(false);
logger.addHandler(consoleHandler);

It's unclear to me why I needed to get then set the rootLogger level to ALL, but that's what I needed.

K. R. Walker
  • 81
  • 1
  • 4
1

You have to read it first what is saying.

 the PlatformLogger API can be used if the logging module does not exist

Well the if you want to use that API you than use following import statement.

import sun.util.logging.PlatformLogger;

Above is the complete reference to your destination.

For Further Reference Visit BUG Tracking of Java

Balochlens
  • 49
  • 1
  • 11
  • 1
    Hmm. I wouldn't say I want to use the API as such, I just want to enable logging for that particular JDK class since it gives me exactly what I want in terms of tracing what goes on. Using something from "sun." package isn't exactly straight-forward, at least not with Maven which by default will not include most JDK internal classes on the compile classpath. Haven't figured that one out yet. But still I would like not to have to directly reference JDK internal classes. – peterh Dec 28 '13 at 19:51
  • 1
    The idea behind PlatformLogger, afaiu, is that it will work even if the J.U.L. framework is not available. (the Project Jigsaw effort). But in my case J.U.L. **is** available because the JDK is still not modular. PlatformLogger is a preparation for what will come in Java 9. – peterh Dec 29 '13 at 14:07