RSS

UPDATE – Site Cleaned, Malware Removed

Tue, Jun 30, 2009    (Click to Rate!) Loading ... Loading ...

0 Comments

google-chrome-malware-site-warning

Over the last few weeks you might have seen a warning window like the one above (or similar to it) when visiting the site. Unfortunately it looks like some WordPress plugin-tinkering that I did right before going on vacation introduced an obnoxious malware hook into the site (don’t worry, it’s nothing epicly horrible).

I just finished manually cleaning it out using talgalili’s tip here. The infection was an invisible iframe-hack injecting a reference to the m-analytics.net site in every single .php or .html file hosted on the site — really obnoxious but easy enough to clear out and tighten up everything in the process.

Sorry you guys had to deal with that while I was gone, we should be good now.

Continue reading...

Did You Know enums Can Define Their Own Methods?

Mon, Apr 20, 2009    (Click to Rate!) Loading ... Loading ...

4 Comments

… I sure as hell didn’t, but found myself in a position the other day where I was thinking “Damn, I wish I could define a common method in this enum that I could call and not have to write another utility method…” Well, ask and ye shall receive… or something like that.

Here’s the enum I had defined in one of my classes:

public static enum EventType {
    COMPONENT_ADDED,
    COMPONENT_REMOVED
}

It’s fairly straight forward what I was using it for — every time I fired an event of a certain type, I always make sure to set the type on the event, so the receiver knows what to do with it.

The situation I found myself in, is similar to MouseEvent’s use of the BUTTON constants in that when a new event of the specific type is created, the only valid eventType arguments allowed should be of ones defined in the enum itself.

NOTE: As I write this, it just dawned on me that this specific example is an invalid use-case, but I’m still going to finish the example because it’s really cool that you can define methods inside of enums. For those that haven’t caught my mistake yet, I’ll explain why this example is invalid at the end of the article.

In order to guarantee that the provided eventType is part of the defined enum, I sat down and started to write a simple boolean contains(EventType eventType) method in the parent event class… it was then that I realized “this feels wrong, this method that checks contains state should be defined in the enum itself — it’s the logical place one would look for such a thing”

After some digging online, it turns out defining methods inside enums is completely valid, becuase they are essentially classes. What I ended up with is the following:

public static enum EventType {
    COMPONENT_ADDED,
    COMPONENT_REMOVED;

    public static boolean contains(EventType eventType) {
        boolean contains = false;
        EventType[] values = EventType.values();

        for (int i = 0; i < values.length && !contains; i++) {
            contains = (COMPONENT_ADDED.equals(values[i]) || COMPONENT_REMOVED
                    .equals(values[i]));
        }

        return contains;
    }
}

So now when I receive an eventType in the constructor of the parent event, I can check it with a simple:

if(!EventType.contains(eventType))
    throw new IllegalArgumentException();

Very cool stuff.

CLARIFICATION: For those that didn’t catch my mistake with this example, you’ll notice the entire purpose for writing the contains(EventType eventType) method in the EventType enum is to verify that a given instance of EventType was defined in the enum — the answer is “of course it has been” — the only value I have to check for is null, if the value of the eventType argument is not null, it’s already guaranteed that it is a valid value from the enum, because it is an instance of the enum — so there is no need to check.

Even though I mad that glaring mistake with this example, I don’t want to think of another example on the fly that is more applicable, or dumb this one down to something really generic like the classic fruit-type example — instead the information provided should still be helpful if you are curious about learning about enums in Java 5 or later in more detail.

ADDITIONAL NOTE: I’m always surprised at the number of people that don’t know about using multiple-conditions in the standard for-loop above. It’s an awesome way to short-circuit an itteration when you find what you want.

Continue reading...

Windows 7 on a Lenovo Ideapad S10e Netbook

Mon, Mar 9, 2009    (Click to Rate!) Loading ... Loading ...

11 Comments

windows-7-lenovo-s10e-desktop

At the end of January I ordered a nice shiny Lenovo Ideapad S10e from Buy.com. I managed to get a decent price that didn’t hurt the pocketbook, and it was a new toy that I could endlessly experiment with. I started to install a wide variety of operating systems to check for support and to put it through the paces.

Now, if you’re like me, you have a profound dislike for Windows Vista (especially on laptops). Of all the operating systems I’ve chosen to install on the 10e I decided to skip Vista because it takes forever to boot and nags you like a four year old for doing just about anything.

My interested was piqued when the beta for Windows 7 was released. During the time period that I was deciding to purchase the Ideapad, I managed to sign up for the Windows 7 test and downloaded the iso. I basically just had it lying around until my S10e arrived. What better a machine to install a brand new Windows operating system on than a shiny new netbook. I plunged…

Before this was possible, I had to get an external cdrom drive. I located a combo on NewEgg that included a 2GB stick of Kingston RAM and a highly portable, power adapter-less Samsung SE-S084 DVD Burner.

With that, the new specs are as follows:

10.1″ Screen (1024×576 remember this is the ‘e’ model)
1.6Ghz Atom
2 GB Ram (2 gigs is the max the atom can see)
80GB Hard Drive
802.11g
10/100BaseT
ExpressCard Slot

I went ahead, booted up with the Windows 7 install disk, and walked the paces.  My first impressions were good since the install took about 30 minutes (enough time to make a cup of coffee and read the latest Slashdot). Boot up speed was okay, I eyeballed  a little over a minute with my wrist watch, including the time it took to enter my password and log on.

Now, if you haven’t used Vista before, Windows 7 will look pretty different, and it will most definitely feel like the red headed, alien step child compared to Win2k or XP. Here is a little proof that it did actually install:

windows-7-lenovo-s10e-system-information

You might notice that the RAM registers at 2.5 GB. You might also notice that I said my machines specs are 2GB. I wasn’t lying. Unfortunately for me, the Atom chipset can only recognize and use 2GB of memory. That means that the standard (and soldered-on) 512MB is nothing more than a space hog internally disabled.

Gripes about the chipset aside,  I really wanted to see how this little Ideapad would stack up so I started the benchmark tools that Windows 7 came with to see how it ranked. After a couple of minutes, the score came to 2.2, the lowest score achieved among all the tests. A screenshot can be seen below.

windows-7-lenovo-s10e-windows-experience-performance-results

Not too surprised by the score (it IS a netbook), I decided to check Windows Update to make sure there weren’t any outstanding video, sound, or otherwise performance enhancing updates. Naturally, there were three. I went ahead and updated, rebooted, and started the test over. Nothing changed, I still managed a 2.2. Oh well.

windows-7-lenovo-s10e-windows-experience-performance-retest

The next  big thing I wanted to test was Power Mangement, and I have to say I was pretty impressed with the sleep/wake function (key for being able to be constantly on the run). Know that I am a Mac user half of the time (the other half an Ubuntu user), and know that Apple has spoiled me pretty bad as far as the Sleep/Wake capabilities of a laptop. Fanboy silenced, I’m impressed. The Lenovo takes a little bit longer than my Macbook to wake from sleep, but is usable in well under two seconds. The stock XP install took closer to 10 seconds to wake and ‘do it’s thing’.

Unfortunately, I did notice something a little odd after putting the Ideapad to sleep and then waking it. There seemed to be a high pitch sound that randomly starts within a couple seconds of waking up. I’ve whittled this down to a driver issue since the high pitch sound goes away when I increase or decrease the volume. I went straight to the RealTek site, grabbed the latest drivers for the sound card  (2-24-09) and installed them. This seemed to do the trick.

Next up was battery life. I know the true purpose for these little machines isn’t to watch a DVD, but it is is something I’ll at least want to be doing at every now and again. I wasn’t going to be using wireless during this time, so I turned it off as well as decreased the screen brightness to half of its normal output. Next, I popped in a 16:9 DVD, and here is what I saw:

windows-7-lenovo-s10e-dvd-playback-pans-labyrinth

Using Windows Media Player, the DVD opened up in perfect widescreen mode with no black borders. This is thanks to the native 1024×576 resolution on the 10e (remember the .1″ difference in screen size compared to the S10). Normally, I wouldn’t have accepted the loss in prime 24 pixel real estate, but so far I haven’t found it a problem. In this case, it actually makes it the perfect screen for viewing widescreen dvds.

Sadly my viewing pleasure came to an end about 10 minutes too early. The battery power had been depleted and Windows started to hibernate the netbook at 6% battery life. I’m sure there was some sort of modification I could have made to prevent it, but in all honesty 6% wouldn’t have given me much to work with anyways. I was going for minimal tweaks so beyond changing the the screen brightness and the power saving setting I don’t think a normal user would think of anything else.  In the end, the 1 hour 51 minute runtime is still a little unimpressive for the machine but it is okay. I have to give some credit to the S10e since the Samsung external DVD drive is completely USB powered.

windows-7-lenovo-s10e-dvd-playback-battery-life

That being said, I didn’t want to leave the experience with a crutch so I decided to help balance it out by rerunning the battery test with another movie imported to h.264 and on an SD card. This is the more ideal situation for me, since I will mostly be watching movies mostly from SD cards instead of a cumbersome external DVD setup.

Under an hour and a half into the movie I checked to see the time left on the battery. To my dismay, 26 minutes were left. Looks like the external DVD drive didn’t consume that much power after all. Again, Windows decided to hibernate at 6% and I was still missing about 5 minutes of the movie. As far as Windows 7 is concerned, battery life conservation when watching DVD or DVD quality movies is poor despite enabling ‘Power Saving’ and disabling wireless.

After the movie test I decided to ease up a bit and retest the ‘Power Saving’ setting in Windows 7. I managed to get about 2.5 hours of ‘normal use’ out of the netbook when web surfing, and writing emails. Nothing too spectacular, but on par with other netbooks running XP.

Since I did have the DVD Burner, I wanted to test out Windows 7’s support for burners. I downloaded the latest MythBuntu ISO, right clicked, and I had an option to burn the ISO. Very nice. I was able to burn the ISO without needing any extra software. I did run into a little problem though. Before I burned the ISO I selected the option to verify the disk when it completes. The verification pop up never completed, and left me with this on screen:

windows-7-lenovo-s10e-dvd-burn-stuck-verify

The disk did, however, burn successfully. Next, I installed Safari to test drive the massive Javascript improvement Apple has been touting. The install went clean, and I was presented with a fairly nice interface on the little netbook screen.

windows-7-lenovo-s10e-safari-2-screenshot

I almost preferred this to Firefox since the address bar didn’t take up as much screen real estate. It ran pretty nice making Gmail quite a bit zippier. I also ran some Sunspider benchmarks comparing IE and Safari and there wasn’t really much of a competition.  Safari won hands down with final tests running 5x faster than IE. That just solidified my stance that my prefererence is not for IE and I don’t think Windows 7 will change it.

After spending a couple days with Windows 7 on the S10e, I feel that it was at least on par with the performance of Windows XP, and much better than the initial Vista release I had experienced on other, more powerful laptops. I was happy with the built in features: a new and clean interface, ability to burn ISOs without extra software, complete hardware support for the netbook, and okay power savings. As it has more time to mature, I’m sure Windows 7 might be a viable contender on these new Atom-based machines.

Windows 7 Screenshot Gallery


Continue reading...

Explanations of Common Java Exceptions

Tue, Feb 24, 2009    (Click to Rate!) Loading ... Loading ...

0 Comments

Huge thanks to Marc Chung for sending along this great reference. It’s a breakdown of all the JDK exceptions and textual descriptions of what they represent — so if you are designing your own API or just working on your own app and want to make sure your use of particular exceptions (e.g. IllegalArgumentException) is correct, give it a look.

For a quick reference, here’s the breakdown of just the java.lang Exceptions:

java-exception-explanations

Continue reading...

Global, Mac-like Menubar on GNOME with gnome2-globalmenu

Mon, Feb 16, 2009    (Click to Rate!) Loading ... Loading ...

4 Comments

gnome2-globalmenu-mac-terminal-example

Caught the introduction of this story over on OS News — apparently folks have been voting on the addition of a global, application-context sensitive menubar in Gnome for a while. The design of the bar is very similar to the way the global bar in Mac works. For those that don’t know, there is a universal menubar across the top of any Mac OS X desktop:

mac-osx-desktop-annotated

the contents of the menubar changes depending on the application that is currently focused. This is different (and sometimes strange) for Windows users that expect to see the application’s menubar inside the application itself (File, Edit, View, etc. menus).

The Linux/Unix desktop environment, GNOME, has always behaved similarly to a Windows desktop, with the applications managing their own menubars. However, given GNOME’s drive to be a simple/intuitive desktop (and the default for the popular Ubuntu Linux distribution), there has always been a very Mac-esque feel to the advancements that GNOME has taken with UI development… almost a hybrid between what Windows would do and what Mac would do. Because of this line that GNOME tended to walk, the desire to have a Mac-esque universal menubar isn’t too far of a stretch for the imagination.

Having this battle fought back in 2006 on Bugzilla resulting in some buggy and initial attempts at a global menubar, the effort never really got the steam it needed to be a viable solution for folks (or make it into GNOME proper). Fast-forward to today, and enter the very intuitive and flexible solution: gnome2-globalmenu project

gnome2-globalmenu-mac-about-dialog

As you can see from the screenshot above, globalmenu is a GNOME applet, requiring no hacked GTK builds or special GNOME builds — simply follow the dead-easy Ubuntu install instructions (or generic install instructions). For the Ubuntu folks, you’ll want to register the following repository depending on the Ubuntu version you are on:

  • Ubuntu 9.04 – Jaunty Jackalope:
    • deb http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu jaunty main
    • deb-src http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu jaunty main
  • Ubuntu 8.10 – Intrepid Ibex:
    • deb http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu intrepid main
    • deb-src http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu intrepid main
  • Ubuntu 8.04 – Hardy Heron (LTS):
    • deb http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu hardy main
    • deb-src http://ppa.launchpad.net/globalmenu-team/ppa/ubuntu hardy main

NOTE: When registering the repository, be sure to check the Add Source box as well, that will automatically add the deb-src entries above to your sources list.

Next, on the Authentication Tab, you can import the gnome2-globalmenu GPG repository key to authenticate the software against, and then hit Reload and you are all set. When you are done the applet installed and listed in the GNOME Add to Panel dialog:

gnome2-globalmenu-mac-add-to-panel

and away you go!

Configuring globalmenu is straight forward, with some basic preferences you can choose:

gnome2-globalmenu-mac-applet-preferences

and usage is automatic… when you fire up an application, it’s menu-bar does not exist in the application’s window, but is instead promoted to the top of the screen to the global menubar:

gnome2-globalmenu-mac-gimp-scrolling-popout-menus

Right now only GTK-based applications are supported, so for applications like Firefox and OpenOffice, the menubars will still exist inside the application’s main menu, but this is an excellent start to the work.

Let’s hope this rolled into a future GNOME release and built on!

Continue reading...

FOG as a web-based Ghost Replacement

Sun, Feb 1, 2009    (Click to Rate!) Loading ... Loading ...

4 Comments

Login Screen

Lets face it, some sectors just can’t move to Linux due to legacy application support, lack of personnel support, employee training, and especially due to the jump in vastly different user interfaces. Each company has their own incredibly (insert sarcasm) unique reason for holding back. So, what is left for the network admins to do other than to support the Windows base? What if there were more than 10, 50, or even 100 computer involved and your admin staff is less than 5?

As some of you might know, I use to manage a network of computers for a small office supply way back in the day. The one thing that I wanted most was to have a standard image to distribute to all the machines at any given time. Being the sole administrator working part time, remotely, and basically with no budget my options were severely limited. I longed for a solution that gave me the power to use 1 machine to create a custom image that could easily distribute security updates, software configurations, printer setups, and network shares. Those days are long gone, but a solution to this common problem has cropped up. Enter FOG, “a free computer cloning solution.”

FOG was created as a solution to a non web-based, expensive re-imaging product that often required the use of driver disks. FOG incorporates the use of TFTP and PXE to do its remote imaging, and a webserver to do the administration.

The install is pretty easy, and the wiki has step-by-step instructions for Ubuntu and for Fedora. Since the wiki has some great information on setting up FOG, I’ll refrain from duplicating documentation. Check out the User Guide wiki here.

Once you startup the install script you’ll be prompted for a Server type, your server address, your DHCP router address, and if you want to use your server install as a DHCP server. I went with the defaults giving the ip address of my server, using my router as the dhcp server, and not enabling FOG as the default DHCP server. Once the install gets going you should see a similar window:

Configuring the server with the install script

After that is done, you’ll be able to login to your freshly installed imaging server. There are a couple of things to note here. Since you need to be able to network boot your boxes, your DHCP server has to know the alternate location to send the netboot clients to. This is briefly described here. Also note, if you had a MySQL server installed before you added FOG you’ll need to modify the /var/www/fog/commons/config.php file to reflect the MySQL root password.

If you direct yourself over to http://localhost/fog/management. You can then use username: fog and password: password to get to the status/home page:

Status page after loggin in the first time.

I would suggest adding a new user to do the management work. You can get to the user management page by clicking on the icon next to the ‘home’ icon in the toolbar (second from the left), click New User in the left hand menu, entering a username and password  and then clicking Create User.  Next, you’ll want to add some hosts. Click on the icon that has a single monitor (third from the left), click Add New Host, and then enter the hostname and hardware address of the Windows machine you wish to image. If you don’t know the hardware address of the host you want to add, and are on the same network you can look it up using the arp table.

First, ping the host (using your hosts ip in place of the 192.168.0.101) to make sure it is alive. Then check the arp table:

~$ ping -c 1 192.168.0.101
~$ arp -a

After adding a host successfully you should see something similar to this:
Host Added Successfully window

Since I didn’t have much space on my image server to begin with, I modified the default storage node to point to a samba mounted filesystem on my fileserver. This is where you’ll store all of your backup images. Since this can get big pretty fast, you’ll want have lots of dedicated storage. You can modify the aforementioned settings by clicking on the Storage Management icon (the sixth icon from the left).

Storage management page

Now we need to add an image. You can do this by clicking on the icon labeled Image Management (the fifth icon from the left). Click New Image, enter in a name, select a Storage Group, an image filename, and then select the type of image to be stored (Single Partition, Multiple Partition, Multiple Partition all Disks, or RAW). As far as the server management goes, you are done. Before uploading drive images to the FOG server, though, you will need to install the client package on the machine you wish to image. that software can be obtained by going to http://[fog server]/fog/client.

Overall, I found the interface fairly intuitive. I would have given it a very intuitive rating had the advanced host tasks been easier to find. I mean, this is one of the really cool features of FOG and the amount of tools that it packs is enough to blow your socks off. If you click on the Tasks Management Icon ( the Star ) on the main site, click on List All Hosts, and then click on the little Advanced icon you get a chance to see what I’m talking about. There are a slew of great utilities to run on the host:

  • Debug features for Uploading and Deploying images
  • Memtest86+
  • Wake-On-Lan
  • Fast Wipe (destroys MBR)
  • Normal Wipe (one pass zeroing out data)
  • Full Wipe (writes random data over a couple full passes)
  • a Disk Surface Test
  • Test Disk
  • Recover (using PhotoRec)
  • Antivirus (using ClamAV)
  • and a Hardware Inventory Utility

Management tasks available for each host.

If you are looking into how to maintain a small to large amount of computers in a SMB or campus setting, you really should consider checking out FOG. Leveraging the best of Open Source you’ll be able to easily deploy standard images to loads of computers in a minimal amount of time. You can even manage computers using your iPod or iPhone!

iPod Screenshot taken from Fogs Documentation site

Check it out, and let us know what you think!

Continue reading...

Using Fail2Ban to prevent Brute Force Attacks

Sat, Jan 31, 2009    (Click to Rate!) Loading ... Loading ...

2 Comments

lock screen Has your SOHO server been seeing a lot of failed ssh attempts from ipaddresses unknown to you? If so, you might be suffering from a brute force attack. These types of attack attempt to break into your box by trying to guess usernames and passwords. They are typically run on zombified computers from all over the world. What can you do about it you ask? Well, fortunately there are programs out there that read failed authentication attempts and modify your firewall to ignore requests from those locations. One such nifty application is called Fail2Ban. I’m going to give you a quick run through on how to setup Fail2Ban to protect against brute force attacks on your Ubuntu ssh server.

To install, you can grab the source code, or use apt:

~$ sudo apt-get install fail2ban

Next we need to modify the config files to suit our needs a little better. Go into your /etc/fail2ban folder and make a copy of the jail.conf. Name it jail.local:

~$ cd /etc/fail2ban
~$ sudo cp jail.conf jail.local

There are a couple of things I want to change from the default settings. The first would be increasing the bantime from 10 minutes to an hour. Then I want to change the max number of tries to 3. This will go for all services that are currently protected by fail2ban. So, lets go ahead and edit the [Default] section of the jail.local that we just copied to look like this:

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1
bantime  = 3600
maxretry = 3

Now lets give it a go! Save the file, and lets restart the fail2ban process.

~$ sudo /etc/init.d/fail2ban restart

For the sake of the article I’ve tested the setup, and you can see what I’ve found. In the top screenshot below I tried logging into my local ssh server, and in the bottom screenshot you’ll see the fail2ban.log and auth.log’s tailed output from the SSH server.

Bad ssh client! fail2ban.log and auth.log on ssh server

Normally, I don’t think a box on my network is going to fail authentication a bunch of times, or, rather, I don’t want to ban any boxes on my network.  What do we do? If you go back into the /etc/fail2ban/jail.conf file, you should notice the ignoreip option. You can modify this file again to ignore all bans for a 192.168.0.x IP by setting this option:

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1 192.168.0.0/24
bantime  = 3600
maxretry = 3

Save the file, and restart the fail2ban process again, and you are in business. This should keep script kiddies and brute force attacks away. Happy Hacking!

Continue reading...

Mephisto Backup

Fri, Jan 30, 2009    (Click to Rate!) Loading ... Loading ...

1 Comment

Mephisto Screenshot

I’ve recently ran across a unique little backup utility called Mephisto. The program is a command line tool written in Java that incorporates rsync and tar to do filesystem backups to a remote filesystem or local image. Of course utilities like this are great for doing system duplication, and especially great when you roll your own LiveDVDs for disaster recovery or general backups. To backup to a remote server you’ll first need to copy over your ssh id (the utility has a little information on that when you go to create a configuration file), and then create a configuration file with the specs for your remote fileserver. I had a chance to test the remote sync feature from my laptop to a ssh server, and while the utility is a little rough around the edges it does function well. One thing that drove me a little nuts was the lack of a status bar during file transfer. While the utility does have a little room to grow, I think this is a pretty good starting point and definitely a great piece of Java code to disect.

Network Backup Screen

You can grab a copy from the blog site in two flavors: one including a JRE or one with just the base program. Check it out, and let us know what you think!

Continue reading...

VitualBox 2.1.2 Released

Tue, Jan 27, 2009    (Click to Rate!) Loading ... Loading ...

0 Comments

virtual-box-logoYou might have noticed that VirtualBox 2.1.2 has been released into the wild. While there is a laundry list of changes, a few performance and stability enhancements for Mac OS X were on the top of want my list.

While Parallels and VMWare offer commercial solutions, Sun backed VirtualBox offers many similar features for free. As mentioned before, however, stability issues have kept me from using it on my Macbook. After having some time to play with this new .1.2 update, I’ve found that most of my previous issues have been resolved. I haven’t experienced random crashes, and I was successfully able to boot OpenSolaris 8.11, Ubuntu Intrepid Ibex, SymphonyOne, and PC-BSD with no hiccups. I even managed to get through almost all of the ESXi bootup disk (a task that would fail within seconds before)!

Macbook Ubuntu CPU

I have been very happy with VMPlayer on my Linux boxes, but felt the lack of a viable free solution for Mac OS X. After a couple of hours, I think I can safely say that Sun contributed greatly to this very impressive, and free, application. I also wasn’t too disappointed in speed considering my Macbook didn’t grind to a halt when starting up Majong. So, if you need a quick virtualization setup that has all the tools to get a guest system installed in one go, then you might want to try VirtualBox.

Check out the latest release, and let us know what you think! Here are some of the screen shots from my experience:

Continue reading...

Beginners Guide to Quick File Listing Using Ruby

Sun, Jan 25, 2009    (Click to Rate!) Loading ... Loading ...

2 Comments

As a beginner to the Ruby language, I often found myself needing feedback listing which files are in a given directory. Ruby, for that reason alone, has been a quick savior. A couple of Google searches on this topic will land you somewhere near the Ruby class Dir. Dir is a part of the standard Ruby distribution, and offers many unique ways of dealing with directories, and the files they hold. You can find out more on the specifics here.

So, my very basic problem was this: I want to search the current directory, and list all the files and folders in the current directory recursively. If you are familiar with bash shell scripting, you’ll know that this task is pretty basic and can be completed with the following:

#!/bin/bash
for i in $(ls -R ./)
do
  echo "$i"
done

So, why Ruby then? Well, bash doesn’t have all the wonderful pieces of Object Oriented goodness that Ruby does, and most specifically I couldn’t easily tell Bash to spit everything out in an XML file. Besides, this was good practice preparing me for doing production level scripting. To get started, you will need Ruby, so if you are on Ubuntu your life is pretty easy. Just run this command in a terminal:

~$ sudo apt-get install ruby

Now, create a file called listing.rb and put the following in:

Dir.chdir("./")
for i in Dir['**/**']
 puts i
end

You can run this script by doing the following:

~$ ruby listing.rb

This should work exactly as the bash script above did. So whats so great? Lets go on adding a method call that accepts a directory, and allow a user to input the directory they wish to list. Modify your listing.rb file to look like this:

 def search(dir)
   Dir.chdir(dir)
   for i in Dir['**/**']
     puts i
   end
 end
#Start of the script
dir = ARGV.shift
search(dir)

If you are unfamiliar with how Ruby handles command line input, the ARGV variable is an array that stores all the arguments a user can specify. Since this is a Ruby array, the shift method will cause the first argument to be popped off and stored in the variable dir. Moving along, let’s see the output this produces. Remember now that this script requires an input directory to be given. To run it you can enter the following:

~$ ruby listing.rb ./

You should see, again, output that shows at least your listing.rb file, and one entry for every other file in the current directory. In both forms of the script I used the Dir[**/**]. The **/** says to match all files and all folders, so if a directory exists in the folder I specified the script will proceed to list the files and folders in that directory. To get an idea of what I mean, try running this command:

~$ ruby listing.rb /etc

Now that we can list a ton the files, how should we store them? That is a bit more of an intermediate topic for another day. For now we can muck around with the Dir class to limit our output. Try changing the **/** to something else, or using wildcards to match something specific in your folder. Try it out, and let us know what you think!

Continue reading...

Zero Install Allows Installs for Unpriviledged Users

Tue, Jan 20, 2009    (Click to Rate!) Loading ... Loading ...

0 Comments

package icon I recently ran across an interesting application that allows unprivileged users to install programs. While this maybe a good surface idea, the concept and coolness factor runs a little deeper.

The idea behind 0Install is to give the ’standard user’ install privileges without compromising a system if malicious software is installed. While this is cool for the user, it is even cooler for the application developer. As you might know, package maintenance can be both tedious and time consuming, but 0Install offers to ease that by giving you a useful tool to easily deploy your app on any distribution. In other words, instead of needing to be “blessed”, as the author states, “by a distribution,” all you need is a URI to give to your potential user. If the user has 0Install on their system, all they need to do is drag the URI onto the 0Install application, and install. This can be done regardless of distribution, and regardless of the package manager employed by the system.

Of course, the cautious may ask about system security, and rightly so. I mean, it is true we don’t want our less knowledgeable users installing applications that could potentially harm our rather big 100+ user system! Instead of taking one package and making it available to everybody on the box, 0Install protects the system by using that URI as a unique identifier.

In a traditional system, “if one user installs the Gimp from http://evil.com then it might save the executable as /usr/bin/gimp. Another user might run this, thinking it was from http://gimp.org.”

Different from how the traditional system works, 0Install relies on the aforementioned URI to determine which application to run. The user that installed from http://gimp.org will never run the binary from http://evil.com because of that URI protection. Of course, the caching system is also smart enough to be space efficient, and not continue to cache applications of the same URI. These features can greatly increase security and ease of deployment while providing better software for users. The 0Install system supports Linux, FreeBSD, Solaris, and MacOSX (using MacPorts), and offers a tutorial that goes through the explaination of how to convert an existing binary tarball into a 0install feed. Check it out, and let us know what you think!

Continue reading...

QT 4.5 as LGPL

Tue, Jan 20, 2009    (Click to Rate!) Loading ... Loading ...

0 Comments

qt-logoIf you haven’t heard yet, there is good news on the application development platform front. Recently Qt Software, owned by Nokia, announced that the next version of their flagship product, QT 4.5, will be distributed under the LGPL. Prior to this announcement, the platform was free for open source use, while the price of a license for developing a commercial application was in the thousands. This means great things for not only the development platform, but also for the developers seeking to build applications running on multiple operating systems, or even embedded devices.

You can see QT in commercial use by major companies like Google (Google Earth Pro), Netflix (Roku player), and even Adobe (Adobe Elements). It currently supports two languages: C++ and Java, and has an Eclipse plugin for both languages. If you want your new concept or production app to reach audiences on Windows, Linux, and Mac, you may want to consider QT as your platform. You can grab the current 4.5 beta here. Check it out and let us know what you think!

Continue reading...

Ruby 1.9 Quick Speed Test

Sun, Jan 4, 2009    (Click to Rate!) Loading ... Loading ...

1 Comment

It has been a while since I’ve had a chance to play with Ruby, and with 1.9.1 coming out in January I figured I’d go ahead and install 1.9 to get a feel. 

Since speed was always an issue in 1.8 I figured I’d re-run my fib.rb script to find the fibonacci number for 35.  I ran it against ruby 1.8.7 (2008-08-11 patchlevel 72) and 1.9.0 (2008-06-20 revision 17482), the standard versions for Ubuntu Intrepid Ibex.

Here’s that script:

#!/usr/bin/ruby
require 'time'

puts "starting fibonacci"

def fib(num)
 if(num < 2)
   return 1
 else
   return fib(num-1) + fib(num-2)
 end
end

if ARGV[0] != nil
 if (ARGV[0].to_i >= 35)
  puts "This might take a bit...."
 end
 start = Time.now
 puts fib(ARGV[0].to_i)
 stop = Time.now - start
 puts "Finding the fib of #{ARGV[0]} took:"
 puts stop
 puts "seconds"
end

The test machine is fairly old, which makes it a good candidate to see the speed improvements. It is an old 1.8 GHz P4 with 768MB RAM running KDE4. Here’s what I got:

~/Code/fib$ ruby1.8 fib.rb 35
starting fibonacci
This might take a bit....
14930352
Finding the fib of 35 took:
97.311404
seconds
~/Code/fib$ ruby1.9 fib.rb 35
starting fibonacci
This might take a bit....
14930352
Finding the fib of 35 took:
11.752508888
seconds

Now, it is no news that 1.9 is faster than 1.8, but an 8x improvement on this simple recursive script? I was astonished! This is better than using XRuby to speedup Ruby performance!

Continue reading...

Develop using the Play! Framework: The JPA Model

Sun, Jan 4, 2009    (Click to Rate!) Loading ... Loading ...

2 Comments

Play Icon A couple weeks ago I wrote an article on a fantastic framework called Play!. I want to revisit the project I created with the framework and introduce one of the coolest features that Play! has to offer: the use of Persistence through their JPAModel. I’m going to modify the CarLot application (Download ZIP) to use this feature while keeping my existing database in place.

To get started, lets setup the database. If you have Ubuntu, but don’t have MySQL installed run this in your favorite terminal emulator:

~$ sudo apt-get install mysql-server

During the install, it will ask you for a root password, this is what you use to admin your server so choose something you’ll remember. After that finishes, we can create the database. First, download the carlot-sql.zip file to your home folder. Now lets unzip it, and build the cars table:

~$ unzip carlot-sql.zip
~$ mysql -u root -p < carlot.sql

When prompted, use the password you gave during your MySQL install. If you followed along with the first article, and already have the database setup up you will need to make one change. Each row must have a unique, identifiable object so that Hibernate can keep track of them. Currently the cars table doesn’t have this so we will need to add a column that is a BigInt with name Id, not null, auto increments, and is the primary key. You can make this change by getting into a mysql command prompt and issuing an alter command:

ALTER TABLE `carlot`.`cars` ADD COLUMN `Id` BIGINT
NOT NULL AUTO_INCREMENT AFTER `VIN`,
ADD PRIMARY KEY (`Id`);

Note: Keep this step in mind when you are trying to use Play! with an existing database.

Next you’ll need to grab a copy of the Eclipse project file carlot.zip and import it as an existing project into Eclipse. Last, make sure that the Play! framework is in your path (documented in the first post), and now we can begin!

Using the Persistence feature we can change quite a bit of the current code and even remove a whole class from the project, specifically the CarLot class. Initially, that class served as a way of connecting to the database, grouping, and storing a list of cars to be handed over to the view. We can cut this out entirely and let the framework to take care of all database ugliness. Lets get started by removing the CarLot class from the project. Next modify the Car class to look like this:

package models;

// Round 3
import javax.persistence.Entity;
import javax.persistence.Table;
import play.db.jpa.JPAModel;

@Entity
@Table(name="cars")
public class Car extends JPAModel {
	//vars that make a car
	public String make, model, vin;
}

You will see that the Car class now extends the JPAModel giving the class all the necessary properties to be correctly managed. When the Play! framework sees the @Entity annotation it will do all the grunt work of keeping track of the Car objects by starting a JPA EntityManager. Now we can find, update, delete, and a whole lot more to these Car objects stored in the database through that Entity Manager.

Since we are working with a pre-existing database, I had to specify the @Table(name=”cars”) annotation to tell the framework which table we are working with. Had I not specified the annotation, the Play! framework would have modified the CarLot schema to have an extra table called Car (assuming the username specified in the application.conf file had sufficient authorities).

Moving along, we will now need to modify the Application class to look like this:

package controllers;

import play.*;
import play.mvc.*;
import play.libs.*;
import java.util.*;
import models.Car;

public class Application extends Controller {

	/**
	 * Default action.
	 * renders the app/views/Application/index.html template
	 */
	public static void index() {
	    List cars = Car.findAll();
	    render(cars);
	}
}

Now, in your project open up the eclipse folder, right-click on CarLot.launch, and select Run As CarLot. You can access your page at http://localhost:9000, and should see something similar to this:


Carlot Dialect Exception

We forgot to tell JPA that we are using the MySQL dialect. Open up your Application.conf file in the conf/ folder and uncomment the jpa.dialect=org.hibernate.dialect.MySQLDialect line:

# JPA Configuration (hibernate)
# ~~~~~
#
# Specify the custom JPA dialect to use here (default to guess) :
 jpa.dialect=org.hibernate.dialect.MySQLDialect

Stop the server by clicking on the terminate button in Eclipse, and re-run the application by right-clicking on the CarLot.launch file and selecting Run As CarLot. You should now see something like this:


CarLot Successful Run

In under 35 lines of code (mostly auto-generated, and including comments!) we were able to connect to an existing database, grab values, display those values, and all without even seeing database connection code. If this doesn’t get you excited, I doubt much will. The Play! framework is very impressive, and far exceeds the declaration of “mak[ing] it easier to build Web applications with Java”. Check out Play! and let us know what you think!

For your reference, the Eclipse Project file is available.

Continue reading...

SmugMug Java API Download Links Fixed

Mon, Dec 29, 2008    (Click to Rate!) Loading ... Loading ...

0 Comments

Guys, sorry for the SmugMug Java API Download links being broken for a bit, I did an upgrade and forgot to update the paths. All the download links have been fixed.

Thanks for using the API!

Continue reading...

Develop using the Play! Framework

Wed, Dec 17, 2008    (Click to Rate!) Loading ... Loading ...

4 Comments

Play IconNot too long ago I posted an article on the Play! framework. The framework has some promising features that really helps develop web applications in Java. To show how easy it is to use, I wanted to demonstrate with an example.

Update #1: Since the article posting there have been a couple of suggestions for updating the tutorial to further take advantage of Play!’s features. I have updated the article to reflect those changes, and wanted to thank you those who sent in the suggestions!

Update #2: After finishing this article, you may want to check-out the followup article on how to use an even smaller JPA-enabled model to lessen the DB legwork even further.

For the example I will use a database, CarLot, that contains 3 cars stored with their make, model, and VIN. What I want to do is connect to the database, grab the cars, and simply display them in a standard html table. I will need to create a Model to grab the cars, and modify the Controller to tell what the view should render. Lastly, I’ll modify the view to show how to display the car objects.

To begin this example you will need an existing mysql installation and the jdbc driver which you can get on Ubuntu by issuing the following command:

~$ sudo apt-get install mysql-server libmysql-java

The setup script that runs during the installation will ask you for a root password. You can use whatever you like, but in practice it is more secure to use a password different from that of your superuser.

Now, create a new file called carlot.sql and put this in it:

CREATE DATABASE IF NOT EXISTS carlot;
USE carlot;

DROP TABLE IF EXISTS `carlot`.`cars`;
CREATE TABLE  `carlot`.`cars` (
  `Make` char(20) default NULL,
  `Model` char(20) default NULL,
  `VIN` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

LOCK TABLES `cars` WRITE;
INSERT INTO `carlot`.`cars` VALUES
 ('Ford','Ranger',123456789),
 ('Nissan','Altima',123456790),
 ('Toyota','Corolla',123456791);
UNLOCK TABLES;

You can then use this file to create the needed database by running:

~$ mysql -u root -p < carlot.sql
Enter password: <password specified during install>

Next we’ll need to install the Play! framework. Grab a copy from the download site and then run the following in a terminal (with the assumption that you downloaded the zipped file to your home folder):

~$ unzip play-1.0-stable4.zip
~$ sudo mv play-1.0-stable4 /opt/play

To make the framework executable without specifying the full path we’ll add the play directory to the environment path. You can do this by editing your /etc/profile as a superuser and adding the following line to the bottom:

export PATH=$PATH:/opt/play

Then run:

~$ source /etc/profile

The ‘play’ executable should now be in your path, and ready to run. We can finally create our project. Do this by running this:

~$ play create car-lot

This will create our project’s folder structure and configuration files in ~/car-lot. To make it easier to reference in the article, I will use <car-lot> to specify that newly created project directory.

Lets move on to the code starting with the Model. There are two parts to the model in this project: the Car object and the CarLot object. The Car object will have 3 private variables (make, model, and vin) that will be accessible through accessor methods. The CarLot database will be responsible for grabbing information from the database, and putting that information into a usable form (a Car object). Keeping these separate will allow us to expand in the future (like adding more features to a car or adding different tables to the CarLot database) without breaking the current application.

Go ahead and create a file called Car.java in your <car-lot>/app/models/ folder and add the following to it:

package models;
public class Car {

	//vars that make a car
	public String make, model, vin;

	public Car(String make, String model, String vin){
		this.make 	= make;
		this.model	= model;
		this.vin 	= vin;
	}
}

If you notice, this code doesn’t have the standard accessors (commonly referred to as getters and setters). You might even ask yourself why? If that’s the case you’ve just noted one of the cool features of Play! called Properties Simulation. This Properties Simulation is a great way to keep code clean without sacrificing the usability. You have full access to your variables without having to write superfluous code.

Moving along, create another file called CarLot.java inside your <car-lot>/app/models/ folder with the following:

package models;
import java.sql.*;
import java.util.ArrayList;
import models.Car;

public class CarLot {

  public static ArrayList getListOfCars(){
    ArrayList cars = new ArrayList();
    Connection connection = null;
    Statement statement = null;
    ResultSet resultset = null;

      try {
        Class.forName("com.mysql.jdbc.Driver").newInstance();
        connection = DriverManager.getConnection(
                     "jdbc:mysql://127.0.0.1/carlot",
                     "user", "secret");
        statement = connection.createStatement();
        statement.executeUpdate("USE carlot");
        statement.executeQuery("SELECT * from cars");

        resultset = statement.getResultSet();
        while(resultset.next()){
	  cars.add( new Car( resultset.getString("make"),
                             resultset.getString("model"),
                             resultset.getString("vin") ) );
        }
        connection.close();
      }
      catch(Exception e){
        System.out.println("exception: " + e.toString());
      }
      return cars;
  }
}

Your Model for accessing the database is complete. Of course, though, there is another way of approaching this. The authors of Play! took database access into consideration, most especially due to models needing to store and retrieve data. The default project configuration file (conf/application.conf) has a special section for database configurations:

# Database configuration
# ~~~~~
# Enable a database engine if needed.
# There are two built in values :
#   - mem : for a transient in memory database (