Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Problem Viewing/Downloading BLOB Data

    SmartClient Version: v9.1p_2014-06-11/PowerEdition Deployment (built 2014-06-11)

    I realize this is on the cusp of being either an Isomorphic problem, an IBM problem, or a configuration problem, but it is fairly simply stated and there is a genuine question at the end on how the functionality is implemented that you will be able to answer and help me identify where to go next.

    I should note that this is all relative to using a DB2 database environment.

    I am needing to add attachments to items. I have defined a table, a datasource and a screen definition, and everything uploads nicely such that I see the records being created in my table and the correct value populated in the BLOB field which contains the file data.

    In the example below (records.jpg), the first record is a text file containing "aaa[space][space][space]aaa", and as you can see the attachment column contains the correct representation of this data. So far so good.

    SmartGWT automatically provides the ability to either view or download these attachments, which is even better (screen.jpg).

    Except that when I attempt to either view or download, an error is thrown in the AS400 Toolbox (i.e. JDBC driver). The error is as follows:

    Code:
    === 2015-05-09 10:29:23,977 [ec-4] ERROR IpIDACall - Error executing operation: ItemAttachments_viewFile
    com.ibm.as400.access.ExtendedIOException: Resource not available.
            at com.ibm.as400.access.AS400JDBCInputStream.read(AS400JDBCInputStream.java:242)
            at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
            at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
            at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
            at java.io.FilterInputStream.read(FilterInputStream.java:107)
            at com.isomorphic.util.IOUtil.copyStreams(IOUtil.java:108)
            at com.isomorphic.util.IOUtil.copyStreams(IOUtil.java:52)
            at com.isomorphic.datasource.ISCBinaryValue.copyToOutputStream(ISCBinaryValue.java:62)
            at com.isomorphic.rpc.RPCManager.completeResponse(RPCManager.java:891)
            at com.isomorphic.rpc.RPCManager.send(RPCManager.java:635)
            at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:172)
            at com.islandpacific.gui.server.customDataSource.IpIDACall.processRPCTransaction(IpIDACall.java:66)
            at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:137)
            at com.isomorphic.servlet.IDACall.doPost(IDACall.java:73)
    .
    .
    .
    My research leads me to believe that this is caused by the LOB Locator being released when the result set closes, rather than at a transaction boundary (http://www-01.ibm.com/support/docview.wss?uid=nas8N1015966 and http://community.jaspersoft.com/questions/537427/jasperserver-setup-against-db2-running-as400).

    It seems if that really is the case I should be able to correct this by adding the hold statements=true parameter to the connection string (http://www-01.ibm.com/support/knowledgecenter/ssw_i5_54/rzahh/jdbcproperties.htm).

    However, when I do add this property I get the same result, which then makes me doubt that I am on the right track.

    Which brings me to my question: is it the case that, similar to the problem solved in the Jaspersoft forum, SmartGWT is attempting to read the blob outside of the transaction?
    Attached Files

    #2
    The problem you are seeing is a result of SmartGWT Server deferring the read of the binary stream until it is assembling the response. Note, this is not the same thing as reading the stream outside of the transaction - that would just be an error. SmartGWT's deferred reading is intentional, and is designed to ensure that the server flow presents a streaming profile where possible. In other words, we hang onto the InputStream rather than reading it, so that we can later copy it directly to the HttpServletResponse's OutputStream without requiring two copy operations and a whole load of scratch memory in the webserver.

    Unfortunately, this approach does not work with some databases. The Javadoc for the ResultSet interface states that
    All the data in the returned stream must be read prior to getting the value of any other column. The next call to a getter method implicitly closes the stream
    A few JDBC drivers impose this documented restriction, but most do not. Until today we only knew of two that impose the restriction, but it seems that the DB2/iSeries driver (or perhaps just more recent versions of it) also falls into this category. Since this restriction makes it pretty much impossible to create an efficient, streaming server flow, and since most drivers do not impose the restriction anyway, we assume we can stream by default, and fall back to a copy-via-byte-array approach when one of the strict JDBC drivers is in use.

    We have now fixed the issue for this and any future cases; conforming to the strict "read immediately" restriction can now be configured with a simple setting in server.properties. The fix will appear in nightly builds of SmartGWT 4.1p and greater as of tomorrow's builds (those dated May 12).

    Regards,
    Isomorphic Software Support
    Last edited by Isomorphic; 11 May 2015, 11:38. Reason: Removed incorrect instruction

    Comment


      #3
      Well, that's a swift and concise response. Thank you very much for addressing this so quickly. I shall be anxious to try this out.

      I assume that this same fix will be applied to SmartGWT 5.0 and up, correct (we are in the process of updating)?

      Comment


        #4
        Yes, all versions from 4.1p onwards. Note, we have removed an instruction from our last post, to avoid misleading people reading this thread in the future. It is database type, not database name, that requires the setting, and we have already set it for "db2iSeries" so you shouldn't need to do anything to make it work.

        Comment

        Working...
        X