Even a chimp can write code

Sunday, September 26, 2004

VeriSign's conflict of interest creates new threat

From Financial Cryptography: "...a world of Internet wire-tapping is a reality. The real conflict of interest here is in a seller of certs also being a prime contractor for easy breachings of certs."

I came across this insightful article (via Ross's Random Bytes) that talks about VeriSign's uncomfortable position as provider of SSL, .com and .net domain registrar and its Internet wiretapping operations.

Update: One might argue that the title of this post tends towards being alarmist. The intent of this post is to make aware, not to alarm. I retained the title from the original post as common etiquette demands.

As a law abiding member of the community, one will concede that law enforcement agencies must have avenues to summon privately held information on an entity in special cases. But that begs the question: does this extend to law enforcement agencies in repressive regimes as well? Does the junta in Burma or the government in China have powers to influence VeriSign or an analogous entity or even popular search engines to provide information on purported dissidents?

It brings to mind this timeless statement on liberty by John Stuart Mill, written over 200 years ago:

The dictum that truth always triumphs over persecution is one of those pleasant falsehoods which men repeat after one another until they pass into common places but which all experience refutes. History teems with instances of truth put down by persecution. If not suppressed forever, it may be thrown back for centuries [...] Men are not more zealous for truth than they often are for error and a sufficient application of legal or even of social penalty will generally succeed in stopping the propagation of either. The real advantage which truth has, consists in this: when an opinion is true, it may be extinguished once, twice or many times, but in the course of ages, there will generally be found persons to rediscover it until someone of its reappearances falls on a time when from favorable circumstances it escapes persecution until it is made such head as to withstand subsequent attempts to suppress it.

I have no answers. Only questions.

Email this | Bookmark this

Wednesday, September 22, 2004

The latest gossip on java.util.Properties

The ubiquity of the Properties class is testament to its utility. It is a rare application that does not use an instance. I notice from the J2SE 5 javadocs that the java.util.Properties now supports an XML file -based backing store, leading to the addition of new methods:



public void storeToXML(OutputStream os, String comment)
throws IOException;

public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException;

public void loadFromXML(InputStream in)
throws IOException,
InvalidPropertiesFormatException;



that work off of an XML file with the schema:


<?xml version="1.0" encoding="UTF-8"?>
<!-- DTD for properties -->
<!ELEMENT properties ( comment?, entry* ) >
<!ATTLIST properties version CDATA #FIXED "1.0">
<!ELEMENT comment (#PCDATA) >
<!ELEMENT entry (#PCDATA) >
<!ATTLIST entry key CDATA #REQUIRED>

which in turn looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>some comment</comment>

<entry key="key1">value1</entry>
<entry key="key2">value2</entry>
<entry key="key3">value3</entry>

</properties>


Now this is interesting. Purists -- in this case I fall into that category -- would argue that the simplicity of the key=value properties structure is the source of its strength and popularity. I do not see too much value in the XML form. The Java Preferences API hasn't gained much acceptance and the use of a totally different XML schema in the Properties class doesn't help that cause any.

And when are these deprecated methods going to be removed from the core Java source anyway? You know how we've always been instructed against catching exceptions but doing nothing about it (i.e. an empty catch clause)? Well the save method in the Properties class does exactly that. Take a look:



public synchronized void save(OutputStream out,
String header) {
try {
store(out, header);
} catch (IOException e) {
}
}


To Sun's credit, this method has been deprecated for a while, with developers advised to use the more proper store method. There're a number of deprecated methods in Java and we still have no idea when these will be dealt with (see Bug 5093875). Oh, well that one's for another day.

Email this | Bookmark this

Saturday, September 18, 2004

Concurrent modification of collections and Java 5

If you have worked with iterators and collections in a multi-threaded environment, then you have probably dealt with the ConcurrentModificationException. If not, then you really need to read this! [<--customary Saturday morning boast]

When you iterate over a collection which is being modified in another thread, the Iterator throws a java.util.ConcurrentModificationException. And rightly so. Regardless of whether you are invoking a next, previous, add, set or remove operation in the first thread, the Iterator chooses a fail-fast approach to interrupt the proceedings. If you delve into the source of the AbstractList in J2SE 1.4.2 for instance, here's kind of what Josh Bloch has written

public Object next() {
checkForComodification();
try {
Object next = get(cursor);
lastRet = cursor++;
return next;
} catch(IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}

// a few lines of code later...

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}


The protected transient int modCount indicates the number of times the list has been structurally modified. Each add call in ArrayList (which sub-classes the AbstractList) increments this by 1.

So how do you work around this?

There are a number of ways you can tackle this issue. You could use the pessimistic approach of enclosing your code within the synchronized block or even using a synchronized collection


List bunchOfSlowMovers = Collections.synchronizedList(list);

synchronized (bunchOfSlowMovers) {
Iterator i = list.iterator();
while (i.hasNext()) {
foo(i.next());
}
}

I personally wouldn't recommend this. Although these steps assure integrity of data, they also introduce a bottleneck in the system. If you have an optimistic outlook, you may likely think that ConcurrentModificationException encounters are few and far between. This could prompt you to surround your iteration code with a try-catch block where you handle the ConcurrentModificationException instance by iterating the collection again.


private HokieBean getTheHokiestOfThemAll(List list) {
try {
Iterator iter = list.iterator();
while (iter.hasNext()) {
HokieBean hokieBean = (HokieBean)iter.next();
if (bar(hokieBean)) {
return hokieBean;
}
}

} catch (ConcurrentModificationException cme) {
// for those rare occasions...
return getTheHokiestOfThemAll(list);
}

}


Of course exception handling and recursion have their overheads and this scheme is useful only if ConcurrentModificationException instances are indeed rare.

The Java Collections framework has seen some enhancements in Java 5 (Tiger), most notably the addition of new concurrent utilities, apart from features like Generics, Autoboxing and Unboxing. Let's look at some of them.

java.util.concurrent.ConcurrentHashMap
This new map class extends the java.util.AbstractMap and implements the java.util.concurrent.ConcurrentMap interface. It supports full concurrency of retrievals and adjustable expected concurrency for updates. All operations are thread-safe and retrieval operations do not entail any locking. Its iterators do not throw ConcurrentModificationException. A concurrencyLevel setting dictates the estimated number of concurrently updating threads and the implementation class performs internal sizing to accomodate that number of threads. This may not completely solve our problem so lets keep looking.

java.util.concurrent.CopyOnWriteArrayList
The CopyOnWriteArrayList is a thread-safe version of the ArrayList where operations like add and set are performed on a copy of the underlying array rather than the actual array itself. In most cases, this may incur some performance costs but it can be beneficial when list traversals happen more often than updates. If you use the CopyOnWriteArrayList, you can do away with the synchronized block. Its iterator will never throw the ConcurrentModificationException because the underlying array never changes for the lifetime of the iterator, but you cannot invoke add and set on the iterator itself. That's not too bad, eh?

So we have at least 2 reasonable solutions to the problem of concurrent modification of collections. If you know of alternate approaches or ideas for the future, please leave a comment.

Email this | Bookmark this

Friday, September 17, 2004

Windows Users Have Fewer Vulnerabilities

... than Linux users, says a Forrester report. Hmm, really?

Email this | Bookmark this

Thursday, September 16, 2004

Good Code comes from Bad Code

If you are a proponent of code reuse, readability and maintainability, then this would be your wet dream. I was refactoring a bunch of Struts Actions on the product last week and the old bulb just lit up! Good code really does come from bad code. I started out trying to clean up some abstract classes that were crying out for help. After hours of refactoring, I was very pleased with the results. The code stench had been eliminated and we were left with works of art that looked so simple, you'd say it would have been the obvious course of action in the first place. But it wasn't.

Why didn't we think about this before, I asked myself? We took a complicated course of action when it was this simple all along. Engineers often write crappy code as stop gap measures. Because the deadlines merit a quick solution in place of a good solution. Code reviewers, maintainers and historians do not give you points for keeping deadlines. And then if you go overboard with the agile approach, foresight -- an essential element of good design and code -- doesn't keep up with the agility of code changes. If you go through short bursts of releases as we do, then cruft can be a problem too. I am referring to layers and patches added to badly designed or written code that make it difficult, if not altogether impossible, to throw the darned thing away and rewrite it all.

But I have discovered that it takes a thousand bad lines to of code to make really good code. The power to critique and deduct is almost a reflex action in most of us. In those several iterations of refactoring, I employed a number of approaches to solve the problem at hand. Most were thrown away almost as soon as Eclipse's incremental build process started churning. Others survived. In Darwinian fashion, the surviving ideas bred to form the end result. The key here is to come up with approaches, alternate approaches and alternate-to-alternate approaches. Then sit back and let the process of merciless elimination take effect.

Which brings me to some important questions. Is there really perfect code? Am I going to look at this so-called good code someday and ask myself, "What was I thinking?!" It is likely. I like to flatter myself by thinking that I too can write immortal code that lives long after I have left; after product groups have been disbanded; after companies have closed down or been bought over; unless copyright laws and dirty lawyers have resigned them to archives never to be seen again.

I love writing code and wouldn't trade it for anything else. I also love keeping deadlines.

[Acknowledgements: Thanks to Scott Berkun and Robert Watkins who've probably never heard of me, but in ways unknown to them, helped me swat some gotchas]

Email this | Bookmark this

Wednesday, September 08, 2004

Ten CSS tricks you may not know

Trenton Moss has this list on evolt.org.

Email this | Bookmark this

Wednesday, September 01, 2004

How many liters in 5 gallons?

Hmm. I now know there are 1.71788572 × 1053 teaspoons in a cubic light year, so let's ask Google, shall we?.

Or try teaspoons in 4 cups.

Email this | Bookmark this

What's next after foo, bar?

We have all used metasyntactic variables in programming. Ever wonder what the sequence was and how it came about?

Well, the list of English values goes something like this:

foo, bar, baz, qux, quux, garply, waldo, fred, plugh, xyzzy, thud


The MIT-Stanford usage has been

foo, bar, baz, quux, quuux, quuuux ...

but in some cases qux has been inserted before quux

For a little bit of history, here's the entry for foo from ESR's Jargon File. Wikipedia provides an equally compelling discussion on metasyntactic variables in general. Go, enrich your geekspeak!

Email this | Bookmark this

Indians 22, Yankees 0

Ooh, that musta hurt!

Photo Credit: Suzy Allman for The New York Times

Email this | Bookmark this