This week's book giveaway is in the Artificial Intelligence and Machine Learning forum.
We're giving away four copies of Transfer Learning for Natural Language Processing (MEAP) and have Paul Azunre on-line!
See this thread for details.
Win a copy of Transfer Learning for Natural Language Processing (MEAP) this week in the Artificial Intelligence and Machine Learning forum!

Timothy Johnson

+ Follow
since Sep 14, 2003
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by Timothy Johnson

Thanks fellas.
For the sake of this project and the exam do you think that I should further explore going the Activatable (vs. UnicastRemoteObject) route? I'm perfectly content with the UnicaseRemoteObject functionality but I'm terrified that I'm going to get an exam question requiring me to go into detail regarding why I chose UnicastRemoteObject over Activatable. I can give high level info but not having done anything with Activatable, I'd kinda be screwed in that situation.

Hey Mark,
Thanks for the input, much appreciated. In my implementation, I have a business layer in between the RMI server and the data layer. So, locking is invisible to the client. Is the "lock expiration" issue (in cases where a client dies) the reason for considering the use of a WeakHashMap or the Unreferenced interface? Other than that scenario, I can't think of a reason why I'd care to do anything if a client crashes or all references to my RMI server are gone?
Thanks again,
Not to be a complete "reposting the same topic for the 18th time" goober, but I'd really like to verify a few things about my RMI implementation.
Below, I've pasted a piece of my requirements regarding RMI...
Restrictions on RMI
To avoid unnecessary complexity in the marking environment certain restrictions are placed on solutions that use RMI. Specifically:

You must not require the use of an HTTP server.
You must not require the installation of a security manager.
You must provide all classes pre-installed so that no dynamic class downloading occurs.
You must use RMI over JRMP (do not use IIOP)
Being an RMI newbie, I zipped through the jGuru tutorial on the Sun site and I also have Max Habibi's book, which contains some very useful RMI information. That said, my RMI server startup code looks like:
DataRMIServer drmis = new DataRMIServer();
Naming.rebind(RMI_SERVER_NAME, drmis);

And my client code looks like:
server_ = (ApplicationFunctionalityIF)

Now for the questions/verifications:
- I'm not doing anything with an HTTP server because I'm not setting any of the relevant JVM parms (ex. java.rmi.server.codebase) and my network clients will have all of the rmic generated code (only the stub and interface extending Remote are required I believe).
- Even though I think a SecurityManager is required for dynamic class loading, I haven't written any code referring to a SecurityManager. And I haven't tweaked any settings that should affect one either, so I must not be "requiring the installation" of one, eh?
- Since I don't specify the -iiop option when I use the rmic tool, I must be using JRMP.
- My RMIServer extends UnicastRemoteObject and implements DataRMIServerIF (which extends the Remote and ApplicationFunctionalityIF interfaces) and since I have gone with UnicastRemoteObject, there is no need to worry about clients dealing with "disappearing objects" (jGuru tutorial mentioned this in regards to Distributed Garbage Collection), right?
- Since I have gone with UnicastRemoteObject (I'm assuming this implementation runs the whole time the server is up), there is no need to consider using the Unreferenced interface, right?
- I don't need to handle starting the RMI registry because my server code does this programmatically.

Thanks a lot.
Hey Gang,
I'm currently writing the GUI piece and my application launcher class. Depending on the mode passed at application launch time, I'm going to need to get either the db file location or the ip/hostname for my RMI server.
Question is... I could use something like JOptionPane or I could write my own JFrame component. I'd rather leverage a Swing component but I'm yet to stumble onto one that will allow me to pass a JFileChooser in so that the user can search for the db file location. I've got no problem with the user using a JTextField for the server location, but I'd like to do better for the db file location.
Or I guess I could assume that any user running the app in standalone mode or starting the server is really a "power user" and capable of keying in a valid file path. This being the case, I could just use the static input methods on JOptionPane and be done with it, but I wanted to get some feedback first.
Thanks Mark, that's what I was assuming but I just wanted to make sure. Have you finished and submitted the assignment yet?

Alright, I think that I'm going a little overboard here but I wanted to check and make sure that I am . My UI requirements state:
"It must be composed exclusively with components from the Java Foundation Classes (Swing components)."
The thing that is a little confusing here is the piece referring to "Swing components". As a lot of the Swing components are very tightly integrated with AWT components, I assume that using AWT components in conjunction with Swing components is okay, right?
Thanks for your input. Yeah, my choices.txt is growing by leaps and bounds but I'm learning a lot in the process.

I'm still a little stumped on the encoding though... I saw one individual claim to have gotten a 91% using the default encoding, Philippe M. is a proponent of "US-ASCII", and Andrew seems to imply that "UTF-8" is the way to fly. Hmmmm....

As far as the delete flag is concerned... I could use RandomAccessFile.writeShort(Character.getNumericValue('\u8000')) but what's the real advantage over using RandomAccessFile.writeChars(new String("\u8000","UTF-8")) or even RandomAccessFile.writeChar(Character.getNumericValue('\u8000'))?

Thanks fellas,
I've read most of the posts here relating to reading and writing bytes to/from the data file. This is what I've come up with and I want to make sure that I'm not doing anything blatantly idiotic. First, I'll post the data file format and then my assumptions.
**** Data File Format Start ****
Start of file
4 byte numeric, magic cookie value identifies this as a data file
4 byte numeric, offset to start of record zero
2 byte numeric, number of fields in each record
Schema description section.
Repeated for each field in a record:
2 byte numeric, length in bytes of field name
n bytes (defined by previous entry), field name
2 byte numeric, field length in bytes
end of repeating block
Data section. (offset into file equal to "offset to start of record zero" value)
Repeat to end of file:
2 byte flag. 00 implies valid record, 0x8000 implies deleted record
Record containing fields in order specified in schema section, no separators between fields, each field fixed length at maximum specified in schema information
End of file
All numeric values are stored in the header information use the formats of the DataInputStream and DataOutputStream classes. All text values, and all fields (which are text only), contain only 8 bit characters, null terminated if less than the maximum length for the field. The character encoding is 8 bit US ASCII.
**** Data File Format End ****
- for the numeric values, I should be using RandomAccessFile#readInt and #readShort
- the valid record flag should equal a string of "\u0000\u0000" and the delete field flag should equal a string of "\u8000"
- I should be using RandomAccessFile#readFully instead of #read when loading my byte[] objects
- When I convert the bytes I read into a String, I should do a new String(bytes,"US-ASCII") and a strObj.getBytes("US-ASCII") on writes
- "US-ASCII" is really 7 bit and I need 8 bit. Am I missing something here or do I need another encoding?
- I'm not sure of the best way to handle my delete flag writes, RandomAccessFile#writeChars("\u8000")???
- Even though it's been highly debated, I think I'll keep from trimming the spaces following many of the values in the data file, when I read them into memory.
- When reading in the field values, I'll have to loop through the chars and find the first null, everything before that will be my field value.

Thanks a lot gang.
Hey Fellas,
I've gone through and implemented all of the methods but #createRecord and the reason that I stopped is because the duplicate key exception that this method could throw makes no sense to me. As far as I'm concerned, the client is going to be passing in an array with 6 elements (name, location, specialties, rate, size, and owner), the fields within the db file, and that's it. The key generation is a function of the db system??? I'm not sure what type of a scenario would cause me to throw this exception and I wanted to see if you guys have any thoughts.
Thanks again,
Hey Fellas,
Something occurred to me though... since the #findByCriteria method returns a long[], this implies that there shouldn't be more than <max value for int> records anyway. So that leaves me thinking that 'recNo' is really the byte offset into the file for a record.
Even with this assumption, I'm still thinking that it might be better to just read from disk on searches (as opposed to pulling everything into memory) because of possible memory utilization issues.
Thanks for your feedback, any additional thoughts?
Hey All,
I had hoped to read all of the records into memory and then only access disk on create/delete/update calls. However, since recNo is a long, I'm kind of stuck because I can't use a Collection and I can't use an array (since I could have more than <the max int value> number of records).
Does anyone have any ideas? Or am I just stuck reading from disk on every "find call"? I'm posting the interface below.
package suncertify.db;
public interface DBAccess
// Reads a record from the file. Returns an array where each
// element is a record value.
public String [] readRecord(long recNo)
throws RecordNotFoundException;
// Modifies the fields of a record. The new value for field n
// appears in data[n]. Throws SecurityException
// if the record is locked with a cookie other than lockCookie.
public void updateRecord(long recNo, String[] data, long lockCookie)
throws RecordNotFoundException, SecurityException;
// Deletes a record, making the record number and associated disk
// storage available for reuse.
// Throws SecurityException if the record is locked with a cookie
// other than lockCookie.
public void deleteRecord(long recNo, long lockCookie)
throws RecordNotFoundException, SecurityException;
// Returns an array of record numbers that match the specified
// criteria. Field n in the database file is described by
// criteria[n]. A null value in criteria[n] matches any field
// value. A non-null value in criteria[n] matches any field
// value that begins with criteria[n]. (For example, "Fred"
// matches "Fred" or "Freddy".)
public long[] findByCriteria(String[] criteria);
// Creates a new record in the database (possibly reusing a
// deleted entry). Inserts the given data, and returns the record
// number of the new record.
public long createRecord(String [] data)
throws DuplicateKeyException;
// Locks a record so that it can only be updated or deleted by this client.
// Returned value is a cookie that must be used when the record is unlocked,
// updated, or deleted. If the specified record is already locked by a different
// client, the current thread gives up the CPU and consumes no CPU cycles until
// the record is unlocked.
public long lockRecord(long recNo)
throws RecordNotFoundException;
// Releases the lock on a record. Cookie must be the cookie
// returned when the record was locked; otherwise throws SecurityException.
public void unlock(long recNo, long cookie)
throws SecurityException;