Linux Journal has an excellent article entitled How to Build a Home Terabyte Backup System Using Linux. This is definitely one that I will be checking out over the Christmas break. One thing I like about this article is that it uses rsync for the backup part instead of some of the more complicated back apps or scripts that are available.
As I stated in my last post, I have just finished up a project for school that was done in Java/JSP. For the database, we decided to go with Derby. Because Hibernate does not support Derby and because I thought it would be faster to do with straight JDBC, I decided to fore go Hibernate and create my own database abstraction layer. After all, how hard could it be?
Rod Johnson is right, definitely use some kind of OR mapping tool and never write your own. This I have learned the hard way. After trying to write my own I now know how hard it can be. And this was for a simple application with only a few tables. I can not image how or why anyone would want to do this for a larger application.
There are several things that I found to be difficult in writing my own database layer:
- Resource Management — Dealing with all the different try/catch/finally/try/catch blocks that you need for JDBC is a pain in the neck. And trying to abstract that so that it doesn’t infect the rest of your code is even harder.
- Managing the object graph — Every time I tried to find one object from the database, I ended up having to find several others. In the end, I just loaded the entire object graph—every object—and put them into a cache for easy retrieval. This was better than having to deal with recursive calls to get the next object. This was in part, though, because the app was dealing with trees and linked lists.
- Exceptions — Trying to abstract SQLExceptions was a pain. What I did was to wrap them in another exception and throw that instead. However, this lead to a ton of my exceptions having to get caught in all layers of the code. However, this problem is probably attributed to my lack of experience then to a true problem with JDBC.
My solution to this mess is to either try out some experimental support in Hibernate for Derby or to find an embedded database that is supported by Hibernate. This is the last time I try to write my own database abstraction layer though.
I can’t believe it. After two months and far too many all nighters (or near all nighters) my software engineering project is finally finished. We handed in the final documentation last friday after staying up all night to finish it.
The application that we created is called project:TeamDocs and is a Document Management System designed for small to medium sized businesses. In release terms, I guess this would be the 0.1.1 release. Which means that there are still a lot of bugs and even more functionality that is still missing. However, the main core functionality is all there and should work. What is even better is that it is a stand along install–Tomcat, the JRE, the database and the app are all included in a single zip file that is launched via a single executable. I think for me this is the coolest part of the entire program.
If you want, download the app and give it a try–it should run, but there will be bugs and it may be unstable. If you do download it, drop me a line and let me know what you think of it.
The goal is to turn this into a full fledge open source project. I have even registered it over at javaforge.com (just look for project:TeamDocs).
Zarar Siddiqi has an article on why some Log4j pattern options are more expensive than others and tend to slow a system down. A pattern option is the character ofter the ‘%’ sign in the following line:
log4j.appender.stdout.layout.ConversionPattern=
%d{ABSOLUTE} %5p [%c{1}] %m%n
Some options like %l or %L output the line number or the method name in your log file. These can be really nice to have when you are debugging code, but they come with a price.
However, according to the article, you should be very careful using these options. The reason is that:
What Log4J ends up doing is that for each debug(..) call, it creates an instance of Throwable which takes a snapshot of the runtime stack. It then proceeds to parse the stack to yield the current line of code being executed along with class and method information.
…constructing stack traces is a fairly expensive operation. When an Exception is created, the JVM needs to literally pause the processing and so it can get a good glimpse of the entire runtime stack – this includes classes, methods, line numbers etc – starting from Thread.run() all the way till the creation of Throwable.
However, in the logging scenario, the culprit is the call to the Throwable.fillInStackTrace() method in the Throwable constructor which gets invoked on each debug(..), info(..) and other logging calls. This is the only way to retrieve the logging information requested via the PatternLayout class.
I will definitely be more careful about what I put in the ConversionPattern from now on.
This is just a quick note to say that NetBeans 5.0 Beta 2 has been released. I have not tried it yet as I only just installed it so I will post an update once I have given it a spin. I was hoping that this would be the release candidate. Since this is a second beta, it means that the release date has been pushed back to sometime in January 2006. However, if the first beta was any indication, this is the version of NetBeans worth waiting for.
Javalobby.org has a discussion about the new Beta release.
I recently bought a new notebook (more about that later) and decided I needed a new mouse for it. The touchpad is fine for short time periods, but you really need a mouse if you are going to be using a notebook for any length of time. So instead of buying a mouse for the notebook, I decided to buy one for my desktop computer and demote the desktop mouse.
My desktop mouse is a Logitech MX500 and it is probably the best mouse I have ever had. The mouse that I decided to replace it with was the MX1000. Although it is now a slightly older mouse (at least in computer years), it is still suppose to be one of Logitech’s top mice.
It is being returned tomorrow.
Why? For starters, the mouse doesn’t work. Yes, it moves the little mouse cursor on the screen around just fine, but none of the buttons work with the programs that I use the most. To get the forward and back button to work in Firefox, you have to reassign the buttons and the up/down cruise buttons only work if I have Firefox on my primary browser. In addition, the middle mouse button–the scroll wheel one– was really hard to push with no audible or tactile feedback to tell you that it had been pressed. In short, I hate it.
Apparently though, all of Logitech’s new mice that use their Setpoint software are like this.
The end result was that I plugged my trusty MX500 back in and it just works. I did not even have to reinstall the drivers to get the extra buttons to work. Now I am looking for a second MX500 for my new notebook.
One project that I am working for school is a J2EE/Tomcat based document versioning system. As such, it contains objects for directories and documents. The problem that I am having is that these object are really shared objects in that they belong to everyone. As soon as a directory is created, it needs to be available to everyone. If someone then renames that directory, that change needs to be made available to everyone.
The solution that I have found so far is to put the entire directory tree into the application scope and simply give each user a reference to the directory they are using in their session scope. The problem is that as the directory tree grows, I am not sure if this will negatively impact Tomcat. How many objects can Tomcat store in the application scope?
My other solution is to put the directory tree in a cache of some sort and then create references from there.
Problem is that I don’t know which solution is better and I don’t have time to test both. I don’t really like the idea of storing all the object in memory, but I may not have any choice. If anyone has any ideas, please share them and I will update this little problem as I try out my solutions.