• Post Reply Bookmark Topic Watch Topic
  • New Topic

Issue resoliving shutdown hook in logger.LogManager  RSS feed

 
Michael Beatty
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My root issue was that I have a shutdown hook that logs a shutdown message to a log file. Seemingly randomly the shutdown message was not showing up.

In my research I learned that the java.util.logging.Logger class that I was using included its own shutdown hook. Since the OS executes the threads with shutdown hooks in no particular order, the Logger class was dying before the log message could be writter. I found the solution was to override the "reset" method in the Logger LogManager class using this example.


My application isn't quite as straight forward as I'm using multiple class files. So what I did was create a new class file MyLogManager with the following code:


Then in my main Class I put at the top:


The insantiate my logger


The constructor to my MyLogger



Now, once I get to my shutdown hook in my main Class



When I run the code, I'm getting Null Pointer Exceptiopn that is getting thrown from my resetFinally method. In debugging the null pointer is coming from the fact that instance is null. Why? And how do I fix?

Any help would be appreciated.
 
Knute Snortum
Sheriff
Posts: 4279
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You seem to be calling resetFinally is a static way, and since it's static, you don't go through the constructor -- and there is no instance anyway.

 
Campbell Ritchie
Marshal
Posts: 56553
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

There is another little problem with shutdown hooks; they must be fast. Once the JVM starts to exit there is only a limited time available for whatever the task is. Logging into a file which is already open should work however. I presume your logger automatically closes the file?
The OS doesn't execute the Threads; the JVM does that. But as you say there is no particular order to execution of Threads. Indeed on a modern multi‑core machine they may truly be executed simultaneously.

Please don't try to squash methods into one line. Please indent and space them properly, then everybody can see what they are doing. I might be able to do that for you, so you can see how much better it looks.

There is something very peculiar about instance = this. You are changing the static instance every time you create a new instance. That is going to cause all sorts of problems. And why do you have a field without private access?

As for what is null, that is difficult to see from the code you posted. But if you post the stack trace, with a translation of line numbers to what you posted (with any corrections of mine), and you identify the line, you have a good chance of guessing what is null, or at least only having a few suspects to question.
 
Michael Beatty
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
There is something very peculiar about instance = this. You are changing the static instance every time you create a new instance. That is going to cause all sorts of problems. And why do you have a field without private access?

As for what is null, that is difficult to see from the code you posted. But if you post the stack trace, with a translation of line numbers to what you posted (with any corrections of mine), and you identify the line, you have a good chance of guessing what is null, or at least only having a few suspects to question.


Thanks for the welcome!

As to what is Null, I'm quite certain it is the "instance" variable as determined by various println() statements for the reasons pointed out my Mr Snortum. I, however, am fairly green when it comes to Java programming so while things "make sense" I don't necessarily understand fully how to fix.
 
Knute Snortum
Sheriff
Posts: 4279
127
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


This whole class is a little odd. The only reason I can see for resetFinally to be static is because you're calling it from main, which is a bad practice. Main should only be used to start the program. It is often as small as this:

You would put the code that's in main now into startup.

Now back to MyLoginManager. I don't see a reason to have instance now, so get rid of it. You can use the default constructor, so get rid of your constructor. Now resetFinally is just reset0() so maybe you don't need that either. Also desiced whether MyLogManager should be static or not and change the members as needed.

There's a lot going on here as you can see.

 
Campbell Ritchie
Marshal
Posts: 56553
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't do any “how” until you have worked out “what” you are doing.
What is the instance field supposed to be? Is it supposed to be some sort of singleton? Why do you want a singleton? Ten years ago people thought singletons were the bees' knees, now people think they are just about the opposite. If you want a singleton, start by making your class final. If it implements Serializable (or similar) you have to provide readResolve and similar methods to maintain singleton‑ness. Don't try double‑checked locking which doesn't work. Actually, I think it does work since the new Java® memory model in Java5, but still don't use it. The best way to create a singleton is a one‑element enum but you can't make enums subclasses of something else. So you will have to find a copy of Effective Java™ by Joshua Bloch and you find he creates only one instance of the Elvis class.you should be able to make your logger class into a singleton because the code required will hardly differ from the Elvis class. Of course, if you want something different from a singleton you will need different code.
 
Michael Beatty
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Knute Snortum wrote:
This whole class is a little odd. The only reason I can see for resetFinally to be static is because you're calling it from main, which is a bad practice. Main should only be used to start the program. It is often as small as this:

You would put the code that's in main now into startup.

Now back to MyLoginManager. I don't see a reason to have instance now, so get rid of it. You can use the default constructor, so get rid of your constructor. Now resetFinally is just reset0() so maybe you don't need that either. Also desiced whether MyLogManager should be static or not and change the members as needed.



Wonderful, its always nice to see the solution is to simplify. I've done as you suggest. I've created a non static method startup() and placed my "Main" code in it and run that method from the Main class. I've removed the MyLogManager constructor, using the default and removed the reset0(), calling super.reset() directly from resetFinally. In my startup(), I instantiate MyLogManager mgr = new MyLogManager(), write my closing output, then execute mgr.resetFinally(). Works perfectly!



In my startup()


Thank You!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!