When having a dynamic language helps
I just committed unix-domain sockets (AF_UNIX) for GNU Smalltalk.
GNU Smalltalk's socket library is more or less based on the java.net library, but java.net does not have AF_UNIX sockets! Okay, they are not portable to Windows, but you'd expect someone to have written an extension library for that. But no, there is none. Why?
It turns out that there are two problems.
The first hurdle has nothing to do with the language; simply, the design of java.net.SocketImplFactory is totally braindead. In fact it is completely unused; Google Code Search results are 99% for the implementation of java.net, and 1% broken code. I modified that part in GNU Smalltalk; there you have class-side factory methods in each address-family class (UnixAddress, IPAddress), so you can pick a different set of implementation classes for each address family. The important part is not that I use class methods, but that my scheme actually works. :-)
However, this flaw only makes the implementation less self contained: the AF_UNIX implementation class would have to be shared with IP sockets, so you cannot provide AF_UNIX-specific niceties (such as removing the socket from the filesystem when you close it).
There is a second hurdle —this one is directly related to the Java language, and it makes it impossible to implement AF_UNIX sockets in a way that is consistent with the existing implementation of IP sockets.
Previously I mentioned the address-family classes UnixAddress and IPAddress. In both java.net and GNU Smalltalk these are concrete subclasses of a SocketAddress class. An instance of one of this classes represents a machine's address in a particular address family. This is different from the struct sockaddr_* structs in C, which represents endpoints of a socket, but it actually works well. Simply, whenever a method needs a socket endpoint it will be split across two arguments, one for the machine and one for the service (port).
In Smalltalk the design extends naturally to AF_UNIX sockets. These sockets are always local to the current machine, so UnixAddress is a singleton subclass of SocketAddress. The language is dynamically typed, so the service can be an Integer object when dealing with IP sockets, and a String or a File when dealing with AF_UNIX sockets.
For Java, you have probably already seen the gotcha: java.net declares the port argument as an int, so this kind of polymorphism is impossible. You have to put the service in the UnixAddress instance, thus breaking the abstraction that SocketAddress instances represent machines.
One would need to add more constructors, or more overloaded methods, that take an Object for the service. However, in Java you cannot extend classes either, so this is a no-no unless Sun does it.
I guess this was why someone wrote this in a mailing list, regarding implementing AF_UNIX sockets in Java:
> has nobody tried to write a library for this purpose before? i> was not able to find any solution for this problem on the
> internet. i might need this for some personal project, but
> maybe AF_UNIX sockets would be an interesting java-feature for
> a lot of people (jdbc-drivers, component systems like
> openoffice uno...)
>
> it seems to be hard (or impossible?) to map an api for non_ip
> sockets into the java.net api.
Yuck!
