The value I'm trying to retrieve is a JPEG image that is 36621 bytes long. When I query the length of the object in CLP using
it reports the length correctly. However, when I retrieve it in Java (using either Blob.getBytes() or Blob.getBinaryStream()), I get 36622 bytes, where the first byte is an extra 0 and the remaining bytes appear to be the expected JPEG contents. If I add an extra byte to the end of file that was the source of my BLOB value so that it's now actually 36622 bytes long, and then update the BLOB column with it, I again get 36622 bytes returned to my application, but the first byte is still an extra 0 and the extra byte I added is truncated. If I add one more byte to the file, then I get 36624 bytes returned to my application. So the pattern is that Blobs always return a value that is an even number of bytes in size, and always with an extra 0 prepended to the expected contents.
select length(companylogo) from esp.contractors
I am running under a 64-bit JDK (Oracle 1.6.0_27) using the latest DB2 JDBC drivers I could find (v9.7fp4_jdbc_sqlj, with driver files dated 3/31/2011). I have tried both the JDBC3 and JDBC4 drivers and get the same results with both. I strongly suspect based on the nature of the error and the seeming rarity of reports of the problem that this is a 64-bit issue. I will re-create my development environment on my 32-bit Windows XP laptop tomorrow and see if the problem doesn't manifest itself there, which will prove whether or not it's a 64-bit-only problem. If it works there, I'll try changing to a 32-bit JDK on my Windows 7 machine and see if that solves the problem there, too. If it is a 64-bit issue, I can't really pinpoint where the problem lies, yet. It could be in the JDBC driver, Glassfish or even the JDK itself.
The one peculiarity in all this is that I first noticed a strange problem running a BIRT report that retrieves the same BLOB values from the database that are being retrieved incorrectly by my application. The report fails with an OutOfMemory error when I try to execute it using a JDBC Connection obtained from Glassfish/JNDI, but when I let it open its own DB2 connection using the same drivers it works fine. That would seem to rule out a problem caused by the 64-bit JDK itself, since the report is still executing under that JDK when it succeeds. Yet why a JDBC connection opened by Glassfish/JNDI would behave so differently than one opened directly by a Java application is a mystery. I will post more after I test everything in a 32-bit environment.