aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Passed 149. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Passed 149." Watch "Passed 149." New topic
Author

Passed 149.

Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
Well, this was fast. I took my written exam on Dec 2, twelve days later I had my grade.
The score breakdown is this:
General considerations': 55 out of 58
Doc: 20 of 20
Server: 53 of 53
GUI : 21 of 24.
I discussed all my design choices in this forum in great deatils, so if you would like to look them up just search by my name.
The 3 points I lost on general considerations I believe are due to the fact that I relied on RMI server to handle all client's requests with the same thread. This assumption is wrong according to RMI spec, even though it worked reliably for me.
The 3 point I lost on GUI was because it was way too complex. I followed Sun Look and Feel Guidelines, which defines very strict standards for component layout and component behaivior standards. That required using Box layouts and its struts, glues, etc. So the code came out way too complex, even though I thought it was proffesionally looking and easy to use.
I will hang around for a while and will be happy to answer design/concept questions.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

WOO HOO! Congrats Gen. I think you did very well, and congratulate you on your high score. Wow Dec 2nd. I took mine on Nov 25th, and still haven't gotten any results.
What are you going to do next?
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
I am going skiing next, I'll be in Quebec the last week of the year.
Then I am off to the Caribbeans getting my scuba diver certification.
Then I am thinking either J2EE architect or Weblogic certification.
Come spring I want to go for pilot's license.
Just wanted to share my plans.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Wow, how do you find the time?
Have fun Skiing, and good luck on the Scuba Cert, even though you'll pass no prob. My brother-in-law is a Scuba Master and teaches at Sport Chalet. "They'll Take you to the limit"
Later
Mark
Jason Voegele
Greenhorn

Joined: Oct 12, 2001
Posts: 9
Congratulations, Gennady! That's an excellent score.
You are the first person I've seen that got a perfect score on the server piece. Would you care to summarize the design of your server?
Jason Voegele
------------------
Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
Jason,
my server is simplicity itself.
1. Parse the command line, if not all info present display Usage or use defaults.
2. Start the RMI registry in the code -- dont require the user start it as a separate process.
3. Bind itself to the registry with Remote interface that exposes only one method:
public RMIConnection getConnection() throws RemoteException, where RMIConnection reuses FileConnection by extension (used in local mode). FileConnection implements Connection interface, which defines all public methods of Data.
4. When my server initializes it creates an instance of RMIConnection correctly initialized with Data settings. When a client first connects to the server it clones this RMIConnection and returns a reference of the clone to the remote client.
So every client has its own server side object, similar to HTTPSession in servlets.
5. My server objects are not synchronized in any way, all synchronizations are handled by database.
6. Note: all my remote methods throw IOExceptions , not RemoteExceptions. I thought it was important to substitute rmi-sub-system exception with more generic IOException since your failures may be related to Database failures as well as RMI failures. This was easily done since IOException is a supercalss of RemoteEception. I have tried to make this point before in this forum, but no one seemed to relate to this.
Marlon Bravo
Ranch Hand

Joined: Dec 06, 2001
Posts: 40
Congrats Gennady. Great score and good luck to your future goals.
Eric Li
Greenhorn

Joined: Nov 06, 2001
Posts: 7
Congradulations! Gennady! This is a great score!
I have 2 questions:
4. When my server initializes it creates an instance of RMIConnection correctly initialized with Data settings. When a client first connects to the server it clones this RMIConnection and returns a reference of the clone to the remote client.
So every client has its own server side object, similar to HTTPSession in servlets.
--------------------------------------------------------
Q1: If each client has its own RMIConnection, then there is no need to use clientID for DGC since each RMIConnection will be unreferenced automatically when the client disconnects. It's also unnecessary to use clientID to maitain the locks for each RMIConnection in a lock manager. Lock manager is not needed in this case because each RMIConnection knows what locks it has and thus will not unlock the record it doesn't have a lock on. This is my implementation. What about your implementation around this lock/unlock and clientID and DGC.
Q2: What's your choice of modifying vs. Extending the Data class and why?
Thanks! Your help will be greatly appreciated!
Eric
christy smile
Ranch Hand

Joined: Oct 15, 2001
Posts: 101
Congratulations, Gennady!
Would you please tell me how to start the RmiRegistry form the application itself? I am trying to do the same thing, just have not figured it out yet.
Thank you!!!
Christy
Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
Christy,
here's how to start rmi registry in your code:
<PRE>
/* This method starts up RMI registry on specified port */
protected static void startRegistry(String portStr) {
int port;
try {
port = Integer.parseInt(portStr);
} catch (NumberFormatException nfe) {
port = Integer.parseInt(DEFAULT_PORT);
}
try {
LocateRegistry.createRegistry(port);
} catch (RemoteException re) {
System.out.println("Could not create RMI registry. Reason : " + re);
System.exit(1);
}
}
</PRE>
If you don't feel comfy with RMI read Sun's RMI Tutorial, clear , simple, right to the point, doesn't go deep into details, enough to complete this.
Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
Eric,
you must strictly define responsibility of components:
1. According to FBN spec, the client must implement all public methods of Data, including lock and unlock. This implies that it is client's responsibility to initialte locking and unlocking.
2. According to FBN spec, Data (or subclass) must allow clients unlock only those records that they locked. This means that tracking locks' owners is Data's responsibility.
3. In my design, Connection objects just relay clients requests to the database. Any other logic, including making sure you unlock only your records, are beyond of Connection's scope of responsibility.
Now, that said, I use ReadWriteLock design pattern to implement locking. No explicit client ids needed. Data (or subclass) maintains a Map of Lock objects, every Lock knows who locked it.
I used the thread forked by RMI server as unique identifier of the client. While it worked perfectly, this is unreliable according to RMI spec (doh!), i think they took off points for that. You can use client's RMIConnection reference to uniquely identify clients for locking.
Look up ReadWriteLock pattern and look up this forum for more details, we have extensively discussed this.
Extension vs. modifying.
My approach always is modify only when absolutely necessary, extend otherwise. Modification was necessary tp replace deprecated API because they will become absolete in the future version of java and the whole application will fail to compile and run.
Benefits of of extension are too great to ignore, i can't imagine why would anyone modify self-contained modules thereby ignoring ALL 3 (!!!) main concepts of OOP.
1. Extension supports Natural modeling. in my design Data is responsible for low level IO, SearchableDate for search algorithm(s), SafeSearchableData for locking. How easy is it to separately maintain each module? If you use source control each developer can keep working on each module independently of others.
2. Specialized behavior & polimorphism. You don;t need locking in local mode. So your ConnectionFactory can supply Data or SafeData based on selected mode. Since you polymorphically using these Connections your client has no idea whether or not locking is actually performed.
3. Better readability, simplicity, code sharing, blah blah.
The disadvantage is byte size slightly increases as does execution speed, but that all is marginal , could be dismissed.
Plenty of information about this on the net.

Hope this helps.
christy smile
Ranch Hand

Joined: Oct 15, 2001
Posts: 101
Hi, Gennady,
Thank you for your reply. That's how I had it, but I am getting the following exception if I use anything beside the default port number "1099", have you ran into this problem? Thank you!
Couldn't contact rmiregistry
RemoteException = Connection refused to host: 32.100.208.14; nested exception is
:
java.net.ConnectException: Connection refused: connect
java.rmi.ConnectException: Connection refused to host: 32.100.208.14; nested exc
eption is:
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown S
ource)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Unknown Source)
at suncertify.db.Data.<init>(Data.java:101)
at suncertify.server.DataServer.createConnection(DataServer.java:237)
at suncertify.server.DataServer.access$400(DataServer.java:13)
at suncertify.server.DataServer$2.actionPerformed(DataServer.java:78)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Unknow
n Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
ce)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
reena kadam
Greenhorn

Joined: Nov 16, 2001
Posts: 16
Hi Gennady Shapiro,
Congratulation,
great score in server & documantation!
Can you pl. clarify my one doubt ?
Although we are not using lock for local mode, Do we have to implement full code for lock and unlock in Data class also or only difination in Data class and complete implementation in RemoteData (network class) ?
Gennady Shapiro
Ranch Hand

Joined: Sep 25, 2001
Posts: 196
reena,
number 1, it's a matter of your choice.
number 2, lock() and unlock() are already implemented by Data, they are empty but not abstract.
As I said above, one of the advantages of extending is specialized behavior. Meaning you should delegate locking logic to RemoteData and let Data use empty lock(),unlock() for local mode.
But...you might say I dont wanna keep track of multple files , I want one Data class plain and simple and I dont care if my local mode uses locking...I am sure they'll accept that too...as long as locking is done correctly.
It's up to you really.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Passed 149.