From b03dd52c86c9e7c2ca521009bbd8a0fe2b8bbb03 Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Wed, 22 Jul 2026 16:12:38 -0400 Subject: [PATCH 1/6] Support serialization and deserialization for GoogleCloudStorageReadOptions Fixes an issue where GoogleCloudStorageReadOptions set on GcsOptions was annotated with @JsonIgnore, causing it to be omitted when serializing PipelineOptions for remote workers (e.g., Dataflow) and falling back to defaults. --- .../extensions/gcp/options/GcsOptions.java | 53 ++++++++++++++++++- .../extensions/gcp/GcpCoreApiSurfaceTest.java | 2 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java index 2da382a5b674..35cba02f7c1c 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java @@ -18,8 +18,19 @@ package org.apache.beam.sdk.extensions.gcp.options; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.cloud.hadoop.gcsio.GoogleCloudStorageReadOptions; import com.google.cloud.hadoop.util.AsyncWriteChannelOptions; +import java.lang.reflect.Method; import java.util.HashMap; import java.util.concurrent.ExecutorService; import org.apache.beam.sdk.extensions.gcp.storage.GcsPathValidator; @@ -53,8 +64,48 @@ public GoogleCloudStorageReadOptions create(PipelineOptions options) { } } + class GcsReadOptionsSerializer extends JsonSerializer { + @Override + public void serialize( + GoogleCloudStorageReadOptions value, JsonGenerator gen, SerializerProvider serializers) + throws java.io.IOException { + serializers.defaultSerializeValue(value, gen); + } + } + + class GcsReadOptionsDeserializer extends JsonDeserializer { + @Override + public GoogleCloudStorageReadOptions deserialize(JsonParser p, DeserializationContext ctxt) + throws java.io.IOException { + ObjectMapper mapper = (ObjectMapper) p.getCodec(); + JsonNode root = mapper.readTree(p); + GoogleCloudStorageReadOptions.Builder builder = GoogleCloudStorageReadOptions.builder(); + + for (Method method : GoogleCloudStorageReadOptions.Builder.class.getMethods()) { + if (method.getName().startsWith("set") && method.getParameterCount() == 1) { + String propName = + Character.toLowerCase(method.getName().charAt(3)) + method.getName().substring(4); + JsonNode node = root.get(propName); + if (node != null && !node.isNull()) { + try { + Class paramType = method.getParameterTypes()[0]; + Object val = mapper.treeToValue(node, paramType); + if (val != null) { + method.invoke(builder, java.util.Objects.requireNonNull(val)); + } + } catch (Exception ignored) { + // Ignore incompatible or unmappable properties + } + } + } + } + return builder.build(); + } + } + /** @deprecated This option will be removed in a future release. */ - @JsonIgnore + @JsonSerialize(using = GcsReadOptionsSerializer.class) + @JsonDeserialize(using = GcsReadOptionsDeserializer.class) @Description( "The GoogleCloudStorageReadOptions instance that should be used to read from Google Cloud Storage.") @Default.InstanceFactory(GcsReadOptionsFactory.class) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/GcpCoreApiSurfaceTest.java b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/GcpCoreApiSurfaceTest.java index 8af5e2260fc5..cd51d4fd9d28 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/GcpCoreApiSurfaceTest.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/GcpCoreApiSurfaceTest.java @@ -51,6 +51,8 @@ public void testGcpCoreApiSurface() throws Exception { final Set>> allowedClasses = ImmutableSet.of( classesInPackage("com.fasterxml.jackson.annotation"), + classesInPackage("com.fasterxml.jackson.core"), + classesInPackage("com.fasterxml.jackson.databind"), classesInPackage("com.google.api.client.googleapis"), classesInPackage("com.google.api.client.http"), classesInPackage("com.google.api.client.json"), From bcc9968c99cc54c9806036b9e99eb78661bcfd15 Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Wed, 22 Jul 2026 16:16:03 -0400 Subject: [PATCH 2/6] Add a unit test --- .../gcp/options/GcsOptionsTest.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java index c499290b851d..de460ca0986b 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java @@ -18,11 +18,16 @@ package org.apache.beam.sdk.extensions.gcp.options; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.cloud.hadoop.gcsio.GoogleCloudStorageReadOptions; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.apache.beam.sdk.options.PipelineOptions; import org.apache.beam.sdk.options.PipelineOptionsFactory; import org.junit.Test; import org.junit.runner.RunWith; @@ -75,4 +80,30 @@ public void testEntriesWithErrors() throws Exception { IllegalArgumentException.class, () -> PipelineOptionsFactory.fromArgs(TOO_MANY_ENTRIES_WITH_JOB).as(GcsOptions.class)); } + + @Test + public void testGoogleCloudStorageReadOptionsSerialization() throws Exception { + GcsOptions options = PipelineOptionsFactory.as(GcsOptions.class); + GoogleCloudStorageReadOptions readOptions = + GoogleCloudStorageReadOptions.builder() + .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) + .setFastFailOnNotFoundEnabled(false) + .setMinRangeRequestSize(12345L) + .build(); + options.setGoogleCloudStorageReadOptions(readOptions); + + ObjectMapper mapper = new ObjectMapper(); + String serialized = mapper.writeValueAsString(options); + GcsOptions deserialized = + mapper.readValue(serialized, PipelineOptions.class).as(GcsOptions.class); + + GoogleCloudStorageReadOptions deserializedReadOptions = + deserialized.getGoogleCloudStorageReadOptions(); + + assertNotNull(deserializedReadOptions); + assertEquals( + GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL, deserializedReadOptions.getFadvise()); + assertFalse(deserializedReadOptions.isFastFailOnNotFoundEnabled()); + assertEquals(12345L, deserializedReadOptions.getMinRangeRequestSize()); + } } From 8af7a982da85e0f63b6f4f30b128a277a93267d3 Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Wed, 22 Jul 2026 19:01:02 -0400 Subject: [PATCH 3/6] Override default fadvice to SEQUENTIAL This fixes the regression introduced by gcs-connector v3. --- .../beam/sdk/extensions/gcp/options/GcsOptions.java | 8 +++++++- .../beam/sdk/extensions/gcp/options/GcsOptionsTest.java | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java index 35cba02f7c1c..eb070b5b0c56 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java @@ -60,7 +60,13 @@ public interface GcsOptions extends ApplicationNameOptions, GcpOptions, Pipeline class GcsReadOptionsFactory implements DefaultValueFactory { @Override public GoogleCloudStorageReadOptions create(PipelineOptions options) { - return GoogleCloudStorageReadOptions.DEFAULT; + // In gcs-connector v3, GoogleCloudStorageReadOptions.DEFAULT changed fadvise from SEQUENTIAL + // to AUTO. Beam workloads default to SEQUENTIAL to preserve expected sequential read + // throughput and caching behavior. + return GoogleCloudStorageReadOptions.DEFAULT + .toBuilder() + .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) + .build(); } } diff --git a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java index de460ca0986b..11e85d796be8 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java @@ -86,7 +86,7 @@ public void testGoogleCloudStorageReadOptionsSerialization() throws Exception { GcsOptions options = PipelineOptionsFactory.as(GcsOptions.class); GoogleCloudStorageReadOptions readOptions = GoogleCloudStorageReadOptions.builder() - .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) + .setFadvise(GoogleCloudStorageReadOptions.Fadvise.RANDOM) .setFastFailOnNotFoundEnabled(false) .setMinRangeRequestSize(12345L) .build(); @@ -102,7 +102,7 @@ public void testGoogleCloudStorageReadOptionsSerialization() throws Exception { assertNotNull(deserializedReadOptions); assertEquals( - GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL, deserializedReadOptions.getFadvise()); + GoogleCloudStorageReadOptions.Fadvise.RANDOM, deserializedReadOptions.getFadvise()); assertFalse(deserializedReadOptions.isFastFailOnNotFoundEnabled()); assertEquals(12345L, deserializedReadOptions.getMinRangeRequestSize()); } From 74d235879fb3bf39a2035b363553a5efe3d45aad Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Wed, 22 Jul 2026 19:59:06 -0400 Subject: [PATCH 4/6] Spotless --- sdks/java/extensions/google-cloud-platform-core/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/sdks/java/extensions/google-cloud-platform-core/build.gradle b/sdks/java/extensions/google-cloud-platform-core/build.gradle index f1bfb63c7a3a..78cfe4739ec5 100644 --- a/sdks/java/extensions/google-cloud-platform-core/build.gradle +++ b/sdks/java/extensions/google-cloud-platform-core/build.gradle @@ -56,6 +56,7 @@ dependencies { implementation library.java.http_core implementation library.java.http_client implementation library.java.jackson_annotations + implementation library.java.jackson_core implementation library.java.jackson_databind permitUnusedDeclared library.java.jackson_databind // BEAM-11761 testImplementation project(path: ":sdks:java:core", configuration: "shadowTest") From 4a50372619783886d2b7b3c9db350a42a111b0a2 Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Wed, 22 Jul 2026 23:08:38 -0400 Subject: [PATCH 5/6] Only support a subset of fields in GoogleCloudStorageReadOptions. --- .../extensions/gcp/options/GcsOptions.java | 111 +++++++++++------- .../gcp/options/GcsOptionsTest.java | 16 +++ 2 files changed, 86 insertions(+), 41 deletions(-) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java index eb070b5b0c56..acfa0f3e24ba 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java @@ -24,13 +24,11 @@ import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.cloud.hadoop.gcsio.GoogleCloudStorageReadOptions; import com.google.cloud.hadoop.util.AsyncWriteChannelOptions; -import java.lang.reflect.Method; import java.util.HashMap; import java.util.concurrent.ExecutorService; import org.apache.beam.sdk.extensions.gcp.storage.GcsPathValidator; @@ -70,45 +68,6 @@ public GoogleCloudStorageReadOptions create(PipelineOptions options) { } } - class GcsReadOptionsSerializer extends JsonSerializer { - @Override - public void serialize( - GoogleCloudStorageReadOptions value, JsonGenerator gen, SerializerProvider serializers) - throws java.io.IOException { - serializers.defaultSerializeValue(value, gen); - } - } - - class GcsReadOptionsDeserializer extends JsonDeserializer { - @Override - public GoogleCloudStorageReadOptions deserialize(JsonParser p, DeserializationContext ctxt) - throws java.io.IOException { - ObjectMapper mapper = (ObjectMapper) p.getCodec(); - JsonNode root = mapper.readTree(p); - GoogleCloudStorageReadOptions.Builder builder = GoogleCloudStorageReadOptions.builder(); - - for (Method method : GoogleCloudStorageReadOptions.Builder.class.getMethods()) { - if (method.getName().startsWith("set") && method.getParameterCount() == 1) { - String propName = - Character.toLowerCase(method.getName().charAt(3)) + method.getName().substring(4); - JsonNode node = root.get(propName); - if (node != null && !node.isNull()) { - try { - Class paramType = method.getParameterTypes()[0]; - Object val = mapper.treeToValue(node, paramType); - if (val != null) { - method.invoke(builder, java.util.Objects.requireNonNull(val)); - } - } catch (Exception ignored) { - // Ignore incompatible or unmappable properties - } - } - } - } - return builder.build(); - } - } - /** @deprecated This option will be removed in a future release. */ @JsonSerialize(using = GcsReadOptionsSerializer.class) @JsonDeserialize(using = GcsReadOptionsDeserializer.class) @@ -343,3 +302,73 @@ boolean exceedsEntryLimit() { } } } + +class GcsReadOptionsSerializer extends JsonSerializer { + private static final GoogleCloudStorageReadOptions DEFAULT_OPTIONS = + GoogleCloudStorageReadOptions.DEFAULT + .toBuilder() + .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) + .build(); + + @Override + public void serialize( + GoogleCloudStorageReadOptions value, JsonGenerator gen, SerializerProvider serializers) + throws java.io.IOException { + // Note: We only support a partial set of options to propagate to remote + // workers. Setting the unsupported ones will not have any effect and will fall + // back to default in remote workers. Support for additional options can be + // added on a need basis. The full list of options can be seen in + // com.google.cloud.hadoop.gcsio.GoogleCloudStorageReadOptions. + gen.writeStartObject(); + if (value.getFadvise() != null && value.getFadvise() != DEFAULT_OPTIONS.getFadvise()) { + gen.writeStringField("fadvise", value.getFadvise().name()); + } + if (value.isFastFailOnNotFoundEnabled() != DEFAULT_OPTIONS.isFastFailOnNotFoundEnabled()) { + gen.writeBooleanField("fastFailOnNotFoundEnabled", value.isFastFailOnNotFoundEnabled()); + } + if (value.getMinRangeRequestSize() != DEFAULT_OPTIONS.getMinRangeRequestSize()) { + gen.writeNumberField("minRangeRequestSize", value.getMinRangeRequestSize()); + } + if (value.getInplaceSeekLimit() != DEFAULT_OPTIONS.getInplaceSeekLimit()) { + gen.writeNumberField("inplaceSeekLimit", value.getInplaceSeekLimit()); + } + if (value.isGrpcReadZeroCopyEnabled() != DEFAULT_OPTIONS.isGrpcReadZeroCopyEnabled()) { + gen.writeBooleanField("grpcReadZeroCopyEnabled", value.isGrpcReadZeroCopyEnabled()); + } + gen.writeEndObject(); + } +} + +class GcsReadOptionsDeserializer extends JsonDeserializer { + @Override + public GoogleCloudStorageReadOptions deserialize(JsonParser p, DeserializationContext ctxt) + throws java.io.IOException { + JsonNode root = p.readValueAsTree(); + GoogleCloudStorageReadOptions.Builder builder = + GoogleCloudStorageReadOptions.DEFAULT + .toBuilder() + .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL); + + if (root != null && root.isObject()) { + if (root.hasNonNull("fadvise")) { + builder.setFadvise( + GoogleCloudStorageReadOptions.Fadvise.valueOf(root.get("fadvise").asText())); + } + if (root.hasNonNull("fastFailOnNotFoundEnabled")) { + builder.setFastFailOnNotFoundEnabled(root.get("fastFailOnNotFoundEnabled").asBoolean()); + } else if (root.hasNonNull("fastFailOnNotFound")) { + builder.setFastFailOnNotFoundEnabled(root.get("fastFailOnNotFound").asBoolean()); + } + if (root.hasNonNull("minRangeRequestSize")) { + builder.setMinRangeRequestSize(root.get("minRangeRequestSize").asLong()); + } + if (root.hasNonNull("inplaceSeekLimit")) { + builder.setInplaceSeekLimit(root.get("inplaceSeekLimit").asLong()); + } + if (root.hasNonNull("grpcReadZeroCopyEnabled")) { + builder.setGrpcReadZeroCopyEnabled(root.get("grpcReadZeroCopyEnabled").asBoolean()); + } + } + return builder.build(); + } +} diff --git a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java index 11e85d796be8..912f0110e9ce 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/test/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptionsTest.java @@ -106,4 +106,20 @@ public void testGoogleCloudStorageReadOptionsSerialization() throws Exception { assertFalse(deserializedReadOptions.isFastFailOnNotFoundEnabled()); assertEquals(12345L, deserializedReadOptions.getMinRangeRequestSize()); } + + @Test + public void testDefaultGoogleCloudStorageReadOptionsSerialization() throws Exception { + GcsOptions options = PipelineOptionsFactory.as(GcsOptions.class); + ObjectMapper mapper = new ObjectMapper(); + String serialized = mapper.writeValueAsString(options); + GcsOptions deserialized = + mapper.readValue(serialized, PipelineOptions.class).as(GcsOptions.class); + + GoogleCloudStorageReadOptions deserializedReadOptions = + deserialized.getGoogleCloudStorageReadOptions(); + + assertNotNull(deserializedReadOptions); + assertEquals( + GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL, deserializedReadOptions.getFadvise()); + } } From 6a0afb001f5f5076f9ffcf1a0c99575f7c6f9467 Mon Sep 17 00:00:00 2001 From: Shunping Huang Date: Thu, 23 Jul 2026 11:42:58 -0400 Subject: [PATCH 6/6] Refactor --- .../beam/sdk/extensions/gcp/options/GcsOptions.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java index acfa0f3e24ba..134c4cb3f281 100644 --- a/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java +++ b/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/options/GcsOptions.java @@ -61,10 +61,7 @@ public GoogleCloudStorageReadOptions create(PipelineOptions options) { // In gcs-connector v3, GoogleCloudStorageReadOptions.DEFAULT changed fadvise from SEQUENTIAL // to AUTO. Beam workloads default to SEQUENTIAL to preserve expected sequential read // throughput and caching behavior. - return GoogleCloudStorageReadOptions.DEFAULT - .toBuilder() - .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) - .build(); + return GcsReadOptionsSerializer.DEFAULT_OPTIONS; } } @@ -304,7 +301,7 @@ boolean exceedsEntryLimit() { } class GcsReadOptionsSerializer extends JsonSerializer { - private static final GoogleCloudStorageReadOptions DEFAULT_OPTIONS = + static final GoogleCloudStorageReadOptions DEFAULT_OPTIONS = GoogleCloudStorageReadOptions.DEFAULT .toBuilder() .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL) @@ -345,9 +342,7 @@ public GoogleCloudStorageReadOptions deserialize(JsonParser p, DeserializationCo throws java.io.IOException { JsonNode root = p.readValueAsTree(); GoogleCloudStorageReadOptions.Builder builder = - GoogleCloudStorageReadOptions.DEFAULT - .toBuilder() - .setFadvise(GoogleCloudStorageReadOptions.Fadvise.SEQUENTIAL); + GcsReadOptionsSerializer.DEFAULT_OPTIONS.toBuilder(); if (root != null && root.isObject()) { if (root.hasNonNull("fadvise")) {