Woozle Wuzzle
In vogue languages

I'm often asked why I don't hop on the lastest language bandwagon and just start coding up a storm. The answer comes in two parts: the first is that I do try out these languages to see what the hype is all about, to see where they can fit in and to see their pros and cons. The second is that I realize that there is more to software engineering than just writing code. Software spends disproportionately more time in maintenance than it does in initial development. Just because a language such as Ruby is much faster for initial development doesn't mean that it's much easier to maintain. (Do note that I'm not saying that Ruby is hard / harder to maintain. I'm simply saying that a one cannot determine what the maintenance model for a language is from doing only initial development.) The long and short of all of this is that I am forced by my professionalism and my responsibilites to not only look at how a language works for initial development but also for long term maintenance. By definition this means that it takes me a very long time to determine if a language is suitable in the long term. Since many newly in vogue languages simply haven't been out long enough to have either the community's or my own understanding of its maintenance model one simply cannot start writing production code with them.

One quick example of all of this is AOP. I'm enamored with AOP but I cannot and will not use it in production software. The reason is that AOP simply does not have a maintenance model at all. In other words, I cannot take an AOP'ified application and future apply AOP on it (i.e. maintain it) and have understandable and determinable effects.

Editor's note: this is a stream of consciousness posting to get an idea down and is not complete or thorough in any way. But as always, comments are welcome.

Java instance initializers

I have been playing around with some UI mock ups lately and it is often that I have code that looks like the following:

    ...
    add(new Label("Some text"));
    ...

If I want to see what Some text looks like in a different color or font then I need to extract the label creation to a local variable and then set the appropriate members. Since I'm a lazy lazy man I was getting tired of this. Luckily I remembered about instance initializers. Because of instance initializers you can do the following:

    ...
    add(new Label("Some text") {{ setFont(someFont); }});
    ...

{{ and }} are not new tokens. Writing it another way makes it more clear:

    ...
    add(new Label("Some text")
    {
        { 
            setFont(someFont); 
        } 
    });
    ...

The only question that remains is: when is the instance initializer executed? You can read section 8.8.5.1 of the JLS if you want. (The problem that I have with section 8.8.5.1 is that it is for explicit constructor invocations which doesn't seem to be the case for this example but I cannot find another reference to instance initializers in the JLS.) The code below provides a clearer answer to the question.

    class PreTest {
    
        {System.err.println("PreTest First");}

        public PreTest() {
            System.err.println("PreTest constructor");
        }
    
        {System.err.println("PreTest Second");}
    }

    class Test extends PreTest {
        {System.err.println("Test First");}

        public Test() {
            System.err.println("Test constructor");
        }
    
        {System.err.println("Test Second");}
    
        public Test(final int number) {
            this();
            System.err.println("Test constructor(" + number + ")");
        }
    
        {System.err.println("Test Third");}
    
        public void method() {
            System.err.println("Test method");
        }
    
        {System.err.println("Test Fourth");}
    }
    
    class Dummy {
        public Dummy() {}
        public void go(Test test) {}
    }
    
    final Dummy dummy = new Dummy();
        dummy.go(new Test(10) {{ method(); }});

When executed, the following is output:

    PreTest First
    PreTest Second
    PreTest constructor
    Test First
    Test Second
    Test Third
    Test Fourth
    Test constructor
    Test constructor(10)
    Test method

An instance initializer is executed during construction but after all other instance initializers and all (appropriate) constructors have finished.

I should point out that this "trick" is also great in unit tests for populating collections.

    ...
    something.addList(new ArrayList() {{ add("1"); add("2"); add("3"); }});
    ...
    foo.addMap(new HashMap() {{ put("1", "one"); put("2", "two"); }});
    ...
i = i++

A question was recently posted on the CJUG forum with regards to the following code:

    int i;
    i = 1;
    i = i++;
    System.out.println("i: " + i);

The poster wanted to know why in Java the result was 1 whereas in C / C++ the result was 2.

If you're like me, the first thing that popped in your head was: This person does not have a clear understanding of the postfix increment operator does. Let's tell him to go suck an egg and get a clue. But then I remembered back to the days when I didn't know what I was doing either and all of the kind and gentle people on usenet that steered me onto the path of knowledge.

In case you're having trouble getting over that hurdle, you can look at the problem as follows:

int[] a = { 0, 1, 2 };
int i;
i = 1;
a[i] = i++;
System.out.println("a[0]=" + a[0] + ", a[1]=" + a[1] + ", a[2]=" + a[2]);

which is slightly more palatable and results in the following:

a[0]=0, a[1]=1, a[2]=2

I'll spare the long winded answer to the reason why Java returns what it does and refer you to a Java forum posting. (Though if you want me to ramble on about it, just ask!) That takes care of the Java part, but what about C / C++? Well, if you didn't get all soft and squishy developing in Java all these years, you'll remember that the order of evaluation of operands of individual operators and the order in which side effects take place is unspecified in C / C++. You'll also start remembering about sequence points and all of that but before you begin to spasm uncontrollably, you'll remember that you've left all that behind you now. At the end of the day, the fact that the particular C / C++ compiler, runtime, etc resulted in 2 is simply luck of the draw. The expression is undefined. To quote Dale King:

...in C that statment might assign 0, 1, 42, -1 or any other value to i. It might crash your machine, erase your hard drive, or cause your computer to melt down. All would be acceptable results of executing that statement, since its behavior is undefined.

There is also Steve Summit's famous response which provides links to the C FAQ for more information.

JBoss and autonomic computing

I spent some time a few days ago working with JBoss to determine if it would be a valid service oriented platform for autonomic computing. You can read my multiple JBoss JMX posts for more information. Until a more well defined service lifecycle exists ala JSR 77, the ability to autonomically manage a JBoss service is not possible.

I'm looking into OSGi, Avalon and Excalibur next. (If you're like me and forget how Avalon, Merlin, Excalibur, etc are related then refer to this.) Stay tuned for results.

Proxy

Given the vast amount of crap that we as programmers need to know these days (which is growing exponentially) I typically wrap unknowns into a black box and add them to my list to check out at a later time. java.lang.reflect.Proxy fell onto this list.

I typically associated a "magic" factor to anything that's in the core Java classes. Take for example how NIO's InterruptibleChannel interacts with Thread. I still want to know how Sun expects third parties to use the SPI to create other NIO implementations but that's another battle for another day.

I assumed incorrectly that Proxy had some magic tie-ins to the JVM that allowed it to masquerade as another class. Instead, Proxy actually goes the sane route. It generates a class (as a byte array) using reflection to inspect the specified interfaces. The class is then loaded using something very similar to ClassLoader.defineClass() (why it does not just use ClassLoader is not known but if there is one thing that I've learned over there years is that programmers love to keep secrets). By default, these generated files are not persisted to disk. You can set the system property sun.misc.ProxyGenerator.saveGeneratedFiles to true to save the files for examination (I do not know where they are saved to).

It's actually unfortunate that Proxy does not use JVM magic since then it might be possible to create a proxy to a class (rather than just interfaces) which would provide a truely useful generic proxy mechanism (facilitating AOP, for example).

More clients performance results

I received a number of equiries to get performance numbers with larger numbers of clients. Unfortunately, I am limited to five client machines and one server machine. To increase the number of clients communicating with the server, I had to have multiple clients per machine. From the previous tests, a hypothesis can be made that the clients are either CPU or I/O bound. Adding more clients to each machine is not going to produce interesting results. The is essentially what was seen.

There are a total of eight configurations (three with SSL and four without). To simplify analysis, each graph contains the results either from the three SSL servers or the four non-SSL. Three cases were chosen:

  • 1 client per machine (so that comparisons could be made back to previous results)
  • 5 clients per machine
  • 10 clients per machine

The same environment was used as in the previous tests.

The choices (besides one client per machine) was completely arbitrary. Numbers were chosen such that the tests would complete in a reasonsable amount of time.

Without SSL

5 Machines, 1 Client per Machine 5 Machines, 5 Clients per Machine
5 Machines, 10 Clients per Machine

With SSL

SSL, 5 Machines, 1 Client per Machine SSL, 5 Machines, 5 Clients per Machine
SSL, 5 Machines, 10 Clients per Machine

Analysis (see the other previous tests for more analysis):

  • As expected, being bound (either CPU or I/O) has not yielded interesting results.
  • For the non-SSL case with more than 1 client per machine, the performance for NIO, IO, Converted IO and Converted IO with Selector have effectively merged. I attribute this to "fill in the blanks". By increasing the number of clients per machine, any nearly-bounded resources were maxed out.
  • The SSL case is known to be CPU bound (as the encryption and decryption are being done in software). It too had a "fill in the blanks"-style result (i.e. it is asymptotically reaching it's maximum value per machine).

A few tests were made to determine if the clients were CPU bound or IO bound. It could be guessed from previous results that they were IO bound (given the signature of the SSL results). Futher testing has shown this to be the case (e.g. all client echo validation was removed). Since the clients are IO bound, adding more clients to each machine would show no greater throughput to the server which is precisely what was observed in these tests.

Link-back to main entry: NIO and SSL.

SSL performance results

In following with the previous tests, I performed a performance test of IO and Converted IO with SSL.

The testing environment is the same as the previous tests except that anonymous software SSL was enabled.

There are a total of three cases:

  • IO Server, IO Client
  • Converted IO Server, Converted IO Client
  • Converted IO w/ Selector Server, Converted IO Client

"IO" uses the standard Java IO (from the java.net). "Converted IO" is an NIO wrapper to InputStream and OutputStream. The server with "Converted IO" uses a separate thread per client. The server with "Converted IO w/ Selector" uses a single thread for all clients and switches between them using an NIO Selector.

SSL IO Server, IO Client SSL Converted IO Server, Converted IO Client
SSL Converted IO w/ Selector Server, Converted IO Client

Analysis (see the previous tests for more analysis):

  • Comparing with the non-SSL tests you can see that there is a significant (~50%) but expected loss in throughput.
  • As hoped, the difference between Converted IO and Converted IO using a Selector decreased dramatically (from ~33% to ~7%) due to the overhead of SSL.
  • Unfortunately, the difference between IO and Converted IO became more pronounced (from ~11% to ~25%). I do not have an explanation at this point and more investigation is needed.

A special thanks goes out to Carlo Segre for use of the cluster.

Link-back to main entry: NIO and SSL.

More NIO and IO performance results

I took the opportunity to create a standard IO client and server and performed some changes / optimizations on the Converted IO. The source is available at the usual place.

The testing environment is the same as the previous tests.

There are a total of four cases:

  • NIO Server, NIO Client
  • IO Server, IO Client
  • Converted IO Server, Converted IO Client
  • Converted IO w/ Selector Server, Converted IO Client

"NIO" means that the component was created using only NIO. "IO" uses the standard Java IO (from the java.net). "Converted IO" is an NIO wrapper to InputStream and OutputStream. The server with "Converted IO" uses a separate thread per client. The server with "Converted IO w/ Selector" uses a single thread for all clients and switches between them using an NIO Selector.

NIO Server, NIO Client IO Server, IO Client
Converted IO Server, Converted IO Client Converted IO w/ Selector Server, Converted IO Client

Analysis (see the previous tests for more analysis):

  • Standard IO performs slightly better (and with less variance) than NIO. This follows the standard claim that the use of a selector adds a bit of overhead (even more than that seen by using multiple threads). A future test should use many more clients to see if the overhead of a selector overcomes the overhead of context switching many threads.
  • The clean up of the Converted IO appears to have created a positive result. The difference between ~10.3 MB/s (NIO), ~11.1 MB/s (IO) and ~9.8 MB/s (Converted IO) (~4% and ~11%, Converted IO to NIO and Converted IO to IO, respectively) is much better than the previous difference of ~20%.
  • The Converted IO using a Selector has a similar trend as before: large variance in throughput and much lower throughput. More investigation is needed.

A special thanks goes out to Carlo Segre for use of the cluster.

Link-back to main entry: NIO and SSL.

NIO and Converted IO performance results

I finally had an opportunity to perform some performance testing on the source I made available.

A few notes about the testing environment:

  • It was not a closed environment. It is a cluster of machines running Linux (2.4.21) with MOSIX with a number of NFS mounted drives. There were a few other processes bouncing around the cluster at the time. This caused a number of dips in the throughput. All processes for this test were pinned to their respective machines.
  • All machines are AMD Athlon(tm) XP 2500+ with 512MB RAM
  • Sun JDK 1.4.2_05
  • The network is 100Mb but it is not known if it is switched (highly doubtful)
  • The echo server was started. The first connected to the server, followed by the second approximately seven second (arbitrary) later, followed by the third approximately seven seconds later, etc for all five clients.
  • Each client transferred 500MB to the server before disconnecting.
  • The data sent from the clients is random and in random sized batches of less than 4096 bytes.
  • All data received by the server is immediately written back to the client.
  • The clients wait for the server to echo back their batch of data and validate it before sending another.

As with most performance tests, the results must be interpreted correctly and cannot be taken at face value. You should not look at absolute values but instead you should look at relative values and trends. For "pure test" results the environment was not ideal but for a more "real world" feel for how applications behave, the environment was adequate.

There are a total of six cases:

  • NIO Server, NIO Client
  • NIO Server, Converted IO Client
  • Converted IO Server, NIO Client
  • Converted IO Server, Converted IO Client
  • Converted IO w/ Selector Server, NIO Client
  • Converted IO w/ Selector Server, Converted IO Client

"NIO" means that the component was created using only NIO. "Converted IO" is an NIO wrapper to InputStream and OutputStream. The server with "Converted IO" uses a separate thread per client. The server with "Converted IO w/ Selector" uses a single thread for all clients and switches between them using an NIO Selector.

All of the source for the clients and servers is available but the test harness is not available. It should be a trivial matter to create you own testing mechanism ideal for your environment.

Ideally, there should be a standard Java IO implementation as a control but unfortunately time is not on my side.

NIO Server, NIO Client NIO Server, Converted IO Client
Converted IO Server, NIO Client Converted IO Server, Converted IO Client
Converted IO w/ Selector Server, NIO Client Converted IO w/ Selector Server, Converted IO Client

Analysis:

  • The large dips in the graphs were caused by MOSIX and the processes that were running on the clusters.
  • The NIO server performed slightly better than the Converted IO server as expected since the Converted IO server has an additional delay associated with the pipe that converts from standard IO to non-blocking IO. The difference between ~7.5 MB/s (Converted IO) and ~9.5 MB/s (NIO) (~20% difference) is significant and further work needs to be performed to tune Converted IO.
  • The NIO client performed slightly better than the Converted IO client (for the same reasons as the server).
  • The selector-based server to multiplex multiple clients performed worse than using a separate thread per client. Based on other results found on the internet, this is a typical result. The overhead of the selector is not mitigated with only a few clients.
  • The fluctuation of the selector-based server was not expected. Further investigation is warranted.
  • It appears that client 3 was not behaving consistently as is seen by its lower throughput and longer times. It is understandable that client 3's trend is not seen in the "Converted IO Server, NIO Client" case considering the large number of times that MOSIX interfered.

A special thanks goes out to Carlo Segre for use of the cluster.

Link-back to main entry: NIO and SSL.

Are we doing it again?

Kris mentioned something that I hear all the time in regards to SOA's:

it's probably something you could implement using reliable JMS topics

(I'm pulling this slightly out of context but it's relevant regardless.) To developers that have kept their eyes open for at least part of the past few years, SOA's will be "yeah, so what?" or "I can just do / I am already doing that with [blah]". For example, an enterprise service bus (ESB) can be considered to be MOM (message oriented middleware).

Is "ESB" just another TLA (three letter acronym) that business people use to make themselves appear to be more intelligent? Maybe just a little. But really it's wrangling in a whole bunch of existing ideas (and some new ones like WS-*) and putting it under one umbrella. So if you get that deja-vu feeling you shouldn't feel uneasy.

Rather than spouting out more goop, just the links below to get you a feel for what's going on:

Pragmatic Programmers

I recently attended a CJUG talk given by Dave Thomas of The Pragmatic Programmers regarding decoupling code. This was a very well put together talk that was able to reach both novice and advanced developers. Based on this talk I am seriously considering purchasing some of the books that they publish.

Thank you Dave for an excellent talk.

Setting a flag in the case of an exception

There are a number of cases where something needs to be done only in the case where an exception is thrown (checked or not). A first pass on this would look like:

    ...
    // allow the user to do something.  If it fails for any reason 
    // the error flag must be set so that further operations are not
    // attempted.
    try
    {
        doSomething();
    } catch(final Throwable t)
    {
        // some exception has been thrown; set the error flag.
        error = true;

        // continue the exception
        throw t;
    }
    ...

The problem with this is that unless the method signature includes throws Throwable you're out of luck. To circumvent this, I do the following:

    ...
    // allow the user to do something.  If it fails for any reason 
    // the error flag must be set so that further operations are not
    // attempted.
    boolean exceptionThrown = true; // set to false -only- if successful
    try
    {
        doSomething();

        // no exceptions were thrown
        exceptionThrown = false;
    } finally
    {
        // if there was an exception thrown (exceptionThrown will have
        // been set to false if an exception was -not- thrown) then set
        // the error flag.
        if(exceptionThrown)
            error = true;
        /* else -- there was no exception thrown */
    }
    ...

Are there any better techniques out there or is this acceptable?

MBeans

Some quick notes on JMX and XML descriptors.

I don't see anything about standardizing the XML format which is very surprising. Personally, I think the XMBean looks the most palatable.

Currently there is only XDoclet support for XMBean. Modeler 1.1 mentions future XDoclet support. JMX is one of the few "Rob approved" XDoclet uses since it is not a "let's use a new technology everywhere it could possibly be applicable and more often than not, not applicable" case (we'll save that rant for another day).

Update (August 13th)

My XDoclet statements above may be a bit misleading. The JMX XDoclet task will write out standard JMX interfaces (which is very convenient). It will also write out XMBean and JBoss <servicefile>-service.xml files (along with a few other things). I don't want to give the impression that there is no XDoclet support for standard MBeans. And yes, I'm confusing XDoclet tag support with XDoclet Ant task support, but to me and the way I use them, they're completely coupled and without one, the other is uninteresting.

Input / OutputStream NIO wrapper to faciliate Java 1.4 SSL

As was alluded to in the main NIO and SSL entry, I have made convenience code available at:

    http://www.realityinteractive.com/software/oss/index.html

Refer to the release notes for information about what is been made available. If you have any comments or questions, just post a comment and I will respond as soon as possible.

It is not mentioned in the source or readme (I will rectify this shortly) that the intention for the conversion is specifically for long running clients. No thought has been given to "fast attack" clients or server (e.g. HTTP).

Performance results are available through the following links:

Link-back to main entry: NIO and SSL.

NIO CharsetDecoder

I am using a NIO CharsetDecoder to covert from bytes to chars in a UTF-8 environment. I received the following CoderResult error:

MALFORMED[1]

OK, that's helpful. After a little code splunking I determined that this means that the error is "malformed" (pretty obvious) and the length is "1" (not so obvious).

What's interesting about the CoderResult is that not only does it not fit any other paradigm used in the SDK but telling me the length of the erroneous input is, for all intents and purposes, useless. What would have been more helpful is to have included the position in the input buffer at which the malformed result occurred. Luckily CharsetDecoder.decode() advances the buffers as it reads so that you can use its current position as a guide (I should point out that this is mentioned in decode()'s javadoc).

Now I just need to determine why bytes that are supposedly UTF-8 have a value of -82. Uuugh!

Since my problem is clearly not on my end, I have added:

decoder.onMalformedInput(CodingErrorAction.REPLACE);

to circumvent the problem. This will use the CharsetDecoder's replacement value to replace any malformed characters.

AOP

There has been a lot of press around Aspect-Oriented Programming (AOP) and Software Development (AOSD). Every time I read an article such as this one the QA guy in me shudders uncontrollably. How can I possibly resolve the risk associated with AOP with the benefits that it is purported to provide? Also, given the inherent decoupled nature of AOP from the actual code (using, for example, deployment time AOP or byte-code based AOP), how can one effectively perform change managment?

Recently, I attended a JBoss discussion in hopes that it would quell some of my AOP concerns. Instead, the exact opposite occurred. Scott Stark managed to scare the bejesus out of me with transactions and protocol concerns being injected at deployment.

  • How in the world can I test and certify a single deployment of my application if significant and complex components are deployment specific?
  • Can I repackage this deployed application after testing and certification so that I'm guaranteed my clients will receive the same application?
  • How can debug a stack trace that I get back from a client?
  • How can I reproduce the client's environment in my test lab?

I know that these "advances" provided by AOP sound great to the trench developer (to which Mr. Stark was directing his discussion) that would normally have to struggle to create this functionality but there are clearly maintenance concerns with these approaches that have yet to be addressed.

Rickard Öberg voices some of my current concerns but unfortunately, like most developers, he limits it to "testing". Testing isn't the only concern; it's the full product life-cycle. I typically associate a 5 to 1 ratio of maintenance and debugging time to initial development time on any piece of complex code (where I will leave complex undefined here) throughout its lifecycle. If AOP is only addressing the "1" part of that ratio while increasing the "5" part then that's pretty crappy!

This thread (based on Rickard Öberg's blog entry) has some interesting insights. Do check other months for follow ups to the thread or related threads. [The AOSD links go down from time to time.]

People have spent a good deal of time claiming the programmatic benefits of AOP, but now it is time to start looking forward at debugging, maintaining, changing and growing AOP based code.

Contracts

I'm interested in an SOP (service oriented platform) for some of the work that I'm currently doing. It would make my life much easier if there was a container with which I could register my services that would take care of lifecycle concerns.

After doing a little research to see what's going on out there I started looking at JBoss's org.jboss.system.Service interface as well as their org.jboss.deployment.Deployer. This is the Service interface:

/**
 * The Service interface.
 */
public interface Service
{
   /**
    * create the service, do expensive operations etc 
    */
   void create() throws Exception;
   
   /**
    * start the service, create is already called
    */
   void start() throws Exception;
   
   /**
    * stop the service
    */
   void stop();
   
   /**
    * destroy the service, tear down 
    */
   void destroy();
}

(The above code is available under the LGPL.)

Do you notice anything missing from the above interface? What's the threading contract?!? Should start() start its own thread if necessary? Does the container provide a thread to start() so that it can manage the lifecycle better and ensure that a faulty start() would not block the entire infrastructure? Etc. After a few minutes of code splunking I discovered that it's just simply undefined (the assumption is that it's the first case).

I'll spare everyone the rant and I will just say: Please document the complete contract on important interfaces. When you write javadocs, ask yourself what would someone need to know that has never seen the code. Attempt to place yourself into their shoes and you will likely end up with more useful javadocs.

More NIO depression

In my persuit of a 1.4 NIO + SSL solution I had a momentary glimmer of hope in SSLServerSocket.getChannel(). This would allow me to registed an accept Selector to watch for connections and then I could use the SSL server socket to accept them. Unfortunately, the javadocs for getChannel() read:

A server socket will have a channel if, and only if, the channel 
itself was created via the ServerSocketChannel.open() method. 

This was confirmed with a trivial test. At first I thought that I was cut off at the knees. I now believe that I have been cut off at the torso.

I should mention that because of java.net.ServerSocket.accept():

IllegalBlockingModeException - if this socket has an associated 
channel, and the channel is in non-blocking mode.

I would have been screwed in any case but at least getting at the channel would have made me feel better.

Link-back to main entry: NIO and SSL.

Try - finally performance problems

This blog entry mentions serious performance concerns regarding try - finally blocks. I have yet to do any experimenting on my own but if this is true, then that sucks!

The angers of not having a common interface

It boils the blood that the pair javax.net.ssl.SSLSocket and javax.net.ssl.SSLServerSocket as well as the pair javax.net.ssl.SSLSocketFactory and javax.net.ssl.SSLServerSocketFactory do not have common interfaces. You have to have separate and completely identical code to configure each socket type as well as set the enabled cipher suites.

These interface-type defects and inconsistencies are common throughout the package hierarchy. I was hoping that the next major release of Java would make a concerted effort to clean these up but it looks like that's not going to happen. Phooey!

Note to self: file RFE on Java bug parade for these interfaces.

Link-back to main entry: NIO and SSL.

Don't forget to set the cipher suite!

I was attempting to use a vanilla SSL server and client socket (such as outlined in this article) but kept getting the dreaded:

javax.net.ssl.SSLException: No available certificate corresponds 
to the SSL cipher suites which are enabled.

The usual searches turned up a million posts about junk I already knew. The JSSE ref guide is great for people that already know what they're doing an is therefore self deprecating.

The long and short of it is that if you use a default SSLServerSocketFactory and create a socket then you must have an anonymous cipher suite installed. For example:

final SSLServerSocketFactory sslSocketFactory = 
    (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
final SSLServerSocket sslServerSocket = 
    (SSLServerSocket)sslSocketFactory.createServerSocket(port);

// use an anonymous cipher suite so that a KeyManager or TrustManager
// is not needed
// NOTE:  this assumes that the cipher suite is known.  A check -should-
//        be done first.
final String[] enabledCipherSuites = { "SSL_DH_anon_WITH_RC4_128_MD5" };
sslServerSocket.setEnabledCipherSuites(enabledCipherSuites);

A unless you do the same on the client side, you will receive the following:

javax.net.ssl.SSLHandshakeException: no cipher suites in common
javax.net.ssl.SSLHandshakeException: 
    Received fatal alert: handshake_failure

Link-back to main entry: NIO and SSL.

Debugging JSSE

To aid in debugging JSSE (J2SDK 1.4 and greater) use:

-Djavax.net.debug=all

The usefulness of this cannot be expressed in mere words.

Your Java security IQ

While looking for the current paradigms on storing passwords in Java I stumbled on this Security IQ Test. It's a bit thin but at least you can get a feel for if you know what's going on at a fundamental level. Perhaps the best part is the answers provided after you get your score.

This is also an interesting thread.

The question that I currently have is: what is the correct techique for obtaining passwords from a configuration file? Currently I store system passwords in an encrypted properties file. Do I have to read and decrypt the properties file each time I need the passwords? I don't think that just reading the passwords once on start makes sense (for the same reason that you use char[] over String for storing the password).

Array .clone() or System.arraycopy()?

I was doing some work this morning with passwords stored as char arrays when I reverted to my C upbringing and wrote the following:

final char[] passwordCopy = new char[password.length];
System.arraycopy(password, 0, passwordCopy, 0, password.length);

I stopped myself and said: Hey! Why am I doing that when arrays have a convenient .clone() method on them?!? I rewrote the code to be the following:

final char[] passwordCopy = (char[])password.clone();

The QA side of me really likes the latter approach as it has a much lower risk associated with it (i.e. there are fewer ways to make a mistake), but the performance side said Whoa! Let's take a look at performance first!

I was going to write up a quick test but the lazy side of me went to Google first. This page has a nice test and performance numbers. The shocking result is System.arraycopy() vs. a for loop. Based on a few JVM's I tried (all on win32) I get the following normalized results:

          .clone():  2.26
System.arraycopy():  1.27
        for-loop():  1.00
Shocking revelation

I was talking with another developer the other day and he revealed an interesting piece of information: he believed that comments and code style were a matter of personal choice. To me this was like believing that the world was flat and then having someone say that it's round. All of that time I spent perplexed wondering why I couldn't see things from long distances over a "flat" plane finally become crystal clear. Learning that developers may believe comments and code style are a matter of personal choice has allowed me to understand and put into perspective a number of other conversations that I have had with developers.

Hypothesis 1.1

Code comments and style are a function of quality.

This is currently my running hypothesis that I am attempting to prove through empirical evidence. My non-scientific research has shown it to be true. The difficulty in firmly establishing quantitative evidence for this hypothesis stems from the fact that, for example, diligently and effectively commenting code intrinsically changes ones approach to coding. In other words, you cannot separate out the processing of adding and maintaining comments without changing the nature of how one programs.

Self commenting code

In an attempt to dispel the "I don't need to comment my code since if the code is written clearly enough it should describe itself" theory, I present the following:

Definition 1.1

The purpose of code comments is to present intent.

Definition 1.2

A software defect is a deviation from intent. This definition does not make a distinction between implicit (i.e. expected but not defined in a requirement) and explicit (i.e. defined in a requirement) intent.

Theorem 1.1

Code is incapable of sufficiently presenting desired intent.

Proof   I will provide an indirect proof of Theorem 1.1 by assuming "code is capable of sufficiently presenting desired intent" and obtaining a contradition. Choose a section of code that contains defects. By Definition 1.2 this section of code does not correctly describe the intent. QED

Notice that Theorem 1.1 contains the word desired. This is necessary to distinguish between the intent that a section of code with defects presents and the intent that is required. Also notice that Theorem 1.1 contains the word sufficiently. Later entries will expound on this in more depth but for now it will suffice to say that code utilizing crafty programming may obfuscate intent.

I do acknowledge that for those who use the "I don't need to comment my code since if the code is written clearly enough it should describe itself" to mean "I'm too cool / talented / whatever to comment" or to cover for "I'm too lazy to comment" that my argument will have fallen on deaf ears. I'm getting to you next!

Pipe selector problems

As if the previous java.nio.channels.Pipe inconsistencies weren't enough, on both Linux and Windows it appears that you have to drain a pipe's source before you can write to the sink again. Again, this is a case that falls under the system-dependentness mentioned in Pipe's javadoc. Poopy I say!

Update

After I determined that the write selector was lying to me on Linux, and after pouring over Stevens' Advanced Programming in the UNIX Environment to refresh my memory on pipe() (which Linux uses), it turns out that the pipe does not require drain-then-fill. Again, the write selector is lying (which appears to be a known "issue" with Linux's select() on a pipe()). Windows remains drain-then-fill.

Update II

It seems that the results of drain-then-fill are dependent on how the sink is filled. If the sink is filled one byte at a time, then neither Linux nor Windows is drain-then-fill but Linux will still have an inaccurate write selector. If the sink is filled in 8k chunks, then Windows will exhibit a drain-then-fill requirement; Linux is never drain-then-fill.

Closing thoughts

Given that Linux's write selector is not accurate and always returns "none available" when there is data in the pipe (but will always return "go ahead" when the pipe is empty), it is nearly impossible to generically replace a file or network channel with a Pipe.SinkChannel. Rob angry good!

Link-back to main entry: NIO and SSL.