There is a class which should store logs in a local file, which is hardcoded into the program.
The logic for initializing it as follows:
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
public class Util {
private static final Logger LOGGER = Logger.getLogger(Util.class.getName());
private static final FileHandler filehandler = createFileHandler();
private static FileHandler createFileHandler(){
FileHandler handler;
try {
handler = new FileHandler("security.log", 0, 1, true);
LOGGER.addHandler(filehandler);
} catch (IOException | SecurityException e) {
handler = null;
LOGGER.log(Level.SEVERE, "Unable to create Security log!");
}
return handler;
}
public static String use_util(){
LOGGER.log(Level.INFO, "Utils are used!");
return "It's just I don't know.. a string, man.";
}
public static void main(String[] args){
System.out.println(Util.use_util());
}
}
Upon the first call of use_util
there is a nullpointerexception however, stating that LOGGER
is null:
$javac Util.java
$java -Xmx128M -Xms16M Util
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException
at java.util.logging.Logger.addHandler(Logger.java:1748)
at Util.createFileHandler(Util.java:14)
at Util.<clinit>(Util.java:8)
According to the Java spec section 12.4.2 :
Then, initialize the final class variables and fields of interfaces whose values are compile-time >constant expressions (§8.3.2.1, §9.3.1, §13.4.9, §15.28). ...
Next, execute either the class variable initializers and static initializers of the class, or the field >initializers of the interface, in textual order, as though they were a single block.
So based on that, LOGGER
should be initialized before fileHandler
is. Despite that, LOGGER
seems to be null when the fileHandler
is initialized...
Why is that? How can the initialization order be forced?
Caused by: java.lang.NullPointerException
at java.util.logging.Logger.addHandler(Logger.java:1748)
From the way I read this, the class fields are not an issue here.
LOGGER
is not null, the call towards LOGGER.addHandler()
is executed, but fails internally.
This is because you pass filehandler
into the call, not the handler handler
that you just initialized in the line before.
Since you're still within the initialization execution for filehandler
at that point, it is still null
.