Monday, December 11, 2006
Zoom23 Launched!
The basic idea is very simple: "Reinvent online shopping".
These days you can buy almost anything online, if not everything. But the online shopping experience is far from shopping in brick and mortar stores. This is especially true if all you want is just to browse products, hoping that something will catch your eye. It is no fun to be clicking through pages of products and being flooded with lots of text that you don't really care for, when all you want is to have a look. Zoom23 displays all items in a slide show format, which is a pretty exceptional approach to displaying products online.
The second new experience that Zoom23 brings are social networking features that enhances the shopping experience. No longer will you be alone when shopping online. Zoom23 will enable you to share your favorite items and give recommendations to other through voting on items and sharing personal slide shows.
Do you often shop online at Amazon, Ebay or Yahoo? Then you can enjoy all the benefits of these stores while having unified access to all the products displayed in a unique way. This is because all of the products on Zoom23 come from these three popular online stores, with more stores to come in the future.
There is still a lot of work to be done especially in adding more social networking features, higher data quality and tighter integration with the original online store, but already now you can go to www.zoom23.com and easily shop for Christmas presents for your family and friends.
I'll come back to this project in the future and will write a little about all the Java, Ruby on Rails, PHP and Ajax that we used to put the site together.
Sunday, December 10, 2006
I'm back baby!
It feels great to be back. I don't have an experience of working for too many companies, but there is something special about being as Sun that gives me the warm fuzzy feeling that is sometimes hard to find elsewhere :-).
My first assignment is working on JSPWiki which seems to be popular choice when it comes to a wiki software at Sun. I'll post more stuff on this in the future.
Sunday, November 26, 2006
A Basket of Rotten Apples
I got the white box, paid and happily went home. When I unpacked the notebook, I put in the installation disk and was about to restart the computer to run custom installation when I heard that the DVD in the drive was getting scratched. Ironically I had the same and many others problems with my MacBook Pro. So I re-packed the notebook and the next day went back to the Apple Store.
When I arrived there, I grabbed a sales guy and told him about my problem. He asked me to demonstrate it to him, which I did. He had to admit that this was not a feature and took the notebook in the back office and came back with a new MacBook. After that, he went to the register, did some voodoo with the receipts and gave me the new box and a new receipt. I unwrapped the notebook in the store and checked if this one was OK. My test CD was unscratched after the test so I happily went home again.
When I arrived home I was going to do the custom installation again. After a couple of seconds of working with the notebook while having my palms resting on it, I noticed that this notebook was vibrating. The whole case was shaking as if the DVD was spinning at the maximum speed and the hard drive was doing some really heavy writing and reading at the same time. The thing was that at the time when this vibration was happening there was no disk in the superdrive and the hard drive was idle as well. With disgust I ceased all the activities with the notebook, put it into the box, and waited until I had the next opportunity to go to Apple Store again.
Couple days later I finally had time to go to the Apple Store. When I arrived I grabbed a sales guy again and told him my story. This guy told me that he has no authorization to do anything about this and that I had to see a Mac Genius with my problem. I guess that he saw that I was not very happy with his answer, so he took me to Mac Genius and asked him to look at my notebook immediately.
I explained the problem to this Genius, who took the notebook to the back office. In a few minutes he came out and told me that he needs to compare the vibrations from this notebook to the notebooks they have on display. For a second I thought that if all the notebooks are doing this then I'd get dismissed, but fortunately all the notebooks on display were making no vibrations at all.
After this the Genius sent me to the sales guy and authorized the replacement. I got the replacement accompanied with the receipt voodoo. The sales guy gave me the notebook and told me to enjoy it because that was my last replacement. I was little surprised to hear that and told him that I want to test the notebook before I go home.
I was pretty surprised to see that this one was doing the same thing!!! I showed it to the sales guy and he was pretty shocked as well. Another sales guy came to us and told us that it is normal behavior after first boot because "The computer is thinking". Duh, that was a bit of an offensive explanation for me and I dismissed the guy.
After this, the sales guy brought yet another box (my 4th MacBook!) and opened it himself. It was not that surprising to me that this one was vibrating as well. The sales guy almost collapsed when he realized that the whole batch of MacBooks that they have in stock might be suffering from the same problem.
After few phone calls to other Apple Stores in the area and talking to the store manager the sales guy opened yet another box and with huge relief called me and told me that "Hey Igor, we have a notebook for you!". I touched the notebook and it was fine, no vibrations at all!
The sales guy did his receipt voodoo for the last time and then I went home with a present for my sister. I still can't believe that I had to go through 5 (five!!) MacBooks to find the one that was working.
If Apple wants to increase the market share so be it, but I hope that it is not going to happen by becoming more like other notebook maker who's name rhymes with Hell! If anyone sees similar issues he should immediately go to the Apple Store and return / exchange the product he bought, for his own sake (don't waste time with repairs) and for Apple's sake as well; they must realize that Apple customers are not going to tolerate flaky assembly!
Sunday, November 12, 2006
MacBook Pro Core Duo Versus Core 2 Duo Temperature Comparison
I used Core Temp Duo to retrieve the temperature from CPU thermal sensor. It's a really cool small app btw.
These are the results of running
$ yes > /dev/null& $ yes > /dev/null&for about 30minutes on MBP Core 2 Duo (C2D) 2.33GHz:
11/13/2006 00:12 : 23:09 - 10.1% - 2.33GHz - 45C 11/13/2006 00:13 : 23:10 - 100% - 2.33GHz - 70C 11/13/2006 00:13 : 23:10 - 100% - 2.33GHz - 71C 11/13/2006 00:13 : 23:11 - 100% - 2.33GHz - 72C 11/13/2006 00:14 : 23:11 - 100% - 2.33GHz - 75C 11/13/2006 00:14 : 23:11 - 100% - 2.33GHz - 78C 11/13/2006 00:17 : 23:14 - 100% - 2.33GHz - 73C 11/13/2006 00:17 : 23:14 - 100% - 2.33GHz - 72C 11/13/2006 00:18 : 23:16 - 100% - 2.33GHz - 72C 11/13/2006 00:20 : 23:17 - 100% - 2.33GHz - 74C 11/13/2006 00:22 : 23:20 - 100% - 2.33GHz - 72C 11/13/2006 00:23 : 23:21 - 100% - 2.33GHz - 71C 11/13/2006 00:25 : 23:22 - 100% - 2.33GHz - 70C 11/13/2006 00:27 : 23:24 - 100% - 2.33GHz - 69C 11/13/2006 00:27 : 23:25 - 100% - 2.33GHz - 68C 11/13/2006 00:29 : 23:27 - 100% - 2.33GHz - 67C 11/13/2006 00:31 : 23:28 - 100% - 2.33GHz - 66C 11/13/2006 00:32 : 23:30 - 100% - 2.33GHz - 65C 11/13/2006 00:34 : 23:32 - 100% - 2.33GHz - 67C 11/13/2006 00:36 : 23:33 - 100% - 2.33GHz - 68C 11/13/2006 00:36 : 23:34 - 100% - 2.33GHz - 66C 11/13/2006 00:38 : 23:36 - 100% - 2.33GHz - 66C 11/13/2006 00:40 : 23:37 - 100% - 2.33GHz - 66C 11/13/2006 00:40 : 23:38 - 100% - 2.33GHz - 67C 11/13/2006 00:43 : 23:40 - 100% - 2.33GHz - 67C 11/13/2006 00:43 : 23:41 - 100% - 2.33GHz - 67C 11/13/2006 00:44 : 23:41 - 1% - 2.33GHz - 52C 11/13/2006 00:44 : 23:42 - 1% - 2.33GHz - 51C 11/13/2006 00:45 : 23:43 - 2% - 2.33GHz - 50C 11/13/2006 00:57 : 23:55 - 8.9% - 2.33GHz - 48C 11/13/2006 01:01 : 23:58 - 1.5% - 2.33GHz - 47C 11/13/2006 01:01 : 23:58 - 1.5% - 2.33GHz - 47C 11/13/2006 01:08 : 1 day 6 mins - 13% - 2.33GHz - 47C 11/13/2006 01:08 : 1 day 6 mins - 13% - 2.33GHz - 47C
And the results of the same test on MBP Core Duo (CD) 2.0Ghz:
11/02/2006 15:30 : 22:08 - 15.3% - 2.0GHz - 47C 11/12/2006 15:28 : 22:09 - 100% - 2.0GHz - 57C 11/12/2006 15:29 : 22:09 - 100% - 2.0GHz - 63C 11/12/2006 15:30 : 22:10 - 100% - 2.0GHz - 64C 11/12/2006 15:35 : 22:15 - 100% - 2.0GHz - 64C 11/12/2006 15:37 : 22:17 - 100% - 2.0GHz - 64C 11/12/2006 15:39 : 22:19 - 100% - 2.0GHz - 64C 11/12/2006 15:40 : 22:20 - 100% - 2.0GHz - 64C 11/12/2006 15:42 : 22:22 - 100% - 2.0GHz - 64C 11/12/2006 15:45 : 22:25 - 100% - 2.0GHz - 64C 11/12/2006 15:52 : 22:32 - 100% - 2.0GHz - 64C 11/12/2006 15:55 : 22:35 - 100% - 2.0GHz - 64C 11/12/2006 16:09 : 22:49 - 100% - 2.0GHz - 64C 11/12/2006 16:10 : 22:50 - 8.8% - 2.0GHz - 56C 11/12/2006 16:10 : 22:50 - 9.3% - 2.0GHz - 54C 11/12/2006 16:10 : 22:50 - 9.4% - 1.5GHz - 48C 11/12/2006 16:12 : 22:52 - 14.2% - 1.5GHz - 48C 11/12/2006 16:12 : 22:52 - 10.3% - 1.5GHz - 47CKeep in mind that I was not aiming for scientific precision when executing these test. Both test were done while the notebooks where plugged to AC adapters and the power management was set to "Better Performance".
I have to say that I was surprised by the results of my "old" MBP. The average temperature of 64C is the best that I've seen for MBP CD. And I know what I'm talking about because this is my 3rd MBP CD.
When it comes to MBP C2D, the results were much better than my expected peak temperature of 84C. Considering that one of the MBP CD 2.0GHz that I returned to Apple (see my older post) was able to easily reach 91C, these results are really good.
The results coming from my "old" MBP could most likely be considered exceptional, so I think in general I can say that the new MBP C2D is cooler than the early revisions of MBP CD. Both the peak temperature and the temperature with the fans running at higher RPM are lower than what I was used to seeing at MBPs CD.
After running the test for 30minutes I could feel that the cases of both notebooks were getting warmer, but only the bottom side of notebooks could be considered more than warm. Based on my previous experience with first generation MBPs, this is far from what I was used to feeling.
After this test I ran a quick battery life test: I unplugged the MBP C2D from the AC adapter, set the power management to "Better Battery Life", set the LCD brightness to half and started listening to iTunes streaming radio (via WiFi). I left the bluetooth on as well. The resulting time was exactly 3 hours. Since this was the first discharge of the battery, I would not be surprised to see slightly better results after a few charge cycles. This result is also a slight improvement compared to MBP CD.
Tuesday, October 17, 2006
Sun Unveils Project Blackbox
This is so cool! :) I almost wish to have one of these on my balcony.
Changing Font Size in NetBeans
When I started using NetBeans on Mac I felt that the font is just way too huge and text as well as menu and tab controls take a lot of space that could be used to display more code which means less scrolling.
The bug I submitted seems to attract attention of NetBeans developers these days so hopefully something will be done about it.
For now, I found out that you can control the font size with a command line parameter
--fontsize <number>
. Or even better you can put this in the netbeans.conf file that can be found in /Applications/NetBeans.app/Contents/Resources/NetBeans/etc/
directory. I prefer to use font size 11 (the default is 13). To set this you need to append the setting to the net so the netbeans_default_options
variable.
netbeans_default_options="........ --fontsize 11"Btw the version 5.5RC2 is out, this release doesn't contain the AIOOBE bug that was giving me a lot of trouble on my intel mac.
Friday, October 13, 2006
SafeSleep (a.k.a. Hibernation) for Intel Macs
But while the computer is in the "sleep" mode it still consumes some energy. Usually it's nothing worth considering, but when you are traveling for couple of days you might want to save every bit of battery energy possible.
Both Windows and Linux offer you an option of hibernation. Of course MacOS supports hibernation as well but Apple refers to this feature as "SafeSleep". While experimenting with my Macbook Pro I've noticed that SafeSleep is used every time the battery is totally drained and there is not enough energy for powering the Sleep mode. When you plug in the laptop, ahem notebook, to the power adapter, it will use the hibernation file to recover the content of the RAM and thus the OS state. In fact the hibernation file is created every time the computer goes to Sleep mode so taking out the battery while the computer is in the Sleep mode will have the same effect.
I was pointed to this article that discusses the
pmset
command line tool and describes how to use it to prevent Macs notebooks from waking up on opening the lid or setting up the power button to put the computer to sleep without displaying the "shutdown menu".pmset
tool can be used to set the hibernation/sleep mode:
pmset -a hibernatemode 0 # Sleep mode, but don't create a hibernation file pmset -a hibernatemode 1 # SafeSleep (Hibernation) mode pmset -a hibernatemode 3 # Sleep mode + create hibernation file (Default)When putting MacOS to sleep it will do whatever
hibernatemode
is set to.I also found this article that describes how to create an apple script that will enable you to hibernate the computer but launching it (without having to fiddle around with terminal). But unfortunately this script doesn't work for me so I fixed it a little:
do shell script "/usr/bin/sudo -k;/usr/bin/sudo /usr/bin/pmset -a hibernatemode 1; /usr/bin/sudo -k" with administrator privileges ignoring application responses tell application "Finder" to sleep do shell script "(/bin/sleep 25 && /usr/bin/sudo -k && /usr/bin/sudo /usr/bin/pmset -a hibernatemode 3 && /usr/bin/sudo -k) &> /dev/null &" with administrator privileges end ignoringStore this 5-line script via script editor as "Application Bundle" with "Run Only" option checked and you are good to go. I've noticed that when you save it as "Application" it still doesn't work.
One last note for PowerPC MacHeads: Some Powerbooks support SafeSleep as well, but it involves a little more work. Check out this article for more details.
Wednesday, October 11, 2006
Adobe Reader Direct Download Link
Adobe is giving me more and more problems on my Macbook Pro. After being unable to install any of the Adobe trial applications (due to an
abort trap
error during installation), I hahttp://www2.blogger.com/img/gl.link.gifd problems installing Adobe Reader as well. This time the Adobe Reader Download Manager doesn't do it's job.When you download the Adobe Reader from the Adobe website, you actually download "Adobe Reader Download Manger" that is supposed to download the Adobe Reader for you and launch the installation. What ever the reason for this is, it doesn't work.
You can however download the Adobe Reader directly and install it it without any problems. The link for the download is: http://ardownload.adobe.com/pub/adobe/reader/mac/7x/7.0.8/enu/AdbeRdr708_en_US.dmg
Tuesday, October 03, 2006
Does AppleCare?
But every love brings some pain... and I have experienced this as well. I was warned about revision A of any Apple computers, but at that time I really needed a new notebook so I was not listening.
So even though I was in love with this computer I started noticing problems with it. I don't want to post list of all of them because it would be quite a long list, but among others, I had heat problems, battery life problems, and noises coming from LCD and CPU.
I made an extensive search for these issues on the Web and I found out that I was not alone. Many users tried to have these problems fixed right away, but most of them were just wasting time by shipping their notebooks to be repaired and getting them back with most of the issues still present.
After approximately 6 weeks of using the notebook, I got to the point where I called AppleCare and let them know about my problems, hoping that they would have already had solutions to most of the problems.
Most of the people at the AppleCare call center I dealt with were really friendly and put effort in helping me. The opposite is true of the so called "Mac Geniuses" at the Valley Fair AppleStore in Santa Clara, whose main interest was to get me out of their sight after doing as little as possible.
To my surprise most of the problems were unresolved after the first repair. So right after the time when Apple finally acknowledged the "CPU Whine" problem I had the notebook fixed again. A couple of issues were resolved this time, but new problems were added as a free bonus, so another repair followed. This one took extremely long (almost a month) due to delays in repair docks as well as shipping problems, but worst of the notebook came back as I sent it, unrepaired, because Apple "could not reproduce the problems".
When even after the 3rd repair the problems were still present and I "reproduced" terrible noise one of the fans was making to a AppleCare representative over the phone, I was given an option of getting a brand new replacement, which I happily took thinking that my nightmares were over.
To my great surprise the replacement had problems of its own: SuperDrive problems, system crashes and a problem with the trackpad button.
This whole crusade for getting a notebook that "works as advertised" has been going on for months now.. and I'm getting yet another replacement in the next few days. Hopefully this time it will be a notebook that has no major issues.
Does all of this mean that Apple products are not what I used to hear about them or am I being just plain unlucky?
And regarding the question: "Does AppleCare?", my feelings are mixed. I think the answer is that yeah they do, if you make sure they know about your problems, you are persistent and you manage to talk to the right people. But considering the money you pay for a premium product and support, I think that Mac Geniuses, the product QA team and repair technicians have a lot of room for improvement. I hope that Apple's growing market share doesn't mean decreasing quality of their products and services.
Echo2 = Swing for Web Applications
One thing that I found really interesting about this framework is that the whole gui is composed from java components (like Swing) that are rendered as xhtml/css/js, and all the communication between client and server is done via AJAX. This makes the app responsiveness heavily dependent on the network latency but that it is the only price you pay for using this framework.
Sunday, September 10, 2006
Drawing (not just) UML fast and lightweight with UMLet
For a pretty long time I was frustrated with all the UML tools I tried to use. Most of them made me suffer a lot and I felt like I didn't want to draw UML diagrams any more (except on a white board or paper). Why? Simply because instead of these tools assisting me, they were giving me more work to do.
Sometimes it was an awkward user interface, problems with aligning elements or weird "UML" syntax. Most of the tools also shared another problem: they were just way too slow to start and/or they slowed down tremendously with the increasing number of elements in a diagram.
UMLet has coped with all of this problems in a very elegant and simplistic way. Some of the main features include:
- small size 5.0MB / 9.9MB (download/unpacked)
- fast and easy to use even when drawing larger diagrams
- exports diagrams to jpg, svg, pdf, eps
- a large palette of diagram elements
- support for custom elements (edit and compile java code within UMLet)
- free with source code included
- integrates with Eclipse
- export to gif and png
- no support for zoom in/out
A diagram like this can be drawn in a matter of seconds:
Editing individual elements of a diagram is super easy. UMLet is unique in its pop-up free approach to the user interface. All the properties of an element are defined as string attributes that are edited via a textarea-like interface. For example, properties of the "Delete record" use case above are defined as:
Delete record bg=blueThat's it. Simple, yet powerful and elegant.
Some extra examples of what kind of diagrams you can draw with this tool are here and here.
You can download UMLet from: http://www.umlet.com/
Try it.. it's really worth it!
Good job UMLet team!
Saturday, September 02, 2006
Solaris + Lighttpd + FastCGI + SSL HowTo
I hadn't heard about Lighttpd (Lighty) web server before I started to be interested in Ruby on Rails (RoR). Lighttpd is fast, scalable, secure, flexible and lightweight webserver which in RoR community is preferred production web server. One of the main advantages of Lighttpd compared to Apache, for example, is the built in support for FastCGI and very easy yet flexible configuration.
When I was preparing the production environment for one of the RoR applications I was working on lately, I found that even though there is quite a lot of HowTos for installing lighttpd on linux and MacOS, there is not a single one that I could find that would describe this procedure on Solaris / OpenSolaris OS.
While setting up the production environment I got stuck on some steps, and I hope that this HowTo will help anyone trying to deploy his RoR application on Solaris and to avoid problems I had.
Targeted configuration: Solaris 10 + Lighttpd + FastCGI + SSL
1. Prerequisites I started out with the core installation of Solaris 10, this means that I needed to add some packages. Before you start, make sure you have these Solaris packages installed:
- SUNWhea >>> needed by lighttpd
- SUNWtoo >>
- SUNWlibmr >>> needed by fastcgi
- SUNWlibm >>
From blastwave.org via pkg-get get:
- openssl >>> needed by lighttpd for ssl
- option 1) 202MB - works
- option 2) 365MB - haven't tried
Now we should be ready to start.
2. Lighttpd
At first we should install Lighttpd which can be downloaded from here. (I used gcc to compile this one)
./configure --with-openssl=/opt/csw --with-ldap --with-bzip2 --with-zlibThe output from the configure command should end like this:
Features: enabled: auth-crypt auth-ldap compress-bzip2 compress-deflate compress-gzip large-files network-ipv6 network-openssl regex-conditionals ... ...
Make sure the "network-openssl" is in the list of enabled features, if it is not there, check the output from configure tests and if you see that openssl was found and right below it is:
checking for BIO_f_base64 in -lcrypto... nocheck your configure arguments and make sure that --with-openssl=/path/to/openssl is set correctly (if installed via pkg-get it will resided in /opt/csw). If this is not done properly everything will compile correctly but the --with-openssl option will be ignored silently!
Let's finish up the installation:
make make installTest if everything went well with -v switch
$ ligttpd -v lighttpd-1.4.11 (ssl) - a light and fast webserver Build-Date: Aug 30 2006 15:19:28If there is no "(ssl)" after the version, something is wrong, check if you set --with-openssl=/path correctly.
3. FastCGI
Now we need to install FastCGI which can be downloaded from here:
./configure --prefix=/usr/local make make install4. ruby-fcgi
Next step is to install ruby-fcgi bindings. This is where I got really stuck. To be able to install this, you need the Sun C Compiler mentioned earlier. If you installed ruby and ruby gems via pkg-get as I did, it comes preconfigured to use Sun compiler by default, even if one is not installed. And if you don't have this compiler you will see all sorts of weird errors when installing gems with native extensions.
Once you have the compiler, installation is trivial. If you are building it manually, download sources here:
ruby install.rb config -- --with-fcgi-dir=/usr/local ruby install.rb setup ruby install.rb installor when using ruby gems:
gem install fcgi -- --with-fcgi-dir=/usr/localNote the double "
--
", that is not a typo, it's simply the way how to send parameters to extconf.rb
If you see an error like this:
install.rb: entering config phase... ---> lib <--- lib ---> ext ---> ext/fcgi /opt/csw/bin/ruby /root/ruby-fcgi-0.8.6/ext/fcgi/extconf.rb checking for fcgiapp.h... yes checking for FCGX_Accept() in -lfcgi... no <--- ext/fcgi <--- extNote this part:
checking for fcgiapp.h... yes checking for FCGX_Accept() in -lfcgi... noIt most likely means that you are using GCC and not Sun C Compiler, check if cc in your path is pointing to Sun C Compiler, you might also check if the environmental variable CC is not set to gcc. Let's test if fcgi and ruby-fcgi bindings were correctly installed by these commands in irb:
irb(main):001:0> require 'fcgi.so' => true irb(main):001:0> require 'fcgi' => trueIf both "require" calls return true, you have successfully installed FastCGI and ruby is able to invoke it. 5. SSL Certificate
If you don't have your server certificate yet, you can create a self signed one like this:
openssl req -new -x509 -keyout server.pem -nodes -out server.pem -days 10006. Configuring Lighty
Create lighttpd.conf
server.port = 443 server.bind = "0.0.0.0" server.modules = ( "mod_rewrite", "mod_fastcgi", "mod_accesslog" ) url.rewrite = ( "^/$" => " index.html", "^([^.]+)$" => "$1.html" ) server.error-handler-404 = "/dispatch.fcgi" server.document-root = "/path_to_your_app/public" server.errorlog = "/path_to_your_app/log/server.log" accesslog.filename = "/path_to_your_app/log/access_log" ssl.engine = "enable" ssl.pemfile = "/path_to_your_pem_file/server.pem" fastcgi.server = (".fcgi" => ( "localhost" => ( "min-procs" => 10, "max-procs" => 10, "socket" => "/tmp/yourapp.fcgi.socket", "bin-path" => "/path_to_your_app/public/dispatch.fcgi", "bin-environment" => ( "RAILS_ENV" => "production" ) )) ) mimetype.assign = ( ".css" => "text/css", ".gif" => "image/gif", ".html" => "text/html", ".jpeg" => "image/jpeg", ".jpg" => "image/jpeg", ".js" => "text/javascript", ".pdf" => "application/pdf", ".png" => "image/png", ".txt" => "text/plain", )
7. Ta-da!
Let's start the server
lighttpd -f lighttpd.conf
I hope that these instructions helped you to get Lighty on Solaris.
If you have other recommendations or have problems with the installation, feel free to leave a comment.
Enjoy..
PS: A big thanks to my friend J who helped me figure out that you need Sun C compiler for ruby-fcgi to compile.
UPDATE: added reference to SUNWbtool and SUNWsprot packages in case you want to compile everything with Sun's compiler.
Sunday, August 27, 2006
Giving Back...
I hope that I can contribute back to this community by submitting a few bugs and posting a few ideas, thoughts or discoveries that I come up with while working and having fun.
Friday, August 25, 2006
Sun Updates Java Tutorials Website
The update seems to have a lot to do with upcoming release of JDK6, because the content already reflects the new features included in this release. Either way, it is nice to have one place to go to get some more insight into Java core libraries and tools and the proper way of using them. Some parts of the tutorials I've checked out were a little bit too "high-level", but that is understandable considering the scope of JDK. The only critisizm I have about the site is that it could use some "face lifting", but that might change by the time JDK6 is released.
Sunday, August 20, 2006
Debugging Deadlocks with JConsole in JDK6
If a code is deadlock prone, it doesn't mean that the deadlock will occur. Deadlock will occur only when wrong actions take place at a wrong time (or order), which makes it really difficult to find and debug deadlocks. When an application is deadlocked it appears to do nothing while consuming only very little of CPU time. The chance of a deadlock appearing grows with the number of threads that execute deadlock prone code as well as with the number of repetitive executions of deadlock prone code (even if it is being executed by only a few threads). The conclusion of this is that if you stress your code by multi-threaded tests, it is more likely that a deadlock will appear compared to no testing, or testing the code only with single-threaded test cases. If a deadlock appears, the tests will freeze and that's about everything you will see. To track down what caused the deadlock is usually very difficult at this point.
JConsole comes to rescue
JConsole - Java Monitoring & Management Console, is a utility that is a part of the JDK since version 5.0 and has been greatly enhanced in upcoming JDK 6. JConsole is JMX based which enables it to easily connect to running JVM and monitor application running in JVM. The only requirement is to start JVM with parameter
com.sun.management.jmxremote
as:
java -Dcom.sun.management.jmxremote YourLocalApp
or
java -Dcom.sun.management.jmxremote.port=portNum YourRemoteApp
Once the JVM is running you can launch JConsole and connect to the JVM and start monitoring.
One of the features that has been enhanced is "Deadlock detection" located in "Threads" tab. Simply described: if your application gets deadlocked, you can start up the JConsole and see where the deadlock occurred, which threads are involved, and which thread owns and is blocked for which locks. Pretty cool :)
Wednesday, August 16, 2006
Java Singleton Revised
In this article the author describes problems with different Java implementations of singleton pattern that are most of the time visible only in multi-threaded environments.
To make long story short his conclusion is that it is not good practice writing a singleton class as:
class Singleton { private static Singleton instance; private Singleton() { //initialize instance } public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
This is commonly used but as described in the article, not a thread safe implementation. Developers should neither use a double-checked locking implementation (described in the article), but rather use one of the two options:
- make
getInstance()
method synchronized - which will be thread safe, but will have impact on performance - initialize static class variable
instance
at declaration time like this:
class Singleton { private static Singleton instance = new Singleton(); private Singleton() { //initialize instance } public Singleton getInstance() { return instance; } }
I like simple solutions to problems that are not always simple and so I like this solution. However IMHO, this implementation is not suitable for all cases where you might want to use singleton pattern.
Let's take a singleton that executes operations on a file as an example. At some point in your program you need to close the RandomAccessFile
, FileOutputStream
or FileWriter
that you are using (you always close files and db connections right? :) ), so I would expect that you would add another static method to the Singleton
class that would close all necessary resources that you opened in the private constructor.
Let's call this method closeInstance()
and implement it like this:
public static synchronized void closeInstance() { //close all necessary resources instance = null; }
We closed all resources and since these resources (required for this class to operate) are closed, we can also set the instance to null
to prevent someone using Singleton
instance while it is an in unusable state. This method is synchronized to prevent some problems with concurrent access.
What will happen if you try to call getInstance()
now? A null
will be returned. That is not really what you would expect, is it? What would you do if for whatever reason you closed the Singleton
instance and later on realized that you need to open it again. You don't have access to constructor and no other way how to initialize the singleton again.
My solution is based on the solution of Peter Haggar, but enhances it to prevent the issues I mentioned above.
public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { //initialize instance //opens all necessary resources } /** * Returns the singleton instance. If the singleton instance was * not previously closed, the instance is initialized before first * call of this method automatically. * * @throws IllegalStateException if instance had been closed by *closeInstance()
method */ public static Singleton getInstance() { if (instance == null) throw new IllegalStateException( "Singleton instance has been closed already"); return instance; } /** * Cleanly closes singleton resources and removes the singleton * instance */ public static synchronized void closeInstance() { //close all necessary resources instance = null; } /** * Creates and returns a reference to the new instance. * If the instance already exists, then the reference to this * instance is returned. This method is intended to be used only * in cases when there is a chance that the instance was previously * closed. In other cases use ofgetInstance()
is encouraged because * of performance benefits, since this method is synchronized * as opposed togetInstance()
. */ public static synchronized Singleton createInstance() { if (instance == null) instance = new Singleton(); return instance; } /** * Checks the status of the singleton instance * * @return true if singleton instance is initialized, if instance * was closed returns false. */ public static boolean instanceCreated() { return instance != null; } }
This implementation of Singleton gives you all performance benefits of the first mentioned implementation while being thread safe and giving you all the flexibility of reinitializing the singleton instance once it was previously, intentionally destroyed.