• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

When to close the RandomAccessFile?!!

 
Theo van Loon
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all,
Upon instantiating my Data class i read the header etc. works just fine. But now i'm coming to the point that i have to update the dbfile. Now i see that i probably do something wrong. In all my methods i use the raf to read data write data etc. I never close the raf though when should i do this...
I read all the records from the dbfile into DataInfo[]
how can i make sure these instances of DataInfo are consistent with the information in the raf?
I'm a bit puzzled on this one...
[ March 27, 2004: Message edited by: Theo van Loon ]
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you already write to the file whenever a record is updated/deleted, etc, just closing the file on server shutdown should be fine. You could expose a specific method for doing so to your clients. Someone on this forum also closed the file in the finalize method of the data class, and that turned out fine.
The topics NX: Saving the database and NX: No caching at all - is that OK? deal with the same issue - you might find them helpful.
 
Theo van Loon
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
well i will go with closing the Raf in the finalize method. But however, i now update my record and it seems to work ok. I don't know yet how to get the changes in the model (suggestions??) But i update the record in the raf and it seems to write the correct values.

But when i start the application after this it's gone all wrong. In the finalize method of Data i close the raf but it never reaches it...
Could someone please help?
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is just a hunch, but I think your problem occurs earlier: When you call raf.write(Constants.getVALIDFLAG()), then unless getVALIDFLAG() returns a byte array, then you are actually invoking RandomAccessFile.write(int), which writes one byte. My valid flag is two bytes. Is this the problem?
About the finalize method, I don't think there are any guarantees it will be called when the VM shuts down, so I plan on closing the file explicitly. Nonetheless, George mentioned succeeding with the finalize approach in the thread RandomAccessFile use (should have pointed to that thread at the beginning, sorry).
[ March 28, 2004: Message edited by: Nicky Bodentien ]
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For your information: Jacques Bosch mentions the same thing in Should I must program for closing data file?: Closing the file in the finalize method may not be the best way because there are no guarantees it will be called - but he didn't lose also marks for doing it that way.
 
Theo van Loon
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am very thankful for your help, my VALID_FLAG is a short...
So how to write a byte[] instead?
I also read the following :

Hi Ulrich,
1. You are OK.
2. The second line (me = null) is useless for sure, and I think (but I may be wrong) that the whole finalize() method isn't useful. A RAF probably closes itself before getting garbage-collected if needed (IMO).
3. Yes ! If you change your mind in the future (or if somebody else does), what's static remains static while any data which makes some sense at the instance level is just there we expect it to be.
Just one comment on your code : I like short variable names too, but I think that "ds" could be a better candidate than "me" as a name for your DataSchema instance.
Cheers,
Phil.

Thanks a lot!!!
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No magic involved. You should call the writeShort method instead of write.
Hope this helps!
[ March 28, 2004: Message edited by: Nicky Bodentien ]
 
Theo van Loon
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nicky thanks a lot and sorry for keep asking you all these questions... but what's your opinion on not closing the raf as stated in the QUOTE section?
 
Mogens Nidding
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My guess is that closing the file in the finalize method goes beyond the requirements, and that it will neither increase nor decrease your score. But I'm painfully unsure. These are my reasonings:
  • Closing the file in the finalize method is good for one situation only: If the garbage collector determines that no one is referencing your data object any more, finalize will be called, and you then have the opportunity to close the file.
  • Pro 1 for closing the file in finalize: It is a nice gesture - it basically says, "Hey, no one is using my database anymore, so let me close the database file".
  • Pro 2: Noone lost points for doing it
  • Con 1: It is probably redundant. In my opinion, the database should not hurry up and close the database file when the database becomes unreferenced - instead, the database file should close itself when it becomes unreferenced. And in practise, it does (although this is undocumented :-(). Let me try to rephrase it with fewer words: I think that the service of closing a file when it is no longer referenced belongs in one place: The file class.
  • Con 2: It is plain wrong if several instances of the data class share the same file. (Depends on your design)


  • As a practical matter, your data object will probably never become unreferenced, so finalize probably won't be called anyway. (If the system exits through Ctrl-C or System.exit, finalizers will normally not run).
    If you want to do cleanup when the system exits, you can use Runtime.getRuntime().addShutdownHook. Actually, JDC Tech Tips: July 11, 2000 demonstrates how. If you choose to do this, bear in mind that shutdown hooks must be thread safe and defensively programmed.
    I would much rather expose a close method in my database interface than add a shutdown hook.
    Did anyone get full scores without closing their files in finalize methods?
     
    Mogens Nidding
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I notice you use String.getBytes() when writing to the database... This is not guaranteed to use US-ASCII encoding, which is probably one of your requirements. Hint: Use an overloaded version of the same method.
     
    Theo van Loon
    Ranch Hand
    Posts: 71
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    So it's not yet crystal clear to me :roll: i guess when the file becomes unreferenced it has to close itself right?
    But what happens when the server shuts down and two or n clients are holding locks for performing actions?
    Can they still perform those actions, is it ok for them to do so, even if server is down. And if server is down how do you prevent the clients from performing any actions?
    A lot of questions i know, but it's important to me at this moment...
     
    Satish Avadhanam
    Ranch Hand
    Posts: 697
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Theo
    Originally posted by Theo van Loon:
    So it's not yet crystal clear to me :roll: i guess when the file becomes unreferenced it has to close itself right?

    Do you mean that the file itself has to close all by itself? If so, I don't think that's how it works. You have to implement the unreferenced interface and in the method you have to close the file. Actually RMI will take care of file closing when it client goes down, but its not guarenteed. So only we have to take care of it.

    But what happens when the server shuts down and two or n clients are holding locks for performing actions?

    If the server shuts down, clients cannot perform any operations on the server side, period. But you should concern in the opposite way i.e. what happens if the client goes down while he locks? This is called "client crashing". If you want to implement this, you can or else you can simply document that its beyond the scope of the project.

    Can they still perform those actions, is it ok for them to do so, even if server is down. And if server is down how do you prevent the clients from performing any actions?

    If server is down, it will throw exceptions like ConnectException, UnmarshallException and others. We don't need to prevent clients from any actions, but we need to take care that when clients gets these exceptions, he should be informed accordingly instead of the stack trace that server is down.

    A lot of questions i know, but it's important to me at this moment...
     
    Mogens Nidding
    Ranch Hand
    Posts: 77
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Theo van Loon:
    So it's not yet crystal clear to me :roll: i guess when the file becomes unreferenced it has to close itself right?

    The short version: Unless you have several Data objects sharing the same file, then just close your file in Data.finalize and be done with it - people got 100% score for that, so it's fine :-)
    The reason I couldn't/wouldn't make it crystal clear is that I don't know! Personally, I hate the thought of closing the database file in Data.finalize(), because
  • I'm 99% sure it's redundant because Sun already put it in FileChannelImpl.finalize() for us (and RandomAccessFile uses FileChannelImpl)!
  • It simply doesn't make sense that every class in the whole world that has a RandomAccessFile member should also possibly close the file in their finalize method.
  • Noone should let your Data class become unreferenced (that is, eligible for garbage collection) before they called some sort of close method on it. Yes, your RMI objects can become "RMI"-unreferenced due to client crashes - if/when that happens, they could call the close method.


  • On the other hand, because of the remaining 1% uncertainty (because Sun didn't document how RandomAccessFile and other I/O classes interacts with garbage collection), you could very well argue in favor of adding the finalize... whew!
    So returning to the beginning: Unless you have several Data objects sharing the same file, then just close your file in Data.finalize and be done with it - people got 100% score for that, so it's fine :-)
    I think what Satish was answering was related to RMI, which I had left out of consideration entirely... If I remember his post correctly, I agree with him :-)
     
    Theo van Loon
    Ranch Hand
    Posts: 71
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ok guys thanks a lot to put it in the most short version. It really isn't needed but for safety and giving the impression you thought about it you close the file in the finalize methode...
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic