crazed monkey

Archive for the 'java' category

RSS

Too late for an open source Java

After years of promises and speculation, Sun finally made Java open source. All I can say is that it’s much too late. Sun has made some poor design and engineering decisions over the past few years which will continue to bite Java developers in the ass. I can’t begin to tell you how much I cursed Sun’s developers over the years, most notably a few years ago when I was working with their NIO library, first in 1.4.1 then in 1.4.2 and finally in 1.5 trying to make sense of their API and their subsequent changes. I’d go into detail, but then I’d get cranky.

Would an open source Java have made my life easier during those frustrating times? Probably. Twisted Python, upon whose protocol interface I based my Java NIO sockets API, is under an MIT license and kicked Java’s ass with respect to non-blocking sockets at the time. The major advantage was, and still is, its slick design. You didn’t have to write much code in Twisted to get a non-blocking server socket running. I still have nightmares about Java’s implementation.

But all that is in the past. Open sourcing Java won’t make much of a difference to the future. Certainly, I don’t care. Thankfully, I left the Java world almost a year ago and am now working in happy Python land. I don’t miss Java one bit, nor do I miss its tools, without which programming would have been far slower. No, Java can die a slow death for all I care. I’m done with it. Hopefully.

Tags:
  • none

Posted on November 14th, 2006 in java - No Comments »

Invoking the Lazy Web for my Tomcat difficulties

As the Tomcat user mailing list has not been much help in solving two annoying Tomcat issues, I hereby invoke the Lazy Web!

The first issue involves Tomcat blocking on a call to HttpServletRequest.getSession(). This seems to only occur when I am debugging Tomcat remotely from within IDEA under Windows XP. I am using the latest version of Tomcat, JVM 1.4.1-b21 and IDEA 3.0.1. This is possibly an IDEA issue. Since the problem only seems to occur when debugging, it is not one needing an urgent solution.

The second and more annoying issue involves a mangled Content-Length header in the occasional HTTP response. When I say “mangled”, I mean that the header field does not read as “Content-Length”, but something almost like “Content-Length”. Naturally, a response without a Content-Length field violates the HTTP specifications. The content and all other header fields are never mangled—only Content-Length, only sometimes, and usually when the length of the body is non-zero.

The following code snippet illustrates how I am setting the response:

private void writeHttpContent( HttpServletResponse response, byte[] contentsOutBytes ) throws Exception
{
    response.setContentType( "application/octet-stream" );
    response.setContentLength( contentsOutBytes.length );

    // Only bother writing if there is something to write.
    if( contentsOutBytes.length > 0 )
    {
        // Grab an output stream from the HTTP response and write to it
        BufferedOutputStream out = new BufferedOutputStream( response.getOutputStream() );
        out.write( contentsOutBytes );
        response.getOutputStream().flush();
    }
}

I have tried a few variations on the above including calling flush() on the BufferedOutputStream, and closing either response.getOutputStream() or BufferedOutputStream, but with the same result. Using response.setHeader( "Content-Length", Integer.toString( contentsOutBytes.length ) ) makes no difference, as one would hope. I also eliminated the call to response.setContentLength() but that always resulted in a missing Content-Length.

Here is an example of a mangled response:

Content-Type: application/octet-stream
Content-Lengtd><b
Date: Tue, 25 Feb 2003 17:28:49 GMT
Server: Apache Coyote/1.0

To date, I have only seen this happen on our Debian Linux box running Tomcat 4.1.16-1 from testing and Sun’s J2SDK1.4.1_01-b01. This led me to believe that it could be a problem with Debian, but a post to the debian-java mailing list turned up nothing.

Naturally, the above problem cannot be reproduced but it does happen often enough to be terribly annoying for our client devices. Furthermore, I have a few Java apps hitting the servlet on a consistent basis using HTTP/1.0 and they never experience this problem. I can’t understand how this could be limited to HTTP/1.1.

If you have any suggestions—any suggestions at all—then do not hesitate to leave a comment. At this point, I’d accept chicken bone voodoo magic as a possible solution.

Update (05/15): After spending most of today and some of yesterday investigating this issue, we have determined that it was the router causing the munged bytes, always in the same offset within a packet. The router in question is a LinkSys, and will be subsequently hurled, beaten and torched sometime in the very near future.

Tags:
  • none

Posted on May 14th, 2003 in computers, java, programming - No Comments »

Things you shouldn’t be able to do in Java #312

The Fishbowl: When is a constant not a constant?. Charles Miller posts one of those “Guess what this code does” challenges, and it’s in Java. I prayed that I wasn’t right, but was sickened when I ran the code and discovered the worst. Ugh. I’m not all that surprised as sittingDuck is not really a constant, more like a variable which has been initialised to a specific value. Actually, scratch that. I just tried declaring sittingDuck as final and it still works as before. So much for objects as constants.

Tags:
  • none

Posted on January 13th, 2003 in computers, java, programming - No Comments »

Java and read timeouts

We were encountering a problem in the server code at my company whereby read() requests on a stream were blocking and never returning. This was causing periodic data retrieval within threads to hang, which would eventually eat up all available threads and lead to stale data. I tried creating a watchdog thread which would periodically loop through the data retrieval threads, determine their execution time and then call Thread.interrupt() if that value exceeded a certain limit. That didn’t seem to work as interrupt() sets a flag (which can be retrieved through the interrupted() method) if the target thread is not executing one of sleep(), wait() or join(). This did not help. As another solution, Colin found a reference in Sun’s Java Developer Connection to a system property called http.defaultSocketTimeout which would set the timeouts on HTTP connections. This did not work either, for the simple reason that they renamed the property to net.client.defaultSocketTimeout and then to sun.net.client.defaultReadTimeout and sun.net.client.defaultConnectTimeout in J2SDK 1.4.1. Using the former of those last two properties successfully set the read timeout (that being the maximum time allowed between reading one byte and then reading the next) for all connections. Of course, we would not have found this out if Colin hadn’t seen this bug (NOTE: viewing JDC bugs requires a login), which contains a link at the very bottom to the Java networking properties.

The above information is useless if you are stuck with a JVM which doesn’t support 1.4. You will have to somehow close() the underlying connection, probably from a thread which directly monitors that connection. You could also write your own streams.

Naturally, setting a property which affects all connections in your application is a bad idea, but Java doesn’t provide you with any other way unless you have access to the underlying socket, at which point you could use Socket.setSoTimeout(). There is a bug requesting the addition of non-global timeout properties for HTTP connections, but this won’t be fixed until Tiger AKA Java 1.5.

People, Java has only been around for some seven years and we’re only just getting per-connection read timeouts? Why wasn’t this done sooner? Is nobody actually using Java as it was meant to be used? Isn’t Java supposed to be a network programming language? It’s not like people don’t want this feature. I mean, look at this bug which requests the ability to set socket options on a URLConnection. That bug has been around since early 1998, has had 217 votes placed on it and is still labelled as “In progress, request for enhancement”!

Java, baby, I loves you but why you gone make me hurt you so?

Tags:
  • none

Posted on December 12th, 2002 in computers, java, programming - No Comments »

The Mind Electric’s Glue loses a user

David Watson has just made the switch from Glue to Apache Axis. I understand his pain, as everything broke on my server when I “upgraded” Glue from 2.x to 3.2. However, I managed to get it working although I was not deploying my application in a JAR, but rather a WAR, so that might have made a difference. For the record, here is what I did:

  1. Placed Glue’s config.xml in /WEB-INF/classes/electric/common/WEB-INF/
  2. Placed the standard.map file in /WEB-INF/classes/electric/common/WEB-INF/maps/
  3. Placed GLUE-STD.jar in /WEB-INF/libs/

After that, no more errors.

David makes a rather interesting statement in his entry which I’d like to comment on:

“Deployment descriptors are overrated, especially when the code can reflect a lot of the details at runtime. If I need to set parameters, I’ll do it in the code, thanks.”

As someone who has had to garner information about parameter and return types from a client’s WSDL document, I can honestly say that deployment descriptor files are certainly not overrated. Had the client we were dealing with created a proper WSDL file, I wouldn’t have had to bother them incessently with questions as to what structure the request parameters and responses took. As it turns out, some of the request and response parameters were string representations of XML documents, easily replaced with custom type declarations within the WSDL. Indeed, some of the responses were documented as arrays of “any”, which is the WSDL world equivalent of Object or void. Had the client not even provided any WSDL information and instead had the parameters hardcoded in source, as David would prefer, it would have been a nightmare, and not just an annoyance.

Don’t get me wrong, I dislike SOAP as it is heavyweight and cumbersome, but if you’re going to use it, at least use it as it was meant to be used.

Tags:
  • none

Posted on November 11th, 2002 in computers, java, programming - No Comments »