oracle/oci-java-sdk

Failed to upload big file 2.5 GB to OCI storage bucket after upgrade OCI SDK to 2.44.0

Kamosh opened this issue · 6 comments

HI all,

We have a code that uploads relatively big files > 2GB to object storage.
The ObjectStorageClient had no problems with upload untill we updated the OCI SDK to version 2.44. 0

The ObjectStorageClient created using code

ObjectStorage objectStorageClient = ObjectStorageClient.builder()
                .clientConfigurator(new JerseyDefaultConnectorConfigurator.NonBuffering())
                .region(regionValue)
                .build(provider);

fails on

Caused by: java.lang.OutOfMemoryError: Required array size too large

The ObjectStorageClient created using code

ObjectStorage objectStorageClient = new ObjectStorageClient(provider);
objectStorageClient.setRegion(regionValue);
return objectStorageClient;

fails on

Caused by: java.lang.IllegalStateException: Connection pool shut down
	at org.apache.http.util.Asserts.check(Asserts.java:34)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:269)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:176)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
	at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:483)

but in fact the root cause is also the java.lang.OutOfMemoryError: Required array size too large
To see this you will need to set the breakpoint to https://github.com/apache/httpcomponents-client/blob/rel/v4.5.13/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L368

Please find the attached simplified maven project with the test.
Only change the OCI SETTINGS part of code in ObjectStorageBigFiles with your OCI access.

ObjectStorageBigFiles.zip

Thank you,
Kamosh

Hi,

Thanks for reporting this issue. Our team will get back to you.

I need a solution for this also.

Visual Builder Studio team also needs a solution for this issue.

We're looking into this issue and will keep you posted on the updates

In the example provided above, BufferedInputStream is used for putObjectBody. This reads and buffers the whole stream into the memory which causes java.lang.OutOfMemoryError/Connection pool shut down. From the source code, the MAX_BUFFER_SIZE is Integer.MAX_VALUE - 8 whereas 2.5 GB in bytes is greater than the max buffer value, hence we see the above error. To avoid the above issue, don't wrap FileInputStream in BufferedInputStream but directly use FileInputStream as given below :

      try (InputStream fileContent = new FileInputStream(file)) {
        final PutObjectRequest.Builder putObjectRequestBuilder = PutObjectRequest.builder()
                .namespaceName(namespaceName)
                .bucketName(bucketName)
                .objectName(objectName)
                .contentLength(file.length())
                .putObjectBody(fileContent);

        final PutObjectRequest putObjectRequest = putObjectRequestBuilder.build();
        final PutObjectResponse putObjectResponse = objectStorageClient.putObject(putObjectRequest);
    } catch (IOException | BmcException ex) {
        getLog().error("Failed to upload [" + objectName + "] to bucket [" + bucketName + "]", ex);
        throw ex;            
    }

Does the above workaround resolve the issue? We'll close this issue in a week's time if we don't hear back from you. Please feel free to reopen if the problem persists