Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: file write on finalize method

Tags:

java

file

In my understanding a singleton object will destroy only when the application is about to terminate. So in C++ I write a Singleton class to log my application and in that Singleton logger's destructor I log the time when my application was terminated. Things worked perfectly in C++.


Now I want to have that same logger in Java, as in java there is no destructor so I implemented the finalize method for that singleton logger. But it seem that finalize method actually never get called. So, I add that System.runFinalizersOnExit(true); line, somewhere in my code (though I know it is deprecated) and that finalize method get called every time before termination of the app. But still there is a problem! If I try to write anything on file in that finalize method, It does not work, though System.out work without any problem! :(

Can you guys help me on this problem? Here is a sample code of what I am try to do:

Singleton Logger Class:

public class MyLogger {
    FileWriter writer;
    private MyLogger() {
        try {
            this.writer = new FileWriter("log.txt");
        }
        catch (IOException ex) {
        }
    }

    public static MyLogger getInstance() {
        return MyLoggerHolder.INSTANCE;
    }

    private static class MyLoggerHolder {
        private static final MyLogger INSTANCE = new MyLogger();
    }

    @Override
    protected void finalize () {
        try {
            super.finalize();
            System.out.println("Here"); //worked correctly.
            this.writer.write(new Date().toString()+System.getProperty("line.separator"));
            this.writer.write("End");
            this.writer.flush(); //does not work!
            this.writer.close();
        }
        catch (Throwable ex) {
        }
    }
    public synchronized void log(String str) {
        try {
            this.writer.write(new Date().toString()+System.getProperty("line.separator"));
            this.writer.write(str+"\n");
            this.writer.flush();
        }
        catch (IOException ex) {
        }
    }
 }

Main:

public class Main {
    public static void main(String[] args) {
        System.runFinalizersOnExit(true);
        MyLogger logger = MyLogger.getInstance();
        logger.log("test");
    }
}
like image 839
sowrov Avatar asked Feb 07 '26 02:02

sowrov


1 Answers

This is one of those curious questions. Note: I wouldn't write my own Logging class - look at log4j or something...

As already stated, I really wouldn't really use finalize.

...

From what you say, your aim is just to run something as the program stops.

I'd register a shutdownhook instead ...

A shutdownhook is a user-defined object which extends Thread class. e.g. you could define a static inner class inside your logger

Here's an example:

http://www.crazysquirrel.com/computing/java/basics/java-shutdown-hooks.jspx

And here's the API doc: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29

like image 178
laher Avatar answered Feb 08 '26 16:02

laher