Grading process: Note: Sun says it takes between 6 - 8 weeks to grade your project. I had been enthusiastically checking my exam history on the cert manager in
their database for weeks and could not find a mention of my project grading. It only showed the SCJD exam I took on Jan 24, 2009 with a 'pending' comment. After 8 weeks (today) I decided to contact Who2Contact customer support and query my SCJD project grading process status. I had been going through old e-mails and found the original link where I uploaded the project on sun certmanager. When I logged in I discovered I was graded about 3 weeks after the exam on Feb 18, 2009. It seems to me there are two certification databases that are not synchronized. One is operated by Sun, the other (I am guessing here) by a third party (probably integral7 or durango or god knows who) and these two are not well synchronized. I recommend check both and save time. I then contacted the sun customer support since I did not receive the certification package yet - at least I passed!!!.
Resources: From the beginning I had contacted enthuware for project guidance. Enthuware sends you a sample project which encapsulates the general SCJD requirements and meets them. This is not a project that you can submit but it has very nice architecture and is very helpful in solving the network and alone mode issues and sheds light on many aspects of the requirements of SCJD in a meaningful and helpful way. However, there were two major issues with this project: For one, I did not like the implementation. A developer friend I asked for a second opinion mentioned, "the project has a nice architecture but very messy code". When I installed this project on MyEclipse IDE, I immediately noticed vast amount of compiler warnings regarding unchecked parameterization (Java 1.5 generics) and the general disorder of indentation. Second, the entire Swing GUI is built using GridBagConstraints which I found to be complex and very difficult to configure the GUI with. IMHO this layout manager should only be used by tools that generate the GUI - not by manual programming. Nevertheless, this was a great starting point.
However, for the UrlyBird 1.3.3 assignment the enthuware poject did not solve the major problem of identifying the client over RMI (e.g. the entire lock mechanism needs to know that a specific record is locked for a specific thread and only that thread can modify the locked record). The UrlyBird 1.3.3 Data Interface does not allow for passing a token or an identifier of the thread. The entire enthuware project assumes such a token is a viable solution, which was not the case for me.
I did some research and the answer came from the excellent book "SCJD Exam with J2SE 5, Second Edition" by Andrew Monkhouse from "Appress". The google preview is available and very helpful. This book addresses the exact problem I encountered in it's chapter 6: "Networking with RMI".
In addition, since I had never used RMI before, I went over the RMI specs just to get the hang of it. It turned out, for me, that using RMI as a network solution is far better than using sockets because a) It is easier - I did not need to implement my own 'request/response' style protocol of communication b) An early prototype of my UrlyBird project used a socket solution. I had a strange java.io.CorruptStreamException trying to read a string array from the socket input stream. I could not get around it. The problem disappeared when I migrated to Java 1.5 but resurfaced on Java 1.6. Since Java 1.5 is no longer a valid version for SCJD I had to use RMI.
Documentation: I took meticulous care to document my project. Documentation is 70 points worth whereas your data store and network server implementation are worth 40 points each. In fact, the only issue worth more is the locking mechanism with 80 points and general considerations (100 points), the later being a none atomic topic. I had set my IDE to warn me of any missing javadoc parameter in any method and class. All of my Java code was documented regardless of private or public methods. Even private fields got their documentation comment. Not only that, each package in my source directory, included a package.html top level document where I had explained why the package exist and what's in it. I attempted to display why the contents of the package is required and included well formatted (using the 'pre' tags and keeping proper code indentation) code usage examples regarding how to use the classes I include in my package. I especially documented utility classes which I used more than once in different modules in my application. Each of these package.html files included an additional information link to the instructions.html file, to the README text file I included in my delivery, and to the choices.txt document (for convenience of the examiner). I had spent about 50% of my overall project time to document!!! That's a lot, but, it was worth it. I got a full 70 points on documentation.
Design: This forum is full of good tips and architecture - I followed recommendations from the "SCJD Exam with J2SE 5, Second Edition" book and I can't really explain my architecture here in full details and keep this short enough to be posted. However, some highlights:
GUI: I used MVC architecture, meaning: MODEL: for the JTable model, as an example, I included my own implementation of AbstractTableModel which allowed me to easily translate String from my Database to displayable GUI objects and vise versa. VIEW: Usage of costume sub-classes of DefaultTableCellRenderer and AbstractCellEditor to render, for example, formatted dates or float values with currency signes, and to enable users to easily search for 'TRUE','FALSE' or 'ANY' boolean value. CONTROL: Controllers are action listeners that may choose to handle action events of interest, ignore them, or, 'post' the events higher up the controller hierarchy for handling by a parent controller. Handling of events is executed via the actionPerformed(ActionEvent) method. Controlling components implement the java.util.Observer interface, This, together, means that a controller can 'control' a component by 'updating' it's model, and that a hierarchy of action events handling, bottom to top flow is established. I also packaged each component according to it's designated role in this paradigm (e.g. com.ub.cli.model.MyTableModel, com.ub.cli.view.MyViewComponent, com.ub.cli.control.MyController).
Help System: I used an online user help system. I implemented a single HTML browser class (with back, forward and home buttons) which allows users to navigate HTML content starting with a TOC page, and I included, in the delivery, a number of well organized user help files (I took care to make them very realistic and helpful using anchors and tables of content) and also linked them in my Javadoc as additional information links. This browser opens by clicking a 'help' button in the GUI and automatically navigates to the content matching the user last action.
Generics: I used generics when ever I could to a) Reuse code whenever possible b) Assist in type safety and avoid ugly and unnecessary casting c) Display my ability (which is not less important in such a project). As such, for example, I implemented a generic proxy utility class designed to ease the implementation of adapters and anonymous class (I hate anonymous classes) usage in Swing related code. It is, however, much more powerful than this. It essentially allows for reflective invocation of any method of any interfaced class, thus becoming an effective low memory footprint proxy. You can start with David Geary's article about proxies to get the hang of it, then you can parametrize it.
Enums: I used enum constructs instead of constants. In general I dislike constants in abstract classes and refuse to use constants in interfaces (which apparently was very common once - check the swing source code...). Using Enums is a very elegant way of making constants available to your classes (and much more) and it displays your understanding of new features in Java (since 1.5).
i18n support: I refuse to use hard coded messages. All of my GUI messages originated in a locale based resource bundle (I included a properties file in addition to the suncertify.properties). I'm not sure this contributed to my score. The only topic I messed up (31/40 points) is GUI, so I have no idea what effect this had on my score. However, hard coding messages in the application does not seem like a good idea to me and I would do this again if I had to.
logging: I used the built in Java support for logging (java.util.logging.Logger) - this beats using System.out.print any time and I think sun examiners like it better. It also displays good programming concepts and understanding of new (relatively) java features. The most important thing to remember about logging - is maintain your own consistent logging policy. Do not verbose meaningless output just because you can. Keep it helpful, use the proper logging level for each log entry, and remember who you log for. In this SCJD project - you log for the sun examiner. They probably want to see when your client and server start, how you do the networking and how you handle concurrency (at a global level - especially when your lock detects a locked record). If you log too much, you may irritate your audience but if you do not log crucial exceptions (say, for example a bad magic cookie code input), you may miss on the global concept of logging.
locking: From the beginning I wanted to use the new java.util.concurrent.locks package. In a hunch I felt this could save me a lot of work and gain me points for displaying ability and understanding of new features. Since I never used this package before - it took me a while to get the hang of it. The Sun Javadoc for this package is very well organized and there are many examples of the java.util.concurrent.locks.Lock and java.util.concurrent.locks.ReentrantLock usage. My locking mechanism is heavily based on these features and, at the end, it was worth learning and I feel I got a lesson for life (well, for a career any way). I got full points for my locking implementation.
An important issue to remember about locking: In theory a client could lock a resource (record), then die out, leaving the resource forever locked. My lock, for example, employs a java.util.Timer service scheduled as a java.util.TimerTask to run at pre-determined intervals and clear the ownership mapping of 'over due' entries. For this to work, I needed to keep a timestamp of the locking action. Needless to say, my lock does not simply caches a record identifier, but rather, a wrapper data container class able to contain this additional data.
Delivery comment: This did not happen to me, but I had seen many issues regarding this. Keep your delivery under 1MB and avoid uploading issues. In my case, the excessive documentation inflated the overall size to more than this limit. I used a free version of HTML shrinker to reduce the size of all my Javadoc. If you do this, take care not to mess up any nice sample code usage between 'pre' tags (the shrinker will mess it up). Also, if you use top level package.html files (these go in the source code packages) make sure not to package them in the runme.jar archive. It is very easy to make this mistake and double package them.
Finally - I could go on and on but there are other excellent tips in this forum already encapsulating the essence of it. It is not true that Sun does not let you know why you loose points. If you go to test history and then to details, on the sun cert manager database, you will see the comments: This is mine (of which I'm very proud):
Comment: This report shows the total number of points awarded for each section. The maximum number of points is 400, to pass you need a minimum score of 320. Section Summary: Section Max Actual Points Points General Con: 100 90 Documentation: 70 70 OOD: 30 30 GUI: 40 31 Locking: 80 80 Data Store: 40 40 Network Server: 40 40 Total: 400 381
The SCJD project was a very unique and satisfactory experience for me of which I had learned a lot from. I wish all new candidates good luck.
Tom Silverman: SCJP5, SCJD6, SCWCD5, SCBCD5, IBM-142, ScrumMaster