|
|
|
||
|
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. I typically associated a "magic" factor to anything that's in the core Java classes. Take for example how NIO's I assumed incorrectly that It's actually unfortunate that |
|
||
|
I have voiced my concerns in the past about maintaining and growing code that uses AOP. I am not one to quickly shun a technology and never look back. I constantly review technologies. I was reading this paper on recovery oriented computing (ROC) which is in line with my autonomic persuits and they mentioned FIG. FIG is fault injection in glibc. If you've ever tried to set up a networking test where When I read about FIG, the little 10W light blub in my head flicked to a dim glow. Use AOP to do fault injection! Unit testing, even if the developer of the unit test is not the developer of the code being tested, is of limited use. No matter how hard we might try, unit tests tend to be parallel to the concerns of the code rather than orthogonal. In other words, unit tests tend to miss many of the bugs that aren't directly in line with the use / purpose of the code. For example, if you have a class that reads data from the network and writes it back then the unit tests are typically going to align themselves with that -- they will ensure that stuff in matches stuff out. But what about the orthogonal concerns, most of which involve difficult to trigger network concerns? (Yes, I'm horrible at giving motivational examples.) Attempting to write code that will cause exceptions to occur is likely to require a harness that's bigger than the original code and test combined. And how do you guarantee the validity of the harness? In other words, who tests the tests? The coast guard? I don't think so! Using AOP (or just On a parallel note, this article brings up some interesting uses of AOP for exception handling. |
|
||
|
For reasons still left unstated I have been doing research in autonomic computing. For those unfamiliar, here are some interesting links:
|
|
||
|
I'm a constructor-based dependency injection kinda guy but with everyone always talking about setter-based dependency injection I started to question my approach. When Dave Thomas reminded me about class invariants I knew that my constructor-based approach was the right one. From Wikipedia: ...a class does not allow use of all possible values for the state of the object, only those that are well-defined by the semantics of the intended use... and The main purpose of a constructor is to establish the invariant of the class, failing if the invariant isn't valid. You know that you should use constructor-based dependency injection when the dependency answers the question is this a class invariant. |
|
||
|
For those that know me, seeing a title like Things that really tick me off elicits a large groan and probably some wonder as to if there is enough storage available on the planet to house all of them. But I digress. I have always hated the term "cookie" with regard to the state mechanism used with HTTP. It's a token people! Call it what it is and there's less opportunity for confusion. Well, it seems that Sun has one-upped that with muffin (no, really).
Whee! |
|
||||||||
|
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:
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
With SSL
Analysis (see the other previous tests for more analysis):
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. |
||||||||
|
||||
|
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" uses the standard Java IO (from the
Analysis (see the previous tests for more analysis):
A special thanks goes out to Carlo Segre for use of the cluster. Link-back to main entry: NIO and SSL. |
||||
|
||||
|
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" means that the component was created using only NIO. "IO" uses the standard Java IO (from the
Analysis (see the previous tests for more analysis):
A special thanks goes out to Carlo Segre for use of the cluster. Link-back to main entry: NIO and SSL. |
|
||||||
|
I finally had an opportunity to perform some performance testing on the source I made available. A few notes about the testing environment:
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" means that the component was created using only NIO. "Converted IO" is an NIO wrapper to 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.
A special thanks goes out to Carlo Segre for use of the cluster. Link-back to main entry: NIO and SSL. |
|
||
|
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:
|
|
||
|
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. |
|
||
|
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
...
// 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? |
|
||
|
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 |
|
||
|
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. |
|
||
|
I am using a NIO 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 Now I just need to determine why bytes that are supposedly UTF-8 have a value of Since my problem is clearly not on my end, I have added: decoder.onMalformedInput(CodingErrorAction.REPLACE); to circumvent the problem. This will use the |
|
||
|
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.
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. |
|
||
|
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
/**
* 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 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. |
|
||
|
In my persuit of a 1.4 NIO + SSL solution I had a momentary glimmer of hope in 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 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. |
|
||
|
This blog entry mentions serious performance concerns regarding |
|
||
|
It boils the blood that the pair 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. |
|
||
|
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
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. |
|
||
|
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. |
|
||
|
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 |
|
||
|
I was doing some work this morning with passwords stored as 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 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
.clone(): 2.26
System.arraycopy(): 1.27
for-loop(): 1.00
|
|
|
Unless otherwise expressly stated, all original material of whatever nature created by Rob Grzywinski and included in this weblog and any related pages, including the weblog's archives, is licensed under a Creative Commons License. |