Java 9 logging

Java 9 includes a facade implementation for logging. The use is very simple and we can expect that logging frameworks will very soon start to support this façade. The fact that this façade is built into the JDK has two major advantage:

  • The libraries that want to log do not need to have any dependency on any logging framework or logging façade any more. The only dependency is the JDK log façade that is there anyway.
  • The JDK libraries that log themselves use this façade and thus they will log into the same log file as the application.

If we use the JDK-provided logging façade the start of the ColorManager class will be changed to the following:

package packt.java9.by.example.mastermind; 

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.Map;
import java.lang.System.Logger;

import static java.lang.System.Logger.Level.DEBUG;

@Singleton
public class ColorManager {
protected final int nrColors;
protected final Map<Color, Color> successor = new HashMap<>();
private Color first;
private final ColorFactory factory;
private static final Logger log = System.getLogger(ColorManager.class.getName());

@Inject
public ColorManager(@Named("nrColors") int nrColors,
ColorFactory factory) {
log.log(DEBUG,"creating colorManager for {0} colors",
nrColors);

In this version we do not import the slf4j classes. Instead we import the java.lang.System.Logger class.

Note that we do not need to import the System class, because the classes from the java.lang package are automatically imported. This is not true for the classes that are nested classes in the System class.

To get access to the logger the System.getLogger static method is called. This method finds the actual logger that is available and returns one for the name that we pass as argument. There is no version of the method getLogger that accepts the class as the argument. If we want to stick to the convention then we have to write ColorManager.class.getName() to get the name of the class or we can write there the name of the class as a string. The second approach has the drawback that it does not follow the change of the name of the class. Intelligent IDEs like IntelliJ, Eclipse, or Netbeans rename the references to classes automatically but they have a hard time when the name of the class is used in a string.

The interface System.Logger does not declare the convenience methods error, debug, warning, and so on, that are familiar from other logging frameworks and façade. There is only one method named log and the first argument of this method is the level of the actual log we issue. There are eight levels defined: ALL, TRACE, DEBUG, INFO, WARNING, ERROR, and OFF. When creating a log message we are supposed to use one of the middle six levels. ALL and OFF are meant to be passed to the isLoggable method. This method can be used to check if the actual logging level gets logged or not. For example, if the level is set to INFO then messages sent with DEBUG or TRACE will not be printed.

The actual implementation is located by the JDK using the service loader functionality. The log implementation has to be in a module that provides the interface java.lang.System.LoggerFinder via some implementation. In other words the module should have a class that implements the LoggerFinder interface and the module-info.java should declare which class it is using the code:

provides java.lang.System.LoggerFinder with 
packt.java9.by.example.MyLoggerFinder;

The MyLoggerFinder class has to extend the LoggerFinder abstract class with the method getLogger.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.163.229