Skip to content
This repository was archived by the owner on Sep 25, 2026. It is now read-only.
This repository was archived by the owner on Sep 25, 2026. It is now read-only.

Blob.reload() does not work as intuitively expected #149

Description

@dmitry-fa

Documentation for Blob.writer(BlobWriterOption...) recommends the following way to upload information:

 byte[] content = "Hello, World!".getBytes(UTF_8);
 try (WriteChannel writer = blob.writer()) {
   try {
     writer.write(ByteBuffer.wrap(content, 0, content.length));
   } catch (Exception ex) {
     // handle exception
   }
 }

But doc is silent on how to renew the blob object, which is a bit tricky because neither blob.reload() nor storage.getBlob(blob.getBlobId()) does not help. Behavior varies depending on versioning setting for the bucket.

If versioning is enabled:

Attempt to reload as recommended:
blob.reload(Blob.BlobSourceOption.generationNotMatch()) causes StorageException '304 Not Modified'

blob.reload() returns the same blob.
storage.get(blob.getBlobId()) returns the same blob (that seems very confusing).
And only storage.get(blobId) returns the updated blob.

If versioning is Suspended:
before upload: blob.getContent() returns an empty array
After upload: blob.getContent() throws StorageException: 404 Not Found , No such object
storage.get(blob.getBlobId()), blob.reload() and blob.reload(Blob.BlobSourceOption.generationNotMatch()) return null.

And again only storage.get(blobId) returns the updated blob.

Activity

  1. dmitry-fa commented on Feb 26, 2020

    @dmitry-fa
    ContributorAuthor

    For those who want to play around with it:
    Setting versioning on a bucket with gsutil:
    #> gsutil versioning set on gs://bucket_versioning_on
    #> gsutil versioning set off gs://bucket_versioning_off

    The code:

    package storage;
    
    import com.google.cloud.WriteChannel;
    import com.google.cloud.storage.*;
    import java.nio.ByteBuffer;
    
    import static java.nio.charset.StandardCharsets.UTF_8;
    
    public class Writer {
    
        public static void main(String... args) throws Exception {
    
            Storage storage = StorageOptions.getDefaultInstance().getService();
            String blobName = "my-blob-name";
            String bucketName = "bucket_versioning_off";
    
            BlobId blobId = BlobId.of(bucketName, blobName);
            byte[] content = "Hello, World!".getBytes(UTF_8);
            BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
            Blob blob = storage.create(blobInfo);
            System.out.println("-- initial --");
            System.out.println(blob);
            System.out.println("size: " + blob.getContent().length);
    
            try (WriteChannel writer = blob.writer()) {
                writer.write(ByteBuffer.wrap(content));
            }
            System.out.println("\n-- right after upload --");
            System.out.println(blob);
            try {
                System.out.println("content '" + new String(blob.getContent()) + "'");
            } catch (StorageException e) {
                System.out.println("content " + e.getMessage());
            }
    
            System.out.println("\n-- after blob = blob.reload(Blob.BlobSourceOption.generationNotMatch()) --");
    
            try {
                blob = blob.reload(Blob.BlobSourceOption.generationNotMatch());
                System.out.println(blob);
            } catch (StorageException e) {
                System.out.println("exception: " + e.getMessage());
                System.out.println("\n-- after blob = blob.reload() --");
                blob = blob.reload();
                System.out.println(blob);
            }
    
            if (blob != null) {
                System.out.println("\n-- after blob = storage.get(blob.getBlobId()) --");
                blob = storage.get(blob.getBlobId());
                System.out.println(blob);
            }
    
            System.out.println("\n-- after blob = storage.get(blobId) --");
            blob = storage.get(blobId);
            System.out.println(blob);
        }
    }
    
  2. added
    type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.
    priority: p2Moderately-important priority. Fix may not be included in next release.
    and removed
    🚨This issue needs some love.
    triage meI really want to be triaged.
    on Mar 2, 2020
  3. changed the title [-]WriterChannel does not update blob's information when upload has finished[/-] [+]WriteChannel does not update blob's information when upload has finished[/+] on Mar 23, 2020
  4. self-assigned this
    on May 8, 2020
  5. changed the title [-]WriteChannel does not update blob's information when upload has finished[/-] [+]Blob.reload() does not as intuitively expected[/+] on May 8, 2020
  6. dmitry-fa commented on May 8, 2020

    @dmitry-fa
    ContributorAuthor

    Blob.reload() is just a shortcut method for Storage.get(BlobId). BlobId includes bucket,name and generation. If generation is not specified Storage.get(blobId) returns the latest version. If generation is given and differs from the latest version the output depends on the versioning setting of the bucket: If versioning is enabled Storage.get(BlobId) returns not the latest version, if disabled then null is returned, which means: 'object not found'. Blob.reload() always use generation, so if the content is changed reload() will never return the latest version. Such behavior is not intuitively expected.

    Possible fix is to make Blob.reload() to not include generation in the get request.

  7. changed the title [-]Blob.reload() does not as intuitively expected[/-] [+]Blob.reload() does not work as intuitively expected[/+] on May 12, 2020
  8. elharo commented on May 12, 2020

    @elharo
    Contributor

    What URL does that sample code come from? It has an issue.

  9. dmitry-fa commented on May 12, 2020

    @dmitry-fa
    ContributorAuthor

    Which sample code do you mean?

  10. elharo commented on May 12, 2020

    @elharo
    Contributor

    byte[] content = "Hello, World!".getBytes(UTF_8);
    try (WriteChannel writer = blob.writer()) {
    try {
    writer.write(ByteBuffer.wrap(content, 0, content.length));
    } catch (Exception ex) {
    // handle exception
    }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: storageIssues related to the googleapis/java-storage API.priority: p2Moderately-important priority. Fix may not be included in next release.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions