Archive for the ‘java’ Category

JAI

Tuesday, February 2nd, 2010

I have a few ‘wonderful’ things to say about JAI (Java Advanced Imaging).

Been having a few issues with it recently. The first one was that the users were able to view B&W (i.e. 2-bit) images just fine, but when they tried to view GreyScale images that had been submitted, it exploded with an error message regarding the class javax.media.jai.operator.SubsampleBinaryToGrayDescriptor. Looking at the name, it’s not awfully surprising that it couldn’t cope with Greyscale Images.

I mean, you provide it with a Greyscale Image, tell it it’s a B&W image, and then expect it to convert it to a Greyscale Image… No, that doesn’t quite work. The entire reason we were using that Descriptor, as far as I can tell, is that it produced reasonable-quality scaled-down images. And it was good, until the client started scanning images in Greyscale.

That was the problem. Finding that was fairly simple. Finding a solution, on the other hand, proved considerably more elusive. I initially tried the javax.media.jai.operator.ScaleDescriptor class, but that generated scaled-down images of appalling quality, which is probably why we switched to using SubsampleBinaryToGrey in the first place.

So I wasn’t able to use that, and looking at the JAI JavaDocs, nothing leaped out at me as being a reasonable solution. Took quite some time until I eventually found this post, which pointed me here. The second link provides a reasonable overview of Image Scaling issues, and made some amount of sense. The first link provides links between the operations discussed and the JAI Descriptors to use. Unfortunately, I feel that it needs a slightly better description of how these operations map, especially for people like me, who aren’t terribly knowledgeable about image processing.

For those who are curious, I eventually managed to make the link between the Area Mapping description in the second link, and javax.media.jai.operator.SubsampleAverageDescriptor. That seems to have solved my problems, but more testing needs to be done. Anyway, if you need to scale images with Java, use SubsampleAverageDescriptor. It will save you huge amounts of pain. And hopefully this post will save you huge amounts of pain too. JAI is just not an awful lot of fun.

I mentioned at the start that I’ve had a ‘few’ problems with JAI. The above is one, and the other is a really, really bizzare one.

Basically, most of the time, people were able to upload images without a problem. Most of the time. Sometimes, however, they would run into problems where an image would simply fail to upload. Looking at the errors, I saw that it was failing in TIFFFaxDecompressor (all our images have to be uploaded as TIFF files, and a thumbnail is generated when the image is uploaded).

Bugger, I thought, and started investigating. Initially, I had no idea why it was even using a Fax decompresser. Those well-versed in their TIFF lore will probably have guessed that it is because they were compressed with the Group 3/4 Fax Encoding. When I figured that out, I tried uploading with different encodings. They all worked. It was only Group 3/4 that was failing. That wasn’t good. Sent me off on a wild goose chase (and I really, really hope that anyone with the same problem finds this post and magically solves all their problems).

After following that pattern for a while, I eventually noticed that when I re-deployed to our application server (Glassfish 2.1.1), it broke. If I shut down and restarted Glassfish, everything was OK. But if I undeployed the application and then redeployed it while the Application Server was still running, then this error started happening again.

Beat head against brick wall.

Something that should have been extremely obvious when we started using JAI, but that wasn’t picked up (I wasn’t with the company when we started making use of JAI) is that it should be installed the system JRE. That’s important. The System JRE.

It should not be included as part of an Application.

And that’s where we went wrong, originally. Installing JAI into the System JRE (Sun Java 1.6, for reference) magically fixed the problem…

Moral of the story?

Always read the goddamn instructions.

Subversive Bug – Too many SVN projects from one source breaks it

Wednesday, October 28th, 2009

Been using Subversive as part of Eclipse for a while now, and it’s generally been good to me. Today, however, I ran across a funny problem when I attempted to check out a new project from the company repository:

Could not set property: org.eclipse.team.svn location. Value is too long.

Which was a little… odd, as I couldn’t recall changing anything in Eclipse that could have caused that. Our SVN repo is located on a server with a very short name, and the paths I was checking out were all < 50 characters. Very strange.

Eventually found this bug, but not until after I’d filed one of my own (since it didn’t come up on a Google Search for some reason), and it basically amounts to concatenating the paths of all the projects pointing a particular repository in a particular workspace together, far as I understand it. Damned if I know why they thought that was a good idea, but there we go. That was in turn resulting in a property exceeding the 4096 character limit Eclipse imposes on them… Buh. You’ll probably need the latest release (0.7.8.I20091023 at the time of writing) in order to fix it. If you can’t upgrade, then you have two solutions: Delete some of your existing projects, (maybe…), or create a new workspace.

Unhelpful Error Messages

Wednesday, October 28th, 2009

Trying to update one of our projects to use the Ivy [1.0.0,) syntax for finding dependencies today, and discovered a few fun facts about Linx and Ivy:

  1. Despite having read/write permissions to a directory, I can’t actually change it’s permissions. Bugger. So what do I do? I copy the directory (so I’m the owner…), then delete the original directory, then rename my one back. What the hell is the point of not letting me change the permissions?!
  2. Ivy would appear to include information like the File’s owner it its hash of the file. I’m not 100% sure on that, but it would seem to be the case, as I made no changes to the ivy.xml file I was working with, just copied it around a little.
  3. IvyDE provides an absolutely useless error message: “Can’t resolve Dependency org#name;rev”. Wonderful. Why can’t you resolve it? At first, it was because the permissions on the server were set incorrectly (remember, you need execute (+x) permissisons to list a directories content…), then it turned out that the hash had failed. Now, IvyDE can’t do much about the first one, as it couldn’t even see the 1.0.1 directory. However, it could have told me that the hash had failed. Would have saved me a fair bit of time. I only found out because I ran the build on the command line… Trivial to fix once I realised the problem, but still annoying.

So yeah… That wasn’t exactly fun.

HttpClient & Java 5

Thursday, October 8th, 2009

For some reason, Java 1.5 won’t compile code if it can’t find the associated annotations for an exisiting class file.

Note that I’m not talking about it being unable to find an annotation you’ve attached to the source code you’re compiling. That’s fine. I’m talking about it being unable to find annotations attached to existing classes (like, say, HttpClient) and then refusing to compile the class because of that.

Now, I’m faily sure that they don’t impact anything to do with the runtime-code given that Eclipse ran it all without a problem. And apparently Java 6 will only give a warning. But Java 5 throws an error and tells me to file a bug report with Sun… Which is extremely unhelpful since it’s not actually a Sun problem. I just needed to include the JAR file on my compile path…

Anyway, the exact error I was getting was:

[javac] An exception has occurred in the compiler (1.5.0_19). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
[javac] com.sun.tools.javac.code.Symbol$CompletionFailure: file net/jcip/annotations/GuardedBy.class not found

I saw a bug report in the Java Bug Repo that mentioned Java pointing out the incorrect class when this happened, so I’m glad that’s fixed. Anyway, this is a known issue with HttpClient, as can be seen here. To download the JCIP Jar, wich has the annotation net.jcip.annotations.GuardedBy, go here.

Hopefully this will help someone (or me, if I ever forget what the hell I was thinking).

Java and Operating System Architecture

Wednesday, September 30th, 2009

You’d think that Java would report something simple, like, say, 32-bit or 64-bit Architecutre in an operating-system independent fashion. But no. It doesn’t…

Instead, it seems that both Linux and Windows report themselves as having an os.arch property of amd64 when running 64-bit versions, but they have a different idea about how to report their 32-bit versions – Linux reports itself as i386, while Windows reports itself as x86. Feh.

Not really a major problem, and you’d think that since I was working with operating-system specific stuff anyway (SWT in this case) it wouldn’t be a problem. And it’s not, really. To be honest, though, I would have hoped that Java would have provided some sort of consistent names for the various architectures, if possible.

Alternatively, this could just be a difference between XP (32bit) and Windows 7 (64bit), but I can’t test that right at this moment.

And did this cause problems for me? Yes, but only a minor one, thankfully, as it was spotted by my workmate running 32bit Windows, long before it reached production, and I just to had to quickly rebuild the application, with the fixed arch attribute in the JNLP file. So yeah, could have been worse.

Apache XML-RPC

Monday, September 28th, 2009

Hmm…

This one is fun: I’ve been working on making one of our applications deploy via JNLP, and also fix it so that it works on Linux. Yes, I know I’m writing it in Java, but for some reason the way SWT was being used prevented it from working on Linux. I forget the exact fix, if anyone is interested I’ll see if I can find it. Anyway, once I did that and had some other people around the office have a look, we noticed that it was being really, really slow. Not all the time, and it seemed to be worst on Linux.

Looking at the logs, it seemed to mostly relate to when XML-RPC was being called. Looked through the XML-RPC changelog, and found a major bug fix that appears to be the one I want: 6th from the bottom of the 3.1 list, which meant it was waiting 30 seconds (the timeout value we set), despite the response having arrived. And funnily enough, upgrading to 3.1.2 seems to have fixed it…

Moral of the story? If the library you’re using was published 3 years ago, then it might be time to upgrade.