-1

I'm having below code and creating log file using java.util.logging.FileHandler.

In this scenario, I should manually close the resources in finally block.

try {
fh = new FileHandler("Test.log");
logger.addHandler(fh);
...
} catch (IOException e) {
e.printStackTrace();
} finally {
  if(fh!=null) { fh.close() };
}

This code works. Now, I thought that it may implement Autocloseable interface. So, I decided to use try-with-resources for FileHandler so that the resources will be automatically closed (to remove manual job of closing the resources).

The code I tried is given below :

try(fh = new FileHandler("Test.log")) {
logger.addHandler(fh);
...
} catch (IOException e) {
e.printStackTrace();
}

But this code doesn't work.

It give an error saying that :

The resource type FileHandler does not implement java.lang.AutoCloseable'

  • How to close the file handler automatically using try-with-resources if possible ?

  • Do I need to close manually ? Or there is any other approach that I can take.

Anish B.
  • 9,111
  • 3
  • 21
  • 41
Bharathiraja
  • 714
  • 1
  • 12
  • 20
  • 1
    This doesn't make sense. You need the handler to remain open. – user207421 Jun 05 '20 at 06:38
  • 1
    Why would you add the `FileHandler` to the logger, then close it? It doesn't implement `AutoClosable`, because it's not supposed to be used like that. – Kayaman Jun 05 '20 at 06:38
  • 1
    And why aren't you doing this via the configuration file? – user207421 Jun 05 '20 at 06:40
  • 1
    @AnishB. Oh yes there is. See the [Javadoc](https://docs.oracle.com/javase/7/docs/api/java/util/logging/FileHandler.html#close()). – user207421 Jun 05 '20 at 06:41
  • 1
    Just for the record, there is actually an enhancement request to make `Handler` implement `AutoCloseable` - so probably there are use cases for this: https://bugs.openjdk.java.net/browse/JDK-8025709 – Forketyfork Jun 05 '20 at 06:44
  • 1
    @SergeiPetunin even the ticket acknowledges that "use cases wherein TWR will be useful for a Handler are limited" and doesn't actually describe the situation where it would be usable, so it's a bit hard to agree on whether it's valid. I'm not sure I agree with "All classes that have `close()` should implement `AutoClosable`" argument either. – Kayaman Jun 05 '20 at 06:56
  • @Kayaman And it's not even possible. There is a whole raft of classes in JNDI whose `close()` doesn't throw `IOException` and so cannot be `Autoclosaeble`. Sadly enough. – user207421 Jun 05 '20 at 08:08
  • 1
    @AnishB. I'm curious why you posted that misinformation without even checking. Please don't. – user207421 Jun 05 '20 at 08:10
  • @user207421 i'm not sure why you mentioned 'handler remain open'. can you please elaborate little bit..i understand that when filehandler open, we should close the file. else **.lck** file created in the directory and its incomplete. – Bharathiraja Jun 05 '20 at 09:22
  • @bharathiraja The purpose of installing a log handler is to handle all future logging. If you close it straight after you install it, it can't do that, or indeed anything, except for events that get logged between the install and the close. The log manager will look after the close in due course. No intervention in that is required. – user207421 Jun 05 '20 at 09:38
  • 1
    @AnishB. You haven't answered my question. – user207421 Jun 05 '20 at 09:39
  • 1
    @AnishB why you deleted the post, that is useful for me. please post it. i',m trying in that way. – Bharathiraja Jun 05 '20 at 11:32
  • @bharathiraja I'm reposting the answer again for you. – Anish B. Jun 05 '20 at 11:36
  • @bharathiraja I have posted my answer. – Anish B. Jun 05 '20 at 11:40
  • 1
    @MarquisofLorne, i'm not logging application logs using `FileHandler`. my scenario is to log specific information when any exception occurs or any validation fails. say example i have a csv and i'm reading and checking whether file is valid format or valid file name. if file name is not valid then I should write `File Name is Invalid`. and also each csv file generating a log. example `test.csv` will have `test.log` and required exception details will be there in file. For application logs I have configured log4j2 and this will have all application specific logs. – Bharathiraja Jun 05 '20 at 11:51

1 Answers1

1

Firstly, FileHandler class doesn't implement AutoCloseable interface.

So, you can't use try-with-resources on FileHandler.

Therefore, you have to call the close() method explicitly.

So, you have to go for the first approach you took.

public class Example {

    private static Logger logger = Logger.getLogger("...");

    public static void main(String[] args) {
        FileHandler fh = null;
        try {
            fh = new FileHandler("Test.log");
            logger.addHandler(fh);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fh != null) {
                fh.close();
            }
        }
    }

}

You can try creating your own custom Filehandler class and implement AutoCloseable interface in that.

For example :

class CustomFileHandler implements AutoCloseable {

    private FileHandler fileHandler;

    public CustomFileHandler(FileHandler fileHandler) {
        this.setFileHandler(fileHandler);
    }

    @Override
    public void close() throws Exception {
        if (fileHandler != null) {
            fileHandler.close();
        }
    }

    public FileHandler getFileHandler() {
        return fileHandler;
    }

    private void setFileHandler(FileHandler fileHandler) {
        this.fileHandler = fileHandler;
    }

}

public class Example {

  private static Logger logger = Logger.getLogger("...");

  public static void main(String[] args) {
    try (CustomFileHandler fh = new CustomFileHandler(new FileHandler("Test.log"))) {
        logger.addHandler(fh.getFileHandler());
        ........
    } catch (Exception e) {
        e.printStackTrace();
    } 
  }

}
Anish B.
  • 9,111
  • 3
  • 21
  • 41
  • @bharathiraja Now, is this ok ? – Anish B. Jun 05 '20 at 11:43
  • 2
    This answer, while showing the OP how to avoid a compiler error, **is an incredibly bad idea.** Closing a logging handler without removing it from the logging framework means that you've just put the logging framework into an indeterminate state. Subsequent log messages may be dropped, or may cause an application exception. – kdgregory Jun 05 '20 at 13:33
  • @kdgregory Please read comments in the question. OP asked for something else. – Anish B. Jun 05 '20 at 13:52
  • @kdgregory I have updated my answer. This is an approach not a workaround to avoid compile time error. – Anish B. Jun 06 '20 at 02:49
  • 1
    1. `Autocloseable` is not a class but an interface. 2. The OP's question is pointless in a way that you haven't even identified, let alone resolved. This code will execute but it won't accomplish anything useful whatsoever. – user207421 Jun 06 '20 at 10:19
  • @MarquisofLorne Okay I agree. But the user who has asked the question wanted it. I think he wants to do something else with this approach (he wants to modify according to his requirements). So, I posted this answer. Otherwise, I have deleted that. Moreover, I have already edited the slight mistake for `Autocloseable` interface that I did in my answer. Sorry for writing it as class. – Anish B. Jun 06 '20 at 14:00
  • 1
    @All as i already explained what i need in the comments.i'm not logging application logs using FileHandler. my scenario is to log specific information when any exception occurs or any validation fails. say example i have a csv and i'm reading and checking whether file is valid format or valid file name. if file name is not valid then I should write File Name is Invalid. and also each csv file generating a log. example test.csv will have test.log and required exception details will be there in file. For application logs I have configured log4j2 and this will have all application specific logs. – Bharathiraja Jun 06 '20 at 15:05
  • 1
    @All still do you think, i shouldnt use `java.util.logging.FileHandler`.for the above scenario. – Bharathiraja Jun 06 '20 at 15:06
  • @MarquisofLorne, All, please reply for the above comments. Your suggestions are valuable for me. – Bharathiraja Jun 08 '20 at 06:37