Tuesday, December 04, 2007

genpet

24-year old Canadian commercial artist Adam Brandejs has fooled me too with his latest atrwork, the genpets! Genpets are supposed to be the creation of Bio-Genica, by combining and modifying existing DNA, and are portrayed as real living pre-packaged, mass produced, bioengineered pets, with blood, bones, muscle, who will bleed if you cut them and die if mistreated. You may find all about his creation on his site, together with the what, why and how. The main point of Genpets is to get the public thinking about the concept of bioengineering. Previous works of art included the flesh shoe and the animatronic heart.

Saturday, December 01, 2007

gpg

I have used GnuPG, the most well-known open-source implementation of OpenPGP standard, to create my public key in PGP ascii-armoured format (RFC2440):

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.7 (MingW32) - GPGshell v3.63

mQGiBEdJwaoRBACGOLGMcEZvvVoLILK/u8MlEttmZgriE/kh/J4KU7Vq1X2aPqYO
IL19VtHKRzQLpk9sAJK51tUbdDRQAm7A0nkkgHZYFfTLY1a9UYUamx3xgtqQ/aWf
kdeqazc2iOv1WcfaDZruLq5I6CY1BB+naUnlDw1q/4icxBaXy5cATGG/4wCghlVQ
fjutAS44UD/w9WpMWAFiUT8D/ijZI1aoyNzHt1pPgJzu63Q8mOM/5WLXtvIFhseN
Yn5jHQBbZvbz/qLN+A04TOS6ZJeiOb7u3sBinM5HxtwFsL/8R7fX9KDtv/0XeCpC
jJxrkhid3Xa6PdVku121RarbXCVjU2J/emsfM7+M5KzkAMqttCVlOQ1B10wxaKoJ
h37jA/9tY8KfDURirg0MIByMVXqeAy/pjB7y+VbTUynzGOXzjMvpFSXeq5mUQrQa
5wfD6g/bsqREQRgSgRi/5zdQJ3kTwAC/9ia1V37iRDVMcWd177t+NnkMuHh/EQRr
BRFyh6Ahw+uE+DYGzipHrTjbzIbmbx9lprK0a0qc5rp5SJhvj7Q7VmFzc2lsaXMg
TWljaGFsaXRzaXMgKEdQRyBwdWJsaWMga2V5KSA8em1lZWFnYWluQGdtYWlsLmNv
bT6IYAQTEQIAIAUCR0nBqgIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEApn
iDzXc29ZJrwAn35i7EU/sOhGyMd2qWdYLhXLn0NPAJ4s7yy2FivfsFs3zOppzF/S
mF7qybkCDQRHScGqEAgAsLjOBlN54y75Vkjkj/Gw0X6vy0nj1SZtQDTef8ZF2oYQ
FX0+KgiR+v9Jgu39GTO6adWwga8DXBHwx+72yMiKh7mnd1p2ppuaGzUos0Vj0WJt
lnPXmpmjahWc5NEO/svWEU1OaNPp70OqY3y7k72PmWZU1CGvw+CBe2herFf+1R5T
or6sq31xfuGLW6MSwj2Tf00SeezK0lVZSOfrVHjWj5VQ6cevExEexWi6idU29Hrk
MZ8JfIEE3qPcPBX30s2NrzLU24eFVczv3CRNsGHUdNAsauwpkheycnMvrdGE7yBo
hkEQ08FROsp/RkbcqbKCczoW09Qc+kVr0SDsidLRDwADBQf/folYqDxqrzmGc2vQ
FisWIWMaPp6P602vtTr6CkICEpuWs10aCQCvHWyhS9rv0/ycbPV9F/HLT9JPAwD3
G60wuzzLbqTlFVxhzSORmmN92t0Xe0tBJa7TbuCJ6j5WfdvskopCC2BGhNJnxZbD
gBjrWGOE+dOJY7B/W8NyPerfcS7RIk5YtwP3uIfPiBwSf+75ToiquXqUkFlnA+LY
6aVyr6KHDk/OuV4rKZJdu8JikZkK5H48v9UK/k5WTQPQJhOP7QdfQa70/yz+Zksb
XgyF8YIgFjUKxcHexh2+wWsbeK4A53XdtyY+JFLApZFywE7u+DZQ721PYTMKVYb+
GpxvaYhJBBgRAgAJBQJHScGqAhsMAAoJEApniDzXc29ZQJsAn0MkgLNZOocsb8KZ
0W6yyu1yP4xDAJ41P01c3jmDH/2sNN/+xbjOaF38lg==
=JM2U
-----END PGP PUBLIC KEY BLOCK-----

You may find it in MIT's public PGP key server and as if that weren't enough, it can also be found here, here, here, here, and here. To import it into your keyring save it in a text file, say zmeeagainpk.asc, and then type:
gpg --import zmeeagainpk.asc
gpg: key D7736F59: public key "Vassilis Michalitsis (GPG public key) <zmeeagain@gmail.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1
As an example let's take the following snippet of text:

The Armor Headers are pairs of strings that can give the user or the receiving OpenPGP implementation some information about how to decode or use the message. The Armor Headers are a part of the armour, not a part of the message, and hence are not protected by any signatures applied to the message.

I have clear signed it using my PGP key and the result is:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The Armor Headers are pairs of strings that can give the user or the receiving OpenPGP implementation some information about how to decode or use the message.  The Armor Headers are a part of the armor, not a part of the message, and hence are not protected by any signatures applied to the message.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32) - GPGshell v3.63

iD8DBQFHUrdQCmeIPNdzb1kRAksZAJ0cOJSKNwkkGmTyQDR4sf39Kl5XgQCffsCu
HpMVh4lnKcq0xmKvc9XA7IU=
=TFRB
-----END PGP SIGNATURE-----

To verify the signature, select this clear signed text, including the armour headers, and save it as signed-text.txt. Then type
gpg --verify signed-text.txt
gpg: Signature made 12/02/07 15:46:56 using DSA key ID D7736F59
gpg: Good signature from "Vassilis Michalitsis (GPG public key) <zmeeagain@gmail.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 426B D59A 9798 E07A 88F8  9647 0A67 883C D773 6F59
Notice that GPG complains that the signing key may not belong to the actual owner. You have to add the newly imported public key to your trusted keys, i.e. the keys you know they come from who they were supposed to, by signing it with your own key:
gpg --edit-key D7736F59

pub  1024D/D7736F59  created: 2007-11-25  expires: never       usage: SC
                     trust: unknown       validity: unknown
sub  2048g/61B55FAD  created: 2007-11-25  expires: never       usage: E
[ unknown] (1). Vassilis Michalitsis (GPG public key) <zmeeagain@gmail.com>
Command> sign

pub  1024D/D7736F59  created: 2007-11-25  expires: never       usage: SC
                     trust: unknown       validity: unknown
 Primary key fingerprint: 426B D59A 9798 E07A 88F8  9647 0A67 883C D773 6F59

     Vassilis Michalitsis (GPG public key) <zmeeagain@gmail.com>

Are you sure that you want to sign this key with your
key "..." (...)

Really sign? (y/N) y

You need a passphrase to unlock the secret key for
user: "..."
... key, ID ..., created ...
Verifying signed-text.txt should not display a warning anymore:
gpg --verify signed-text.txt
gpg: Signature made 12/02/07 15:46:56 using DSA key ID D7736F59
gpg: Good signature from "Vassilis Michalitsis (GPG public key) <zmeeagain@gmail.com>"
Among the various GPG GUIs GPGShell is perhaps the most comprehensive and it is the one I am using for the examples here.

Friday, November 23, 2007

disqus

I decided to give Disqus a try and replace Blogger's default commenting system. I have kept a copy of my old template just in case, as Disqus is very much in beta version right now. Not that I get a lot of comments anyway...

Monday, November 05, 2007

concurrency

An awesome book on concurrency that all Java programmers ought to read before embarking on anything more complicated than the primordial Hello World application. I cannot help but reiterate here an example on one of my favourite subjects, that of publication safety. A typical (yet unsafe) lazy initialisation is shown below:


public class LazyInitialization {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();
        return resource;
    }
}
There's two issues with this approach. The first is easy to spot: if threads A and B call getInstance() at the same time, they may both see resource as null and both proceed in creating a Resource instance, hence ending up creating two different instances even though getInstance() is supposed to always return the one and the same instance.

The second is much more subtle and has to do with publication. Suppose that thread A first invokes getInstance() and creates a Resource instance, then thread B sees that resource is non-null and returns the resource reference. B could observe however the write to the resource reference by A as occurring before writes to resource's fields by Resource's constructors! Hence, B could see a partially constructed Resource. One way this can be fixed is by making getInstance() synchronized. Another way is by changing the lazy initialization to eager:


public class LazyInitialization {
    private static Resource resource = new Resource();

    public static Resource getInstance() {
        return resource;
    }
}
Why does this work? Static initializers are run by JVM at class initialization time, i.e. before any thread has the chance to use the class. In addition, JVM acquires a lock while doing so, and this same lock is acquired by every thread at least once to ensure that the class has been loaded, therefore all memory writes made during initialization are visible to all threads. Any subsequent modifications will need to be synchronized of course between readers and writers, unless Resource is immutable.

Saturday, October 20, 2007

picnik

Picnik IS the best online photo editor around. Simple, intuitive, rich, blazing fast. I was very glad to hear that Flickr will incorporate picnik's amazing functionality for photo editing. At last I shall be able to make my Flickr sets look more presentable.

Thursday, August 23, 2007

FindBugs

Inspired by Josh Bloch and Bill Pugh's Java Puzzlers talk at Google, Java Puzzlers, episode VI, I decided to use FindBugs and analyze some core Java libraries we wrote and used at one of my previous employments. Here are some of the findings: Commons: 675 classes, 505 bugs (98 bad practice, 27 correctness, 96 malicious code vulnerability, 14 multithreaded correctness, 207 performance, 63 dodgy). Messaging: 31 classes, 21 bugs (9 bad practice, 8 malicious code vulnerability, 3 performance, 1 dodgy) Services: 239 classes, 78 bugs (5 bad practice, 4 correctness, 35 malicious code vulnerability, 1 multithreaded correctness, 26 performance, 7 dodgy) Content management: 637 classes, 577 bugs (38 bad practice, 14 correctness, 72 malicious code vulnerability, 3 multithreaded correctness, 382 performance, 68 dodgy)

Example bugs include:

Bad attemnpt to compute absolute value of signed 32-bit hashcode:

indexPrimary +=  Math.abs(this.getStoragePrimary()
  .hashCode()) + SEP;
Why? If the hash code is equal to Integer.minValue() then the result will be negative as well.

Impossible cast (ouch!):

ArrayList list=new ArrayList();
setChoices((DateDatum[])list.toArray());
Possible null reference dereference for internalConnetion:
try {
  if(internalConnetion == null) {
    throw new TransactionManagerException("...");
  }
  ...
  } catch(Exception e) {
    throw new TransactionManagerException(
      e.getMessage(), e);
  } finally {
    if (internalConnetion.getDepth() < 1) {
Nullcheck of value previously dereferenced:
if (accountId.equals(internalAccount)) {
  permissions.add(new AllPermission());
  return permissions;
}
if (accountId == null) {
  return permissions;
}
This last comparison for null is redundant since, if true, it would have already raised an exception.

Method invokes inefficient Boolean constructor:

return new Boolean(false);
Boolean objects are immutable, there's no need to create a new instance; use Boolean.valueOf(...) instead.

Method invokes inefficient new String(String) constructor:

String path = new String("");
Method concatenates strings using + in a loop:
for(int i = 0; i < (hash.length / 2); i++) {
  rtnValue += Integer.toHexString(x);
}
Inefficient use of keySet iterator instead of entrySet iterator:
Set keySet = headers.keySet();
Iterator iterator = keySet.iterator();
while(iterator.hasNext()) {
  String value = (String) headers.get(key);
}
May expose internal representation by incorporating reference to mutable object:
public void setMethods(Hashtable methods) {
  this.methods = methods;
  FunctionsContainer.getLogger().info("Loaded " +
    methods.size()+" methods");
}

This code stores a reference to an externally mutable methods object into the internal representation of the object. Storing a copy of the object would have been much safer.

It's always a good idea to statically analyse your code once you're done with it. It's not going to render it bug free but it certainly helps. Oh, and while I'm at it, go get yourself a copy of Java Puzzlers book; it helps avoiding some very dark corners you might not have been aware of.

Sunday, August 19, 2007

xkcd

A webcomic of romance, sarcasm, math, and language by Randall Munroe. Check it.

Friday, August 17, 2007

parkour


I didn't know that parkour was so popular until I saw the video above. This is a short definition from Wikipedia:

Parkour (sometimes abbreviated to PK) or l'art du déplacement (English: the art of displacement) is recreational activity of French origin, the aim of which is to move from point A to point B as efficiently and quickly as possible, using principally the abilities of the human body.

Astonishing eh? Now my traceurs, summon your spidery powers and displace yourselves!

Tuesday, August 14, 2007

cURL

If you are not already using it, I suggest you start using cURL. cURL, or Client for URLs, or see URL comes in two flavours, a command line tool for getting and sending files using URL syntax and a library, libcurl, for use by other programs. It supports more than a dozen protocols (FTP, FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE, LDAP), cookies, proxy tunneling, transfer resume, authentication (Basic, Digest, NTLM, Negotiate, kerberos...), SSL certificates, HTTP uploads, progress meter, speed limit, you name it. Here's some examples:

Upload a file as multipart/form-data plus extra params to a URL: curl -F upload=@localfilename -F press=OK [URL]

Use an agent of your choice: curl -A "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" [URL]

Get the last 500 bytes of a document: curl -r -500 http://www.get.this/

ftp upload through a proxy: curl --proxytunnel -x proxy:port -T localfile ftp.upload.com

Read and write cookies from a netscape cookie file: curl -b cookies.txt -c cookies.txt www.example.com

Download resume: curl -C - -o file http://www.server.com/

cURL is in Flash Player 9, Mac OS X, F-Secure and IBM's BOINC among others. Interfaces exist for most major as well as other more obscure languages. Unfortunately, the javacurl interface supports a small subset of cURL's features and is not well tested.

Friday, August 10, 2007

cloning adventure

Once I wanted to create clones of tree nodes, naming the clones of node say A as A-Copy-1, A-Copy-2, etc. My first thought was using the parent's child-count property and start counting copies from that value onwards. However, if the nodes are A, A-Copy-1 and A-Copy-2, when A-Copy-1 gets deleted the child-count becomes 2 and if that is used you get the same name as one of the existing children. Then I thought I would simply iterate through all children named A-Copy-i, for i = 1 to child-count, and create clones whenever that name was for take. That would reuse slots created by previous deletions but would make distinguishing the new nodes impossible. This was easily fixed by finding the maximum copy count of A and start creating clones after that so, if A-Copy-4 and A-Copy-6 sibling nodes are left in the tree, any new copies would be named as A-Copy-7, A-Copy-8 etc. That way you would always get a nice continuous set of cloned nodes in the tree. Even if you wanted to clone A-Copy-i node, that would quite naturally become A-Copy-i-Copy-j. I decided to use regular expressions to look for <node name>-Copy-<copy count> sibling nodes. That gave the extra benefit of having the copy count part available by means of a capturing group. To force any metacharacters in the node name to be treated like ordinary characters, I preceded every single character in the name with backslashes:

StringBuffer escapedNodeName = 
  new StringBuffer(nodeName.length()*2);
for (int i = 0; i < nodeName.length(); i++) {
  escapedNodeName.append('\\').append(nodeName.charAt(i));
}
RE exp = new RE(escapedNodeName.toString() + "-Copy-([1-9]\\d*$)");
This failed miserably! Guessed why? It is quite alright to escape a metacharacter, but it is another kettle of fish when "escaping" ordinary characters. When this code was used on a tree which had numbers in names, the escaped digits became backreferences and the match failed. I hastily changed the escaping part of the code to enclose the name within a quote (\Q and \E). No sooner had I done this than I realised that even that had its own fallacy: what if the node name had a \E in it? Proper quoting required some more effort:
StringBuilder escapedNodeName = 
  new StringBuilder(nodeName.length() * 2);
escapedNodeName.append("\\Q");
slashEIndex = 0;
int current = 0;
while ((slashEIndex = nodeName.indexOf("\\E", current)) != -1) {
  escapedNodeName.append(nodeName.substring(current, 
                                            slashEIndex));
  current = slashEIndex + 2;
  escapedNodeName.append("\\E\\\\E\\Q");
}
escapedNodeName.append(nodeName.substring(current, 
                                          nodeName.length()));
escapedNodeName.append("\\E");
Thankfully this is made available as java.util.regex.Pattern.quote(String) method since Java 1.5.