Caffeinated Bitstream

Bits, bytes, and words.

Java

Implementing DES

DES, the Data Encryption Standard, was developed by IBM and the US government in the 1970's. Today, DES is considered to be weak and crackable, and a poor choice for anyone in the market for an encryption algorithm. However, many legacy protocols still use DES, so it's important to have implementations handy.

I recently found myself looking for a simple standalone DES implementation to study. Most of the open-source DES implementations are either highly optimized into obfuscation, or sloppily written. Either way, it's hard to find a clearly written and well-commented implementation suitable for educational purposes. I decided it would be a good exercise to write one myself. I wrote the implementation in Java, for the extra challenge of performing bit manipulations on signed primitive types. This implementation is undoubtedly very inefficient, but is well-commented and should be easy to understand for anyone who wants to dive into a sea of Feistel functions, S-boxes, variable rotations, and permutations.

References

I found the following resources useful in my study of DES:

Downloads

  • DES.java - My DES implementation in Java
The Java user experience

A friend of mine wrote an interesting blog post advocating the use of Java for rich internet applications, and expressed frustration with its lack of Web 2.0 mind share. This got me to thinking about how a lack of polish often seems to hold Java back, and I wrote the following comment in response. (I'm reposting it here because, yeah, I'm just that desperate for blog material.)

Technically speaking, I think Java could make a killer platform for the sorts of applications you're describing. I quite like Java, and I'm especially looking forward to the improved dynamic language support that Java 7 is supposed to offer.

However, I think Sun has not been very successful at managing the customer experience. Success in this sort of consumer-facing technology requires not only solid engineering, but getting right a lot of the small details that add up to a positive experience. Several things come to mind about Java:

  1. As you mentioned, people remember applets from the bad old days.
  2. Java has always struggled with trying to provide responsive GUIs, and no amount of switching back and forth between heavyweight and lightweight widgets has helped. I haven't looked at Java GUIs lately (or JavaFX), but like applets, it may be an uphill battle to convince people that things are different now.
  3. When I mentioned the use of Java to a customer once, he looked at me in shock and said, "You mean that thing in my system tray that's always bugging me about needing to be updated?" Flash, which has arguably won the applet war, doesn't generate that sort of reaction in people.
  4. Oh yeah, speaking of system trays... Java finally introduced support for putting icons in the "system tray" / "notification area" in December 2006 -- about ten years too late. Ten years is not a fast enough response time when competing on feature points related to the user experience.
  5. Probably many other minor details...

Steve Jobs would not approve of the conditions that led to the above points. I'm not an Apple fanboy or anything, but let's face it... the dude knows how to sell products. Sun needs to take a page or two from the Apple book, and focus on the spit and shine. Even then, Sun will need to lay down some serious shock and awe to supersede bad memories. I would love to see Sun pull this off, before everyone gives up and just starts writing web applications in x86.

Foreign Key Constraint Discovery

When developing database-oriented business webapps, the data model can sometimes become quite complex with many database tables referencing other database tables. To maintain referential integrity, you can (and should) declare foreign key constraints so rows cannot be deleted if other rows depend on them. However, if the application is a basic CRUD webapp that provides the user a direct, non-abstract view of the data, the user may be surprised to get a confusing constraint violation error when he or she attempts to delete a row. Such errors seldom contain useful details, so even if you wrap the error in a pretty page, the user may still be left wondering exactly why that row could not be deleted. Even if your database provides such details when a constraint is violated, an important usability question must still be asked: Why was the user given the option to delete the row in the first place, if deleting the row would result in a constraint violation?

The ideal solution would be to remove the option to delete rows that cannot be deleted, gray out the delete button, or otherwise indicate that deletion can't happen. Better yet, provide some information about why the row is important and can't be deleted yet. This requires the webapp to determine which rows can be deleted when the rows are being rendered in the web page view.

The goal is to write a routine for preemptively checking foreign key constraints. Such a routine must be very general, because we don't want to hard-code data model logic that must be maintained every time we change the schema, and prevent us from easily reusing the code in other projects. It would be great if databases supported an SQL query such as "CHECK DELETE CONSTRAINTS FROM table_name WHERE id IN (42,43,44,...)". Unfortunately, I haven't come across any such feature. Fortunately, databases do allow the schema to be examined and foreign key constraints discovered. Therefore, our problem can be handled with a simple, two-step solution: (1) At application startup time, perform foreign key constraint discovery, and (2) when delete options are being rendered, call our routine to query the deletability (deleteability?) of each row.

In Java, for instance, a schema's foreign keys can be examined in a database-neutral manner with JDBC using the DatabaseMetaData.getExportedKeys() method on each table, building a list of all foreign key relationships. (The list of tables can be queried with DatabaseMetaData.getTables().) The foreign key relationships defined with ON DELETE CASCADE must be flagged based on the presence of the importedKeyCascade flag in the DELETE_RULE.

When the webapp needs to check the deletability of displayed rows, it can call the routine with the table name and a list of id's to check. The routine can check each foreign key relationship with a SELECT to see if any foreign key constraints would be thrown if any of the specified rows were deleted. Relationships defined with ON DELETE CASCADE do not throw constraint violations for the initial delete, but the cascaded delete might violate a constraint, so the "check deletability" routine must be recursed into for each of these cascade relationships. Because the directed graph of foreign key relationships is allowed to contain circular references, the set of processed rows must be passed into each recursion and checked against to prevent infinite recursion. After processing, you should have a list of row id's that cannot be deleted, along with the reasons. Implementation of this scheme is left as an exercise for the reader. For bonus points, integrate with Hibernate so the webapp can pass a collection of persisted objects instead of row id's.

I've found that this approach results in a nice, easily reusable module that seems to work well with PostgreSQL and SQL Server. For some webapps, there may be some performance issues with executing these additional queries for every page view. However, if all the relevant criteria fields are indexed, it's probably not a big deal. Many people solve this problem by never actually deleting rows, but merely setting a "deleted" boolean flag to indicate that the rows should no longer be displayed. This can be a fine solution, except when there are business reasons for making sure the user is aware of all the outstanding dependencies.

Taming Roller's URL strategy

When I decided to start this blog, I installed the Roller 4.0 weblog software. Many different blogs can run in one instance of Roller, and the URLs for the blogs are arranged as subdirectories of a master Roller URL. For instance, if you installed Roller to be /roller, then your blogs might have URLs like /roller/my_blog, /roller/potato_farming_in_pocatello, and /roller/i_like_lettuce. That's fine for many uses, but I prefer to have more concise URLs. I'd like my blog to be referenced from the root of the web site, like /my_blog. Why should I have to conform to how Roller thinks I should set up my web site?

Configuring a web server to remap incoming URLs is a simple matter, and can be easily accomplished with tools like Apache's mod_rewrite. Such remapping techniques are well known and I won't bother going into detail about it here. However, what about outgoing URLs? With the rewrite rules in place, users can easily access the blog at /my_blog, but all the links on the page point back to the ugly URLs. It's a simple matter to redirect these in the web server so that they work, but it's nasty and wasteful to be constantly sending redirect messages, and besides... what would Googlebot think of such shenanigans?

I get stubborn about these sorts of things, so I decided to roll up my sleeves and see what was going on under the hood of Roller. It turns out that Roller provides a URLStrategy interface that can be swapped out programmatically with different implementations to provide different URL behaviors. Also, to my astonishment, Roller 4.0 is hooked together with Guice -- the lightweight dependency injection system developed at Google. I haven't worked with Guice, but I have used the Spring Framework's inversion of control library for dependency injection, so I know that these systems are built to make it easy to swap out components -- just what I'm looking for!

Unfortunately, there's no facility in Roller to configure the Guice dependency injection at runtime -- as far as I can tell, the Guice configuration is hard-wired in the code. (As opposed to an XML configuration file, as is common in Spring applications.) However, there is a runtime property to select the class that does the configuring -- the so-called Guice module. This means that to provide my own URLStrategy, I must supply at least two new classes: a custom replacement for Roller's JPAWebloggerModule class which is used to configure Guice, and the replacement for the MultiWeblogURLStrategy class which currently defines the URL behavior.

I start by configuring Roller to use my custom Guice module, by adding this line to my roller-custom.properties file:

guice.backend.module=com.davidsimmons.roller.CustomWebloggerModule
This property will configure Roller to use my CustomWebloggerModule class, which configures Guice with all the same bindings as Roller's own JPAWebloggerModule class does, except it binds my CustomURLStrategy class to the URLStrategy interface instead of the default MultiWeblogURLStrategy implementation. My CustomURLStrategy extends MultiWeblogURLStrategy, so it is almost the same, except that it knows about special weblogs that I want to be referenced from the root of the web site. For these weblogs, my custom class post-processes the URL to remove the first component of the URL path. Voilà! All my links now reflect the friendly version of the URL.

There is one gotcha -- when I reparented the blog, important cookies stopped working because they were tied to the /roller path. To solve this for the JSESSIONID, I configured my Tomcat servlet container to use an empty path by including emptySessionPath="true" in the Connector attributes. There are a few more path-dependent cookies that Roller uses that may come back to bite me... we'll see.

The sample code is available here: simmons-customurl.tar.bz2