Latest News

6th November 2009
Send to twitter Send to Facebook

I have just finished Joshua Bloch's Effective Java Programming Language Guide and I can confidently say it is brilliant. This book will not introduce Java to the uninitiated, but it does illuminate the dusty and frankly perverse corners of a very powerful language. Although it is a dense read, it is a resource I will be returning to again and again.

With his many citings of the official Java spec, Bloch's authority is quickly established. Anyone that explains the uses and abuses of such common, but mysterious object properties as serialVersionUID and hashCode already has won me over.

Bloch's real gift is in making these opaque features understandable and putting them in to a context an average programmer is likely to understand. For instance, all Java objects have a clone() method that's meant to quickly and effeciently create new copies of an instantiated object. However, correctly implementing a clone() method is far trickier than it looks. And the same goes for the Serializable interface.

In many ways, Bloch complements the Gang of Four's Design Patterns. He extends the higher order approach to object-oriented programming into the Java context and provides concrete advice (e.g. favor object composition to inheritence, limit your APIs expose to the minimum, use the Singleton pattern for effeciency and comparison correctness, etc.).

What this book isn't is a how-to guide to anything. This is programming practices book and it rates as highly as any I've read.

31st August 2008
Send to twitter Send to Facebook

Following on the earlier post I made about programming hex maps for games, I have taken a stab at a Java program that generates different sized maps. You can download the zip file here. If you've got a recent version of the JRE (1.5), this should work for you out of the box by double clicking on it. Otherwise, you can run it by unpacking the archive and typing "java -jar HexMap.jar".

This toy just generates hex maps according to adjustable parameters. Hit the "Repaint" button to see the glory.

In a future post, I'll be explaining the math and heuristics I used. I'll also make the source code available then. However, there are better implementations I have in mind for this. Eventually, I should be able to emit an actual game that uses this work. No time, no time. Sigh.

12th February 2002
Send to twitter Send to Facebook

From a truly ill-considered Ask Slashdot question came this pearl of wisdom. A former (award winning!) Java hacker confesses his adulterous thoughts for Our Favorite Language. I'd like to pick up on a few of his points and perhaps add a bit of my own.

  • Unicode: it's a sore spot of Perl, but seems to be hunky-dory for java. I lay the blame for Perl's developmental problems here on DWIM. As Perl coders, we've come to expect Perl to handle simple (and not so simple) string manipulation without that much handholding from us. I suspect that this bit of Sloth is biting the 'porters. Certainly, the unicode issue is preventing Perl from being a first class XML processing language (no XS cheating here).
  • Perl's threading system is still developing, but java's model seems to be working fine. Of course, Perl's forking model is probably better and easier to use than java's (cross-platform forking is difficult to guarentee). I say tit-for-tat on threading/forking here.
  • Dedicated IDEs are bullshit. There, I said it. Coders shouldn't handle their code with the tongs of an IDE, like some poor MS Word shlub. If the java folks have more IDEs than Perl People, good on 'em.
  • ALL PRAISE CPAN! Perl was years ahead of MOST other languages here and continues to put java to shame. CPAN is not only an FTP archive, it's damn protocol to download and install libraries! In your face, JAR!
  • Elegance is something for which python and java are praised and for which Perl is found wanting. Clearly, I don't get the 'elegance' argument and I never have. If 'elegance' means fewer characters typed during coding, Perl wins for most applications. Consider perl one-liners, the inclusion of perl hashes, regexes, etc. Perl delivers the promises of 'less typing'. Is elegence the lack of 'weird characters?' It may be, but Perl's syntax acts like a road sign to tell the maintain what's going on. Sigils (those funny characters preceding variable names) are not a misfeature -- they are essential to maintaining a Perl program. You always know what to expect from a variable with a sigil. Without them, the reader (and coder!) needs to find the original declaration of the variable to figure out what it is. I hate that. Is elegance the object model of a language? Python and Perl's object model isn't terribly different. Shocked? Don't be. The difference between python and Perl objects is that python has a object type, where perl blesses variable data. Java and Perl object models are very different. Java's single inherentence (which is a Good Thing) and object data protection (which is a Useless Thing) definitely come from the C++ crowd.
  • You always get the source code with every Perl script and library. This makes it simpler to debug programs in Perl because you can always step through almost all of the code, including the libraries.
  • Readability. Perhaps this is meant to go under 'elegance,' but I think this is a different issue. All languages can be obfuscated. It's not the language designer's perview to make you code clearly. Any claim a language makes to being inherently cleaner to code in (I'm looking at you, Java and python) is naive. I don't expect a java programmer to maintain a Perl program, just as I don't expect a Perl programmer to maintain a java program. In fact, that's why I'm not an editor for a Japanese magazine -- I have no facility for the language. Does that mean Japanese is inferior to English?

[Original use.perl.org post and comments.]

12th September 2006
Send to twitter Send to Facebook

The more I use Java, the more I realize what "ivory tower development" means. And I don't like one bit, sir.

Java doesn't support printf. The C function printf is something nearly 100% of all programmers worldwide know how to use because it's how you make words appear on a screen or in a file. More importantly, it's the function you use to format text. That is, it allows you to control how many decimal places appear for floating point numbers, whether leading zeros appear in front of numbers, whether to show numbers as hexadecimal, octal or decimal, and a whole lot more. It's used in that most famous of introductory programs, hello.c:

#include 
void main (char **argv, int argc) {
  printf("Hello, world!n");
}

It's so basic a function that you can forget how darn useful it is. But, Java doesn't have it. What Java has a method, which is part of those kinds of classes that concern themselves with streams, which is a highly generic way of thinking about files and consoles and network sockets and your mom.

Ok, let's leave your mom out of this (for now).

That Java method is named println. It doesn't know how to format your output (to make your decimal numbers all pretty or to add fancy columns to your output), but it does know how to put the platform-appropriate newline character on the end of your string! So, you've got that going for you!

Now, the designers of Java aren't stupid (more on this later). There are problems that programs using printf encounter. For instance, internationalizing the output of programs with printf can be difficult. Sometimes. In badly designed large programs, which few programmers ever have to deal with.

More damningly, printf is ideologically impure. It's a function and Java's all about the Objects, baby. Sure, they could have made a static method of the String (or OutputStream or whatever) class called printf, but that might cause someone a little grief sometime somehow. Better to cheese off every programmer coming to the language. Yup. Great thinking there.

Another noticable absentee from Java fopen. The C function fopen is known by 99% of all programmers worldwide and nearly all popular programming languages have something like open (Perl has 3 closely related file open functions but you probably only ever need open).

As programming interfaces go, fopen is pretty nasty. You need to pass it a filename (and all operating systems name files differently). You need pass it a mode (are you reading from, writing to, appending to the file or all of the above?). And what do you get back from fopen? A file handle? A file descriptor? A lottary number? Who knows? However, it's a big puddle of programming poo that 99% of us have learned to deal with.

Instead, java has many circumlocutions to address files and even more to get data into and out of them. Working with files is task performed in 98% of all programs ever written. And Java makes getting to these files weird, frightening and confusing. You need a File object, which is then passed to a Output/Input Stream object, which in turn is passed to a Buffered Stream object. Nice and Object Oriented. And a complete pain in the genitals.

So, let's recap. Java, which was loosed upon the world in the nineties purposefully ignored very popular input/output conventions so that 100% of the programmers who learned any other language (most have syntaxes derived from C) would be utterly baffled by the most common of all programming tasks.

Are there times where all this OO sugar pays off? Sure. And Java is very helpful in these cases. Could Java have provided a nice compatibility layer for the oceans of existing C-based programmers? Sure, it could have. Easily, in fact. But the Java language designers thought they knew more about the how to tackle the jobs that Java programmers would face than the programmers themselves.

In classical literture, this type of overweaning pride is called hubris. In my native country Massholia, we just call that "being a f*cktard."

29th July 2006
Send to twitter Send to Facebook

A project for work required me to program in that most rigid and litigious of languages, Java. I used Apache Axis to make SOAP calls over SSL, thus making the project buzzword compliant. This post is about how, with the help of John Cho at VMware, I was able to coax Java in talking with SSL hosts whose X509 certificates have no recognized identity by the client. Typically, this means the hosts are self-signed and are not know to trusted root certificate servers. Without this hack, Java will refuse to use the SSL connection until the user imported the client certificate from the self-signed server, using the keytool utility from the JRE.

NOTE: Disabling authenticating of SSL certs is not compatible with security-sensative projects. Please understand that by using this hack, you are reducing the effectiveness of SSL security (although the actual network traffic through the SSL tunnel is still encrypted). The decision to use this hack is typical of the design choices made on the security-versus-convenience axis.

Although this code is specific to Axis, the careful reader may find this code applicable to their next Java project.

Apache Axis 1.4 (and earlier) uses the standard java.net.ssl package that is distributed with Sun's JDK 1.5 (it's in older JDKs too). The Axis class that creates the SSL socket factory that contacts the class that actually does the cert authenication is:

org.apache.axis.components.net.JSSESocketFactory.java

What we need to do create a special X509TrustManager that accepts all certs and install it as part of the SSL Factory. There's a lot of abstraction and action at a distance code here, so let's start with how to implement an all-trusting X509Certificate class.

class TrustyTrustManager implements javax.net.ssl.X509TrustManager {

  public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
    return null; 
  }

  public void checkClientTrusted(
         java.security.cert.X509Certificate[] c, 
   	 String authType) throws CertificateException {
    // do nothing, accept by default
  }

  public void checkServerTrusted(
         java.security.cert.X509Certificate[] c, 
         String authType) throws CertificateException {
    // do nothing, accept by default
  }
}

Recall that X509TrustManager is just an abstract class. It requires three methods to be implemented. Fortunately, these methods are easy to deal with, if you don't care about authenication. The first, getAcceptedIssuers(), is supposed to return an array of certs for trusted authority servers. Since we aren't going to consult any, we can return null there. The last two methods throw an exception if the described certificate cannot be authenticated by building a "trust path" from the root authorities to the given one. Since not throwing an exception means that the trust path was succesfully constructed, we do absolutely nothing in these methods. If only all code were so easy to write!

The only catch here is that we do need to import java.security.cert.CertificateException to handle the exceptions that we'll never throw, otherwise we get a compiler error. Thanks for the extra hoop, Java.

I added this class as an inner, private class to the JSSESocketFactory.java file, but you may want to isolate this code into its own file for use in other projects.

Now we need to install this X509Certificate class. This can be done by change the code in initFactory() to something like the following:

    protected void initFactory() throws IOException {
	// Inspired by John Cho
	try {
	    javax.net.ssl.TrustManager[] trusty = 
		new javax.net.ssl.TrustManager[] {
		    new TrustyTrustManager() 
		};
	      
	    javax.net.ssl.SSLContext sc = 
                  javax.net.ssl.SSLContext.getInstance("SSL");

	    sc.init(null, trusty, new java.security.SecureRandom());
	    sslFactory = (SSLSocketFactory) sc.getSocketFactory();
	} catch (Exception e) {
	    throw(new IOException("SSLFactory: " + e.getMessage()));
	}
    }

Let me step through the code backwards, since it will help to know where we're going with this method. The whole point of initFactory() is to initialize the protected class member sslFactory with a valid object. SSLSocketFactory objects are returned by javax.net.ssl.SSLContext objects, which the documentation describes like this:

«Instances of this class represent a secure socket protocol implementation which acts as a factory for secure socket factories. This class is initialized with an optional set of key and trust managers and source of secure random bytes.»

I emphasized "trust manager" here, since that's what we implemented with the TrustyTrustManager class. Now, we just need to create an SSLContext object for the SSL protocol (not sure why there are other options here), and shove in our TrustManager.

Well, not quite. It turns out that SSLContext expects to get an array of TrustManagers.

init(KeyManager[] km, TrustManager[] tm, SecureRandom random)

We don't need KeyManagers at all and the random seed can be generated from a method in java.security. What we do need is an array of TrustManagers with one TrustyTrustManager object in it. Once this is assembled, init() can be called correctly and the SSLSocketFactory obtained.

There you are! It's as simple as rocket science, but not as hard as brain surgery.

Some advanced Java coders will probably decry this code as cheating. It's not very OO to manhandle an existing class like this. Surely, there must be a way to subclass JSSESocketFactory and override the behavior of initFactory() more cleanly. The answer is "yes," but that means finding all those places that instantiate JSSESocketFactory objects and subclassing those classes. And, of course, you can see how this subclassing will quickly ripple through the entire object heirarchy of Axis to destroy all my free time. In Perl, I might have simply poked through the package namespace at some point to overwrite initFactory(). I'm not aware how to do that in Java effectively, but I welcome your suggestions.

UPDATE: For additional information on doing this with Apache's XML-RPC lib for Java, check this out. I think this technique may work with axis too, since it is built of the standard Sun SSL stuff. But, I haven't tried.

9th May 2006
Send to twitter Send to Facebook

Programmers love to argue about which programming languages are better than others. If you listen carefully, you'll notice that there's a hierarchy to the debate. Java programmers laugh at C++. C++ coders deride C monkeys. Everyone laughs at shell hackers. No one can understand assembly programmers and those that "think in LISP" occupy a sublime and knowing orbit above all rest (so they think).

But I'm a Perl hacker first and foremost. Despite some of the more vocal members of the community, Perl is a humble language (with, as its critics will quickly add, much to be humble about). In recent years, I've forced myself out of this comfort zone into the wider world of programming. Like all generalist, I try to pick the right tool for the task. For instance, PHP is a best tool I've found for general web applications, which is why this site uses it. For quick and dirty Windows games, Python (with its pygame library bindings to SDL) stands alone. For repetative system admin tasks, shell scripts and cron combine like Voltron to create superlative software robots. The thing is, most programming languages are pretty similar. They have data types, loops and conditional branching. That's really the bare minimum you need to get things done. Where languages differ is in the services they offer the programmer.

I've heard that you love someone not for his winning attributes, but for his faults. However, I've found that there are definitely some faults that are harder to love than others. This missive is about those faults in Java that keep our relationship forever at the stage of the first date. If Java is your "Main Mama", you may want to stop reading this now.

For my work, I need to hack up a bit of Java that speaks XML-RPC. Now, you may recall that I'm no stranger to working with this protocol. I've written XML-RPC clients and servers in Python, Perl, PHP, ASP and even (God help me) C. But I missed out on Java until now.

No problem, I thought. I'll just look through my book at the chapter Simon St. Laurent wrote about using the helma XML-RPC library for Java. Simon did the lion's share of the book and did the most thorough job of any of us on the project, so I took a look. Funny thing: that library has morphed into the Apache XML-RPC library. Ok, fine. How different could it be? I mean, it was working fine before. How many changes were needed? Perl's Frontier::RPC library has hardly changed in six years (and we use it heavily at Leostream).

As it turns out, the one thing Java does well is faciliate abstractions. With the newest version of the library, you can tweak all kinds of parameters, swap out XML parsers, add additional data types (which defeats the whole effing point of XML-RPC), create new class factories -- the list goes on! In fact, there's a whole class just for configuring the XML-RPC client! Excessive you say? Just wait.

The one thing you can't do with this library is start using it quickly. The main culprit? Missing dependencies. When I tried to run a simple XML-RPC client, it complained about not knowning how to encode the XML-RPC timestamp thingie. Oy. But wait! Weren't JAR files supposed to solve this issue? Wrong again, Fatty!

Ok, so I needed to install subversion just to get the bleeding-edge version of the missing ws-common library. That's not so bad, right? Wrong. I also needed to get a nightly snapshot of the TRUNK code of the main library because the "release" version could not handle structures correctly (the unknown "string" problem). Fine. That happens. It's open source so you've got to expect the release management to get a little "cowboy" sometimes.

At length, my "hello, world" XML-RPC program got up and running. After several phone calls gloating about this teapot triumph, I proceeded on to handling more realistic and complicated data structures. I had my test server return a structure to my Java client that had a value that was an array. In perl, the structure looks something like this:

  { "foo" => "bar",
    "boz" => [ "boom", "doom", "soon" ],
  }

Here's a quick test: how many dictionary classes does Java have? I'm talking about generic collection types that hold key-value pairs. 1? 3? 10? Wrong! It's a trick question. In Java, new Map classes spontaneously generate all the time.

I bring this up because in order to traverse this data structure, I need to know the how to type the objects correctly. Now, in simple programs where you control the data, that's easy. When you have to deal with arbitrary data coming in from an unknown source, Java whips out the hate on you.

Because Java sucks is very advanced, I have to iterate through methods to transverse this structure. Something like the following:

Map my_struct = get_the_struct();

Iterator it = struct.keySet().iterator();
while (it.hasNext()) {
  Object this_key = my_struct.next();
  Object raw_object = result.get(this_key);

   // here comes the good part
   Class c = raw_object.getClass();
   if (c.isArray()) {
       // fetching this object was so nice, I do it twice!
       Object [] this_value = (Object []) result.get(this_key);
       System.out.print(this_key + " => ");
       int i;
       for (i=0; i < this_value.length; i++ ) {
           System.out.print(this_value[i] + ", ");
       }
       System.out.println();
   } else {
     // simple data type
     System.out.println(this_key + " => " + raw_object);
   }
}

It took me about 3 hours to puzzle out this code. It would have been swell for the docs to have an example of handling complex data like arrays and hashes, but then I would have missed out on my afternoon of personal discovery and emotional growth.

After many fruitless web, book, and source code searches, I managed to hack this code to handle my "weird" data. It's crappy, but it works.

The truly loathesome part is the way I had to work with hash values that are arrays. For reasons that aren't clear, I couldn't just use the value returned from a Map if it is an array of Objects. That would be too easy. I had to properly cast the data because Java is a bucket full of venomous hate. Of course, I need to check if the object is, in fact, an array and then fetch the object again for the cast!

Allow me to paint with a very broad brush for a moment. The stunt programming exhibited in the code above is exactly the kind of stupidity that prevents Java folks from learning about what's going on in the rest of the computer universe. Strict data typing is 100%, no-foolin' legalese.

All modern scripting languages handle this kind of "collection of random data types" better than Java. VBScript is only slightly less lawyerly about it, but it too sucks hard on big, stiff data structures (VBScript has two assignment operators: one for objects, one for everything else. Thanks for nothing, Microsoft).

It's enough to really bring me down, man.

What the hell is wrong with these language designers? Can they please stop worrying about continuations, anonymous classes, multiple inheritance, abstract interfaces, factory classes and orthogonality long enough to make a language that's useful for the kind of problems I have to deal with? I live in world of strings. If your language makes dealing with strings hard for me, I will hate you with my fists.

Can I get a "hell ya!"?

Jesus H. Christ.

About this blog

The taskboy blog is a exploration of computer technology by Joe Johnston. Topics of posts include practical examples Perl, PHP, Python and Java as well as book reviews, industry insights and miscellaneous good stuff.

Current Status

Watching _Brass Latern_. Ah IF, your coyness is your charm.

Posted: Sun Sep 05 16:02:15 +0000 2010