File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Why the EOFException always thrown ????? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Why the EOFException always thrown ?????" Watch "Why the EOFException always thrown ?????" New topic
Author

Why the EOFException always thrown ?????

Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
This question have posted at this thread. But the problem take place again and again yet. I'm sorry post my ugly question again, I only want to get a good result.
Before I put the validate block into the synchronized block, why throws this exception?? The test records in this example is only form 1 to 5, there are 32 records in my db file, so every thread there is no chance to rearch the end of the file. As the API said: "Signals that an end of file or end of stream has been reached unexpectedly during input. EOFException is mainly used by data input streams to signal end of stream. " Why in my test thorw this exception ?
As George said this problem possiblely take place when "modifies the raf pointer by seeking to the pointer position". At first, I believe this, but after study the print statements, I find that the file pointer isn't modify by other thread never ! Suppose that since the pointer is modified, why the EOFException is thrown?
pls help me, this confused me several months(from 2003/12), pls !!
[ January 31, 2004: Message edited by: Leo Tien ]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,
It seems that you've already received good advice in the previous thread.
My statements may not be very helpful, so I hope others will not think that
I have gone over the previous thread and the coding examples in great
detail, for I haven't, though I did glance over it.
Here is what the JavaDoc says about RandomAccessFile:
It is generally true of all the reading routines in this class that if end-of-file is reached
before the desired number of bytes has been read, an EOFException (which is a kind
of IOException) is thrown. If any byte cannot be read for any reason other than
end-of-file, an IOException other than EOFException is thrown. In particular, an
IOException may be thrown if the stream has been closed.
So, this would seem to imply that you are reading beyond the end of file
for some reason. I assume that you can run your test threads either one
after the other in a synchronized fashion or all at once in a concurrent
fashion; and the sequential fashion works fine, but when you then run
them concurrently on the same machine one the same day, you can eventually
get the EOF exception. If this is true, then it would strongly suggest that
multi-threading is occuring some where you did not anticipate, that your
position pointer is some how becoming invalid.
Since I can't see all your code and then create a model in mind for what is
happening where, I can only give general advice, and I apologize if it is
overly simplistic in nature (and, again, I hope those with more experience
and knowledge than me will not assume that I am covering all the bases).
I think that I am fortunate in that I have the URLyBird project, and no cookies
are passed into the lock and unlock calls; so, presumably, this project is
simpler than others (though other threads suggest that even though these
security cookies are not explicitly stated in my project, that I might want to
use them to ensure that the same client which locked a record, is the same
client which unlocks the record (and perhaps the same client which operates
on the record); though, whether I need such a security cookie depends, in part,
on how I structure the code (i.e., if lock, operation, unlock, are in one code
block, seems less likely I need the feature).
My advice is to simplify. You should be able to create a simple, working model
of your system. At least that is what I do, if for no other reason than all this
is new to me.
I apologize if my advice to simplify seems like a cop-out. In a sense it is, since
I am not working on your project, but just giving general advice.
Part 1: High Level View
--------------------
The first question I would ask is this: does your design support concurrency.
It seems clear that many people are much better at parsing a question than I
am, and seeing what the real problem is even if it is not stated with great
precision.
You say that every client has its own Data instance. So, my first question to
understand your design has to do with the following discussion:
If each client will have its own Data instance, and the read and write methods
of Data are synchronized, then then fails to be a concurrent server. Do you
agree?
Thus, it seems to me, that if each client has its own Data instance, to create
a concurrent server, you must store the file in a collection. Do you?
Now, if you take the other approach, which may or may not be allowed for
different projects, and the client never touches Data, but instead talks
to a middle-man (the server), only then is it possible for Data's methods
to be synchronized while at the same time creating a concurrent server.
In summary, and I hope people will correct me if I'm wrong, if the client
directly invokes the methods of Data, the design must look something
like this:
Client --- Data --- In-memory Collection representing file --- physical Random Access File
Otherwise, you don't have a concurrent server.
If the client does not directly access Data, then you can have:
Client --- Server --- Data --- physical Random Access File
or
Client --- Server --- Data --- In-memory Collection representing file --- physical Random Access File
What is your overall design? Before trying to debug your code, I would be curious
if your overall design meets the test of being a concurrent server.
Sorry if my question seems dumb, or I could not extract this information
from your previous comments.
Once I have an outline of your overall design, and it has been determined if
this overall design meets the standards of concurrency, then the next
step is to make sure each sub-section fulfills its obligations.
Again, in the face of all the types of data structures your previous post mentioned,
my question seems perhaps "like an idiot" is answering your question; but,
that is how I operate: I simplify, and begin first by making sure the over-all
design has some chance of meeting the requirements, which in this case
is that the server be concurrent (as much as possible).
Thanks,
Javini Javono
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Javini, thanks for your reply.
"If this is true, then it would strongly suggest that
multi-threading is occuring some where you did not anticipate, that your
position pointer is some how becoming invalid. "
extremely agree.
"If each client will have its own Data instance, and the read and write methods
of Data are synchronized, then then fails to be a concurrent server. Do you
agree? "
Agree, because I select multiple Data instance design, so the synchronized methods in Data class don't make any sense. In my new Data class, all methods is synchronized on lockedRecords, which is a WeakHashMap store the locked records map, it is static variable in Data class. As you said, my design is : Client --- Server --- Data --- physical Random Access File.
I post this thread only want to know why the test throws this exception, here is part of the code(only test, not my real class):

Thank you again.
[Andrew Monkhouse: I have removed the locking code - see comments below]
[ February 01, 2004: Message edited by: Andrew Monkhouse ]
Javini Javono
Ranch Hand

Joined: Dec 03, 2003
Posts: 286
Hi,

"If each client will have its own Data instance, and the read and write methods
of Data are synchronized, then then fails to be a concurrent server. Do you
agree? "
Agree, because I select multiple Data instance design, so the synchronized methods in Data class don't make any sense. In my new Data class, all methods is synchronized on lockedRecords, which is a WeakHashMap store the locked records map, it is static variable in Data class. As you said, my design is : Client --- Server --- Data --- physical Random Access File.
I post this thread only want to know why the test throws this exception, here is part of the code(only test, not my real class):

Hi,
Even though I'm responding to your message, I hope doing so will not stop others from
responding if they know more about this than I do.
Not having looked at your code to closely, since we are still at the stage
where I'm trying to understand the design, you have stated that your design is this:
Client --- Server --- Data --- physical Random Access File
To verify this, this means that your client talks to the server something like this:
myServer = RMI fetched remote server;
myJTable.showToUser(myServer.readAllRecords());
where the above is symbolic, psuedo-code which sort of looks like Java.
You are not referencing Data from the client directly, that is; but you
only have an object reference to the Server object which you have
built.
Now, if the above is true, you must only have one instance of Data
for the physical Random Access File. This is carried out simply by
the Server making sure it doesn't instantiate more than one Data.
If you really are instantiating more than one Data object, then even
if the methods are synchronized, you are still battering and "destroying"
your database random access file.
Once you only have one Data instance for the one database random access
file, perhaps things will start to work better.
Then, you need to consider how to modify your design so that your
server handles concurrent requests concurrently, if it does not already
do so.
Thanks,
Javini Javono
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Javini, thank you for your reply.
I use RMI support network mechanism, and between client and Data class, I use a Data wraper class witch implements one interface named RecordAccess.
I think that I am fortunate in that I have the URLyBird project, and no cookies are passed into the lock and unlock calls;

as you said, I have no cookies too, so I want to use Data class to identify the client, this is the only reason I use multiple Data instance. While I use multiple Data instance, but only one RandomAccessFile instance in my application and use DataHelper class to do read/write operation.
where the above is symbolic, psuedo-code which sort of looks like Java. You are not referencing Data from the client directly, that is; but you only have an object reference to the Server object which you have built.

First, pls see my network layer design:

RecordAccessFactory supports two methods: getLocal and getRemote. Every client use one of these two method to get a RecordAccess object. RecordAccessLocal and RecordAccessRemote extend RecordAccess interface, and they implemented object RecordAccessLocalImpl and RecordAccessRemoteImpl wrap the Data class and support some business methods, like book, search.
My ugly design is only this, I want to see your comment on it.
Now, if the above is true, you must only have one instance of Data for the physical Random Access File. This is carried out simply by the Server making sure it doesn't instantiate more than one Data.
If you really are instantiating more than one Data object, then even if the methods are synchronized, you are still battering and "destroying" your database random access file.

I afraid don't understand what you mean on the first paragraph enough and agree your second one. Now, I change the Data's methods from use this lock into use lockedRecords' lock, as said above. I don't ensure this is enough, need some test yet.
My statement and design is too ugly, thank you see it, pls write your comment on it and hepl me. Thanks again.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Leo,
Reading your code, I see two issues in relation with the problem you mention, and a few other problems as well.
Your EOFException issue:
-----------------------
1. It's clear that you have a synchronization problem. If I understand your design, you have:
- multiple Data instances (one per client)
- one RAF instance
- one WeakHashMap instance for locks
It means that all accesses to your RAF should be synchronized on its instance, which is not the case (but well for your WeakHashMap): For example, in isValidRecord(), you access your raf instance without any synchronization.
2. In your isValidRecord(), your test is incorrect: your "if ( pointer > raf.length() )" should have been written "if ( pointer > raf.length() -1 )".
Other issues:
------------
In lock():
*******
1. Are you sure that the notifyAll() call is needed?
2. Just before your while loop, you should perform a test like this one:

In unlock():
*********
Your unlock() method looks much more complex that it needs to be. What about this one?

About the use of WeakHashMap:
****************************
Do you take the "lack of notification" issue into account?
You could read this thread I posted in September about it.
Regards,
Phil.
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Philippe, thanks for your reply.
I'v read a lot of your comments in other threads and get a lot of benefits from it, thank you, you are one of my teachers here.
EOFException issue:
-----------------------

Pls forget all the code above, it's only a template to test the EOFException. The new code is below.

Very good !!! This is my strong hole. Thank you point it out.
But in other words, my test pointer number cann't bigger than raf.length - 1. As I said above, I use only the first 5 records, the max number of record is seek number 714, the db file's max byte is more than 5000 bytes, I don't know why throw the EOFException yet? (I tested, the modifed code throw the exception yet, I think this doesn't related width lock mechanism)
Other issues:
------------
In lock():
*******

Because others do it, before I understand this thread, I just do it.

From design, I agree you. But in my assignment(URLyBird 1.3.1), no requirement of this. I think I use WeakHashMap as the locked container and Data.this as the key of the item, it cann't be duplicated, so I may not take care of this. Only one thing can take place, when one Data instance(client) locked a record that number is 4, after a while, he locked the record 5, then in the locked container only store he locked this record, the record 4 is covered. What you think about it ? Pls write your mind.
In unlock():
*********

Sorry, I don't understand what you mean, could you detail a bit on it and the code below the statement ?
About the use of WeakHashMap:
****************************

I'm reading, thank you.
Thank you Javini and Philippe, pls pardon my long-winded words, I want to go to bed, see you tomorrow.
[ February 01, 2004: Message edited by: Leo Tien ]
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
This is my new ugly code.
[Andrew: deleted locking code - see comments below]
[ February 01, 2004: Message edited by: Andrew Monkhouse ]
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Leo,
I'v read a lot of your comments in other threads and get a lot of benefits from it, thank you, you are one of my teachers here.

Thank you! I start to get teased about my SCJD assignment never handed in... (see Bharat's comment in this thread. I *love* getting teased in general, but I appreciated your comment above as well.
Leo (about the notifyAll() in lock()):
Because others do it, before I understand this thread, I just do it.


Mmh... You'd better understand that thread before making a choice. A notifyAll() call cannot be justified by a "I did it just in case".
Now, reading Max's post dated October 03, 2003 01:04 PM in the same thread could help you making that choice.
Max's book is great, the best SCJD book in the world AFAIK, and I'm one of the best advocates of it, but as all best books in the world, it has a few mistakes in it (did you ever read a technical book with no errata BTW ? ), and the notifyAll() call in lock is one of them IMO. I remember having read the comment about that notifyAll() call (unfortunately I gave my book to a friend, and in such a thread I can measure how much I miss it). But I remember that the code comment simply doesn't justify that notifyAll() call.
And if you're still hesitating about it, just try to come up with a final decision by yourself. After all, that's what the SCJD assignment is made for.
From design, I agree you. But in my assignment(URLyBird 1.3.1), no requirement of this. I think I use WeakHashMap as the locked container and Data.this as the key of the item, it cann't be duplicated, so I may not take care of this. Only one thing can take place, when one Data instance(client) locked a record that number is 4, after a while, he locked the record 5, then in the locked container only store he locked this record, the record 4 is covered. What you think about it ? Pls write your mind.

I must disagree with you here. The requirement doesn't come from your instructions but from your own design. The latter (a WeakHashMap with a Data instance as the *key* (which is unique by definition)) makes the requirement. My own opinion is that implementing a locking design which doesn't allow more that *one* record per client at a time is too restrictive (in comparison with your one_lock_on_one_table_per_client scheme, my own locking scheme allows multiple locks to be granted to a given client on multiple tables). But if you do, the minimum is to make sure that your implementation ensures (and is consistent with) your own design decisions.
Sorry, I don't understand what you mean, could you detail a bit on it and the code below the statement ?

By design (your own BTW), you ensure that a given client cannot own more than one lock. What does it mean ? That when a client wants to unlock his record, you don't need any record reference. Or the client owns a lock, and - by definition - the record he can unlock is the one he owns the lock on, or he doesn't and there is nothing to do (except maybe throwing some SecurityException, depending on your instructions). Just be consistent!
I disagree with the base design decision, but once accepted, I *love* that 2-lines unlock method (and BTW, I'm pretty sure Mark would love it too ) :

This is my new ugly code.

I didn't read it yet (I was here replying to the previous post), and ... it's a high time I stop for today either. But before going and work tomorrow morning, I'll comment your new code above (if it's not removed in the meantime ).
Regards,
Phil.
[ February 01, 2004: Message edited by: Philippe Maquet ]
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11404
    
  81

Hi Leo,
Sorry to remove all your locking code, but we do not allow such large amounts of the assignment (locking is worth 20% of the assignment) to be posted here.
It is not fair to you (or the rest of us) if someone was to get certified without knowing how to write the code themselves, and it devalues the certification.
I think you now have the solution to your problem. If not, could I suggest that you write a simpler program that is not related to the SCJD which demonstrates your problem - you could then post that.
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Leo,
That's what I feared (your code being removed), and it's quite normal BTW - Andrew had no other choice as moderator of this forum. Now I may imagine that it must be a bit frustrating for you (we weren't so far away from a final solution ). So, feel free to repost the same code in a PM to me, and I'll do this time what I *never* do: replying to some technical question from a PM.
Regards,
Phil.
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Philippe, may be you'v received my private message, but the code cann't be send, it's too long. I send a mail to you --- p.maquet@skynet.be(subject: leo's ugly codes), mail address correct?
Mmh... You'd better understand that thread before making a choice. A notifyAll() call cannot be justified by a "I did it just in case".

After read the thread carefully, I understand and decide not to use it. But I have a question, if I use notifyAll() in lock() method could make some problem ??
But if you do, the minimum is to make sure that your implementation ensures (and is consistent with) your own design decisions.

Yes !!! I don't notice it before (I say one_lock_on_one_table_per_client scheme), thanks point it out. Ago, I do a great think on define key-value pair in WeakHashMap, at last, I select Data.this--recNo as it, whether this cause the one_lock_on_one_table_per_client scheme ?
....multiple tables...

I'v seen this word in other thread, but I think I don't support it, so I didn't read it. Did you implements it? How you do?

Perfect !!! How beautiful code !
Thanks Philippe.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Leo,
I got your mail, but I cannot read the attachment . Please resend it, but with a simple .java (or even .txt) file attached.
I won't be able to look at it tonight, but tomorrow night (West Europe time == JR_time+8).
After read the thread carefully, I understand and decide not to use it. But I have a question, if I use notifyAll() in lock() method could make some problem ??

I think "yes", but all people don't think so. I just entered in discussion with Max about it to clear things up, and I'll post the results here or in a new thread within the next couple of days.
...multiple tables...
I'v seen this word in other thread, but I think I don't support it, so I didn't read it. Did you implements it? How you do?

As far as I know, I'm the only guy on this forum who implemented a multiple-tables system by design (even if the application only uses one table). So I think you may forget it! To tell you in a few words, I use a Table class (a multiton) to which Data instances (one per client) delegate their job. And I support multiple locks per client which may span on multiple tables.
Perfect !!! How beautiful code !

Beautiful I don't know, but for sure the shortest possible unlock() method!
Best,
Phil.
[ February 02, 2004: Message edited by: Philippe Maquet ]
Leo Tien
Ranch Hand

Joined: Sep 10, 2002
Posts: 156
Hi Philippe:
I got your mail, but I cannot read the attachment . Please resend it, but with a simple .java (or even .txt) file attached.

Sorry, I send you again.
I think "yes", but all people don't think so. I just entered in discussion with Max about it to clear things up, and I'll post the results here or in a new thread within the next couple of days.

Waiting and Attention....
....at last, I select Data.this--recNo as it, whether this cause the one_lock_on_one_table_per_client scheme ?

You'v not answer this question yet .
Thanks a lot.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Leo,
....at last, I select Data.this--recNo as it, whether this cause the one_lock_on_one_table_per_client scheme ?
You'v not answer this question yet

Yes, because HashMap keys (Data instance) must be unique in the map.
Regards,
Phil.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why the EOFException always thrown ?????
 
Similar Threads
Reading a stream of bytes from a socket.
B&S: I have some question about EOFException
declare or handle
RandomAccessFile.length() is not thread save!
URLyBird 1.3.1 DB Access layer design, pls comment!