2009-11-15

Making Windows a better place to be

Many developers including me are forced to use Windows at work due to various corporate reasons even when our work has nothing to do with Microsoft technologies. And we are all stuck with that terrible Command Prompt or a Power Shell which are crap compared to a proper terminal. However, there is a way to have a fully functional Unix terminal in Windows thanks to Cygwin and a patched version of Putty

I am doing this for several years and this is one of the first things I do in any Windows machine that I want to do some software development on, so it's time to come up with a little tutorial.

Setting up Cygwin and PuttyCyg

Getting Cygwin

Go to http://www.cygwin.com to download and run the setup.exe. Installation process is illustrated in screenshots below.
 


I suggest you installing cygwin directly to C:\cygwin as it's recommended. It's a significant part of your system and it is really worth the place in C:\ directly.



Cygwin offers "C:\Windows\System32" as a place for local packages, however I don't like that idea and keep it all under "C:\cygwin".


Some mirrors were failing for me with missing packages so I choose a respectable source and deal with slower download speed in exchange for reliability.



Choosing packages may take a while. You can go with default selection, however going through the long list is worth a while if you want to have goodies like vim, curl, ping, openssh, mc and so on.


Now go make yourself some coffee.


Don't add any icons or shortcuts because they open cygwin in that ugly command prompt we are about to get rid of.


Introducing Cygwin to your Windows

Now that you have the Cygwin, try it out by launching C:\cygwin\cygwin.bat. You will see something like this.


As you can see, a few files can be modified to configure your environment. Keep them in mind for future:
  • ~/.bashrc
  • ~/.bash_profile
  • ~/.inputrc

Now append these to the beginning of your Windows PATH environmental variable:

C:\cygwin\usr\local\bin;C:\cygwin\usr\bin;C:\cygwin\bin;



Run a fresh Command Prompt (if you are using Launchy or a similar program to run the cmd.exe, you have to restart it before the new PATH applies to programs you run.) and you will be able to do the following:


That's just a small benefit you get from cygwin, but it's handy to have unix commands anywhere in the system. If you think that cmd.exe is enough to enjoy unix commands, you are wrong. It fails to resize properly, it's hard to copy and paste. Compare using Putty with a remote machine to using Command Prompt on your local Windows box, It's like day and night.

Getting PuttyCyg

Get the latest puttycyg from http://code.google.com/p/puttycyg/. For the past year it's this one: http://puttycyg.googlecode.com/files/puttycyg-20090811.zip. You can put it in c:\cygwin\puttycyg to avoid a mixup with the original Putty if you use it.

Configuring PuttyCyg to access local cygwin

Create a shortcut to putty.exe from the puttycyg pack that you just extracted.


Run it to configure the local connection. Check "Cygterm" in Connection type and enter a minus (-) in Command.


Be sure to go to Window configuration and set Lines of scrollback to something more reasonable than the default 200.


Save the settings. Name the session "localhost".


Now click "Open" to test the configuration. You should see a working terminal.


You can now enhance the shortcut you created earlier to load the "localhost" session automatically. Just append "-load localhost" to the end of Target.


You're all set. A few resources to get you familiar with Cygwin:

2009-10-28

REST fan types

While looking up some information about REST and RESTful services I've encountered a pretty amusing forum post that defines REST fan type hierarchy. Let me share the smile:

API Makers: I find them everywhere. They have a system, usually not built thinking on REST, and they want an API created. They usually think REST is an API making technique or recipe, for the web.
 - URI Jugglers. This are the ones that think REST is all about creating URIs, and nothing more. So their discussions are solely focused on URIs, and their presentations are about URIs definitions.
 - RPCers. Bad group that think REST is a way to map RPC in disguise using URIs in a web API. The most of them don't know they speak RPC at all.
 - Exposers: This type is repeated below. Those are the guys that think you need to expose things in REST using resources. So REST is an API for exposing things on the web.
 - CRUDers: Another repeated group. They think REST is a web api for CRUD. Simple.

Mappers: This other category may use the API idea, but they actually thing REST is a representation type and the work to be done is to map all that is know used to that new type. Interesting?
 - CRUDers. Again, the idea is that CRUD can be mapped naturally to HTTP operations, and that makes it RESTful. 
 - HTTPers. They believe REST is HTTP. Deep enough.
 - Exposers. Again too. They usually try to map all classes, data entities, elements into resources, and then call their systems RESTful.

FAD followers: This is a group of the reminders of the types. Usually, they tend to follow a lead.
 - Standard Haters: Here you have all those that think Standards are evil and that REST is an anarchy where you have the freedom to do whatever you like, so they follow REST doing whatever they want.
 - KISS lovers: This are the ones that like thinks to be simple. And someone told them REST is easy, so they follow doing easy things with URIs. There are lots of URI jugglers in this group.
 - Servicers: They think Services is good, and someone told them REST is a way to do services without SOAP. So they follow.
 - BuzzWorders: This is a vast majority. They like buzz words, so they follow REST just because it is cool and all people talk about it. There are some Buzz creators too, with thinks like ROA and REST in WOA. No pun intended on REST-*.

That post has a missing type - the ones that properly understand and use REST. Perhaps there is no such group of people? And I guess the main reason for that is because REST is a style, not a standard. Yes, I am the Standard Hater. :)  

2009-09-29

XML processing in Java

One of the things that most Java developers tackle on daily basis is dealing with XML. Despite the fact that XML is taking lots of criticism and new formats like YAML are emerging and becoming more popular, you cannot avoid XML it's too widespread and used everywhere. It's the main format for interchanging data across systems and even people. There is a great deal of fat books that show how to use various XML APIs and libraries to handle the beast with all it's standards and extensions. There are many solid tools that had been continuously developed for years by large communities (Xalan, Xerces, JDOM, DOM4J).

And still XML processing in Java is still a major pain in the ass.
I see two reasons for that: 
  1. XML is too bloated as a format. See the picture below (click to enlarge):
  2. Java libraries that deal with XML are bloated. It's natural because they simply try to implement the specifications

Let's say you have a Java application which receives some data in form of simple XML:

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <entry id="1">entry number one</entry>
<entry id="2">entry number two</entry>
</data>
Your application has this class:

public class Entry {
private int id;
private String content;
//the usual setters and getters here
}
If you would want to parse this XML with Java, into Entry objects you would usually do something like this:

try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("data.xml"));
NodeList nl = doc.getElementsByTagName("entry");
for (int i = 0; i < nl.getLength(); i++) {
Entry entry = new Entry();
entry.setId(Integer.parseInt(nl.item(i).getAttributes()
.getNamedItem("id").getNodeValue()));
entry.setContent(nl.item(i).getTextContent());
System.out.println(entry);
//do real stuff
}
}
catch (final Exception e) {
System.out.println("Failed parsing: " + e);
//do real handling
}
Expected output:

Entry:{id: 1; content: entry number one}
Entry:{id: 2; content: entry number two}
In Java 6 DocumentBuilderFactory.newInstance() will usually return an instance of this implementation: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl 
This is Xerces embedded into the JRE. What's wrong with that? First, it's a huge library with big memory footprint. It will be outdated in comparison with what you can get at the official homepage, so if you want to go for the latest version with all the bug fixes, you will have to add another megabyte of jars to your project, set a system property (javax.xml.parsers.DocumentBuilderFactory) to change the default implementation and hope your code works. Then you have to know DOM. You have to use an ugly for loop to iterate the results instead of doing it right (for (Node n : doc.getElementsByTagName("entry") { ... }).
Even though Java aims to be loosely coupled, you can use the API and switch implementations, you should keep in mind that API changes over time, and implementations work differently. I have seen legacy code where you can find sick things like DocumentBuilderFactoryImpl = (DocumentBuilderFactoryImpl) DocumentBuilderFactory.newInstance();, I have seen Axis failing to parse complex SOAP messages after switching to different, newer JDK, I have seen third party software vendors who start cursing when you change your web service implementation and your WSDL is generated with minor cosmetic differences (i.e.: xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" instead of previous version: xmlns:s="http://schemas.xmlsoap.org/wsdl/soap/"). In all these cases APIs and implementations failed to do what they were meant for. Of course, everything can be fixed, but it takes time and nerves, and these things are precious.
XML processing in Java is terrible, and the worst part is when you have to go through all this just to parse a simple piece of data. Why couldn't it be as simple as that:

for (XmlSlicer piece : XmlSlicer.cut(data).getTags("entry")) {
//each piece is: <entry id="...">...</entry>
Entry entry = new Entry();
entry.setId(Integer.parseInt(piece.getTagAttribute("entry", "id")));
entry.setContent(piece.get("entry").toString());
System.out.println(entry);   
//do real stuff
}
After being fed up with Java's great XML APIs and libraries I made a small tool for simple daily work with XML files.
The code above would work in XML Zen - a small and lightweight XML processing library that supports ~1% of what other XML processing libraries can do, however this 1% of functionality is what you use 90% of the time. There are no big APIs, just simple logic driven object oriented processing of XML strings. And it's just a little over 10Kb.
You can add XML Zen dependency with Maven, just set the dev.java.net repo first:

<repositories>
<repository>
  <id>maven2-repository.dev.java.net</id>
  <name>Java.net Repository for Maven</name>
  <url>http://download.java.net/maven/2</url>
  </repository>
  <!-- other repositories -->
</repositories>
Then the dependency:

<dependency>
    <groupId>com.googlecode.xmlzen<groupId>
    <artifactId>xmlzen</artifactId>
    <version>0.1.1</version>
</dependency>
That's it, you are ready to go. And when it comes to building XML and XML Zen is not enough for your needs, check out this great project: http://java.ociweb.com/mark/programming/WAX.html.

2009-08-18

MacBook Disassembly

A few months ago my MacBook finally died.

I will never buy a Mac again. Although I loved OS X, the hardware is terrible and heavily overpriced. My MacBook had bluetooth adapter and motherboard replacements in the first year of use, and it didn't really help. Then the warranty period was over and I used the all-broken-no-bluetooth-randomly-freezing-hard-drive-randomly-unavailable MacBook for another painful year untill one day the screen went black and never went back...

Here is a slideshow with my little MacBook disassembly project.



A month later I've bought myself a Dell Studio 1537 (with 3GB of RAM, 1440x900 screen and 3 years of warranty).

After installing Ubuntu 9.04 all I missed from MacBook was two finger scroll, which can be easily enabled anyway.

Too bad I'll have to discontinue Hawkscope for Macs, unless someone is willing to join the development and perform the builds. Anyone?

2009-06-17

A tool for unpacking multiple archives and other ramblings

I've always wondered why torrents are packed into multiple archives, sometimes even archives inside other archives. Anyway, I've got fed up with all the unpacking routines, especially after downloading several seasons of something that has each episode in an individual folder containing 20 rar or zip files. So, after one evening of coding this nightmare is now over.

Here is the screenshot of the stupidly named tool (click to visit project page):


It was also a good reason to try out new version of NetBeans. I still hate GUI builders, however for small "write and forget" kind of projects like Multi Unpacker it's a fairly good choice. However NetBeans is still slow and unresponsive in comparison with Eclipse.

So far Multi Unpacker is for Windows only, however it's a spare evening away from becoming cross-platform (and you are welcome to join the project). Too bad my MacBook broke down completely, so Macs will most probably not get any special treatment... This is also bad news for Hawkscope, unless someone is willing to donate me an old Mac? :)